diff --git a/site/content/docs/04-compile-time.md b/site/content/docs/04-compile-time.md
index ed6977f81fc8..8e709d7c37cc 100644
--- a/site/content/docs/04-compile-time.md
+++ b/site/content/docs/04-compile-time.md
@@ -82,6 +82,8 @@ The following options can be passed to the compiler. None are required:
| `loopGuardTimeout` | 0 | A `number` that tells Svelte to break the loop if it blocks the thread for more than `loopGuardTimeout` ms. This is useful to prevent infinite loops. **Only available when `dev: true`**
| `preserveComments` | `false` | If `true`, your HTML comments will be preserved during server-side rendering. By default, they are stripped out.
| `preserveWhitespace` | `false` | If `true`, whitespace inside and between elements is kept as you typed it, rather than removed or collapsed to a single space where possible.
+| `sourcemap` | `object | string` | An initial sourcemap that will be merged into the final output sourcemap. This is usually the preprocessor sourcemap.
+| `enableSourcemap` | `boolean | { js: boolean; css: boolean; }` | If `true`, Svelte generate sourcemaps for components. Use an object with `js` or `css` for more granular control of sourcemap generation. By default, this is `true`.
| `outputFilename` | `null` | A `string` used for your JavaScript sourcemap.
| `cssOutputFilename` | `null` | A `string` used for your CSS sourcemap.
| `sveltePath` | `"svelte"` | The location of the `svelte` package. Any imports from `svelte` or `svelte/[module]` will be modified accordingly.
diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts
index 202e14fd9813..4d4cf909fda6 100644
--- a/src/compiler/compile/Component.ts
+++ b/src/compiler/compile/Component.ts
@@ -36,6 +36,7 @@ import { clone } from '../utils/clone';
import compiler_warnings from './compiler_warnings';
import compiler_errors from './compiler_errors';
import { extract_ignores_above_position, extract_svelte_ignore_from_comments } from '../utils/extract_svelte_ignore';
+import check_enable_sourcemap from './utils/check_enable_sourcemap';
interface ComponentOptions {
namespace?: string;
@@ -343,21 +344,28 @@ export default class Component {
? { code: null, map: null }
: result.css;
- const sourcemap_source_filename = get_sourcemap_source_filename(compile_options);
+ const js_sourcemap_enabled = check_enable_sourcemap(compile_options.enableSourcemap, 'js');
- js = print(program, {
- sourceMapSource: sourcemap_source_filename
- });
+ if (!js_sourcemap_enabled) {
+ js = print(program);
+ js.map = null;
+ } else {
+ const sourcemap_source_filename = get_sourcemap_source_filename(compile_options);
- js.map.sources = [
- sourcemap_source_filename
- ];
+ js = print(program, {
+ sourceMapSource: sourcemap_source_filename
+ });
- js.map.sourcesContent = [
- this.source
- ];
+ js.map.sources = [
+ sourcemap_source_filename
+ ];
- js.map = apply_preprocessor_sourcemap(sourcemap_source_filename, js.map, compile_options.sourcemap as (string | RawSourceMap | DecodedSourceMap));
+ js.map.sourcesContent = [
+ this.source
+ ];
+
+ js.map = apply_preprocessor_sourcemap(sourcemap_source_filename, js.map, compile_options.sourcemap as (string | RawSourceMap | DecodedSourceMap));
+ }
}
return {
diff --git a/src/compiler/compile/index.ts b/src/compiler/compile/index.ts
index 96b24bceeed8..afe9c56cf4ca 100644
--- a/src/compiler/compile/index.ts
+++ b/src/compiler/compile/index.ts
@@ -13,6 +13,7 @@ const valid_options = [
'name',
'filename',
'sourcemap',
+ 'enableSourcemap',
'generate',
'errorMode',
'varsReport',
@@ -82,7 +83,7 @@ function validate_options(options: CompileOptions, warnings: Warning[]) {
}
export default function compile(source: string, options: CompileOptions = {}) {
- options = Object.assign({ generate: 'dom', dev: false }, options);
+ options = Object.assign({ generate: 'dom', dev: false, enableSourcemap: true }, options);
const stats = new Stats();
const warnings = [];
diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts
index f74f4cdf1ccb..89af0c297c51 100644
--- a/src/compiler/compile/render_dom/index.ts
+++ b/src/compiler/compile/render_dom/index.ts
@@ -10,6 +10,7 @@ import { ImportDeclaration, ClassDeclaration, FunctionExpression, Node, Statemen
import { apply_preprocessor_sourcemap } from '../../utils/mapped_code';
import { RawSourceMap, DecodedSourceMap } from '@ampproject/remapping/dist/types/types';
import { flatten } from '../../utils/flatten';
+import check_enable_sourcemap from '../utils/check_enable_sourcemap';
export default function dom(
component: Component,
@@ -34,9 +35,15 @@ export default function dom(
const css = component.stylesheet.render(options.filename, !options.customElement);
- css.map = apply_preprocessor_sourcemap(options.filename, css.map, options.sourcemap as string | RawSourceMap | DecodedSourceMap);
+ const css_sourcemap_enabled = check_enable_sourcemap(options.enableSourcemap, 'css');
- const styles = component.stylesheet.has_styles && options.dev
+ if (css_sourcemap_enabled) {
+ css.map = apply_preprocessor_sourcemap(options.filename, css.map, options.sourcemap as string | RawSourceMap | DecodedSourceMap);
+ } else {
+ css.map = null;
+ }
+
+ const styles = css_sourcemap_enabled && component.stylesheet.has_styles && options.dev
? `${css.code}\n/*# sourceMappingURL=${css.map.toUrl()} */`
: css.code;
@@ -521,7 +528,7 @@ export default function dom(
constructor(options) {
super();
- ${css.code && b`this.shadowRoot.innerHTML = \`\`;`}
+ ${css.code && b`this.shadowRoot.innerHTML = \`\`;`}
@init(this, { target: this.shadowRoot, props: ${init_props}, customElement: true }, ${definition}, ${has_create_fragment ? 'create_fragment' : 'null'}, ${not_equal}, ${prop_indexes}, null, ${dirty});
diff --git a/src/compiler/compile/render_ssr/index.ts b/src/compiler/compile/render_ssr/index.ts
index b35a6ce6ffee..9d2c1cc60b68 100644
--- a/src/compiler/compile/render_ssr/index.ts
+++ b/src/compiler/compile/render_ssr/index.ts
@@ -10,6 +10,7 @@ import { extract_names } from 'periscopic';
import { walk } from 'estree-walker';
import { invalidate } from '../render_dom/invalidate';
+import check_enable_sourcemap from '../utils/check_enable_sourcemap';
export default function ssr(
component: Component,
@@ -200,11 +201,13 @@ export default function ssr(
main
].filter(Boolean);
+ const css_sourcemap_enabled = check_enable_sourcemap(options.enableSourcemap, 'css');
+
const js = b`
${css.code ? b`
const #css = {
code: "${css.code}",
- map: ${css.map ? string_literal(css.map.toString()) : 'null'}
+ map: ${css_sourcemap_enabled && css.map ? string_literal(css.map.toString()) : 'null'}
};` : null}
${component.extract_javascript(component.ast.module)}
diff --git a/src/compiler/compile/utils/check_enable_sourcemap.ts b/src/compiler/compile/utils/check_enable_sourcemap.ts
new file mode 100644
index 000000000000..51f07c353ac1
--- /dev/null
+++ b/src/compiler/compile/utils/check_enable_sourcemap.ts
@@ -0,0 +1,10 @@
+import { EnableSourcemap } from '../../interfaces';
+
+export default function check_enable_sourcemap(
+ enable_sourcemap: EnableSourcemap,
+ namespace: keyof Extract
+) {
+ return typeof enable_sourcemap === 'boolean'
+ ? enable_sourcemap
+ : enable_sourcemap[namespace];
+}
diff --git a/src/compiler/interfaces.ts b/src/compiler/interfaces.ts
index 7446c4c14b57..b999fbd803dd 100644
--- a/src/compiler/interfaces.ts
+++ b/src/compiler/interfaces.ts
@@ -131,6 +131,8 @@ export interface Warning {
export type ModuleFormat = 'esm' | 'cjs';
+export type EnableSourcemap = boolean | { js: boolean; css: boolean };
+
export type CssHashGetter = (args: {
name: string;
filename: string | undefined;
@@ -147,6 +149,7 @@ export interface CompileOptions {
varsReport?: 'full' | 'strict' | false;
sourcemap?: object | string;
+ enableSourcemap?: EnableSourcemap;
outputFilename?: string;
cssOutputFilename?: string;
sveltePath?: string;
diff --git a/test/sourcemaps/index.ts b/test/sourcemaps/index.ts
index 903629c06b1b..fc021cd6a7ca 100644
--- a/test/sourcemaps/index.ts
+++ b/test/sourcemaps/index.ts
@@ -85,11 +85,13 @@ describe('sourcemaps', () => {
);
}
- assert.deepEqual(
- js.map.sources.slice().sort(),
- (config.js_map_sources || ['input.svelte']).sort(),
- 'js.map.sources is wrong'
- );
+ if (js.map) {
+ assert.deepEqual(
+ js.map.sources.slice().sort(),
+ (config.js_map_sources || ['input.svelte']).sort(),
+ 'js.map.sources is wrong'
+ );
+ }
if (css.map) {
assert.deepEqual(
css.map.sources.slice().sort(),
diff --git a/test/sourcemaps/samples/no-sourcemap/_config.js b/test/sourcemaps/samples/no-sourcemap/_config.js
new file mode 100644
index 000000000000..5b84d4055408
--- /dev/null
+++ b/test/sourcemaps/samples/no-sourcemap/_config.js
@@ -0,0 +1,5 @@
+export default {
+ compile_options: {
+ enableSourcemap: false
+ }
+};
diff --git a/test/sourcemaps/samples/no-sourcemap/input.svelte b/test/sourcemaps/samples/no-sourcemap/input.svelte
new file mode 100644
index 000000000000..6d39eaad0e79
--- /dev/null
+++ b/test/sourcemaps/samples/no-sourcemap/input.svelte
@@ -0,0 +1,11 @@
+
+
+{foo}
+
+
diff --git a/test/sourcemaps/samples/no-sourcemap/test.js b/test/sourcemaps/samples/no-sourcemap/test.js
new file mode 100644
index 000000000000..127459a54e6e
--- /dev/null
+++ b/test/sourcemaps/samples/no-sourcemap/test.js
@@ -0,0 +1,4 @@
+export function test({ assert, js, css }) {
+ assert.equal(js.map, null);
+ assert.equal(css.map, null);
+}
diff --git a/test/sourcemaps/samples/only-css-sourcemap/_config.js b/test/sourcemaps/samples/only-css-sourcemap/_config.js
new file mode 100644
index 000000000000..767e10a4b9af
--- /dev/null
+++ b/test/sourcemaps/samples/only-css-sourcemap/_config.js
@@ -0,0 +1,5 @@
+export default {
+ compile_options: {
+ enableSourcemap: { css: true }
+ }
+};
diff --git a/test/sourcemaps/samples/only-css-sourcemap/input.svelte b/test/sourcemaps/samples/only-css-sourcemap/input.svelte
new file mode 100644
index 000000000000..6d39eaad0e79
--- /dev/null
+++ b/test/sourcemaps/samples/only-css-sourcemap/input.svelte
@@ -0,0 +1,11 @@
+
+
+{foo}
+
+
diff --git a/test/sourcemaps/samples/only-css-sourcemap/test.js b/test/sourcemaps/samples/only-css-sourcemap/test.js
new file mode 100644
index 000000000000..a7ac6a9b0bdd
--- /dev/null
+++ b/test/sourcemaps/samples/only-css-sourcemap/test.js
@@ -0,0 +1,4 @@
+export function test({ assert, js, css }) {
+ assert.equal(js.map, null);
+ assert.notEqual(css.map, null);
+}
diff --git a/test/sourcemaps/samples/only-js-sourcemap/_config.js b/test/sourcemaps/samples/only-js-sourcemap/_config.js
new file mode 100644
index 000000000000..0b3b7987f174
--- /dev/null
+++ b/test/sourcemaps/samples/only-js-sourcemap/_config.js
@@ -0,0 +1,5 @@
+export default {
+ compile_options: {
+ enableSourcemap: { js: true }
+ }
+};
diff --git a/test/sourcemaps/samples/only-js-sourcemap/input.svelte b/test/sourcemaps/samples/only-js-sourcemap/input.svelte
new file mode 100644
index 000000000000..6d39eaad0e79
--- /dev/null
+++ b/test/sourcemaps/samples/only-js-sourcemap/input.svelte
@@ -0,0 +1,11 @@
+
+
+{foo}
+
+
diff --git a/test/sourcemaps/samples/only-js-sourcemap/test.js b/test/sourcemaps/samples/only-js-sourcemap/test.js
new file mode 100644
index 000000000000..b150653c3d72
--- /dev/null
+++ b/test/sourcemaps/samples/only-js-sourcemap/test.js
@@ -0,0 +1,4 @@
+export function test({ assert, js, css }) {
+ assert.notEqual(js.map, null);
+ assert.equal(css.map, null);
+}