Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: source map generation depends on the devtool option #743

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -363,11 +363,11 @@ module.exports = {
### `sourceMap`

Type: `Boolean`
Default: `false`
Default: depends on the `compiler.devtool` value

Enables/Disables generation of source maps.

They are not enabled by default because they expose a runtime overhead and increase in bundle size (JS source maps do not).
By default generation of source maps depends on the [`devtool`](https://webpack.js.org/configuration/devtool/) option, all values enable source map generation except `eval` and `false` value.

**webpack.config.js**

Expand Down
7 changes: 6 additions & 1 deletion src/getSassOptions.js
Expand Up @@ -41,10 +41,15 @@ function getSassOptions(loaderContext, loaderOptions, content) {
options.outputStyle = 'compressed';
}

const useSourceMap =
typeof loaderOptions.sourceMap === 'boolean'
? loaderOptions.sourceMap
: loaderContext.sourceMap;

// opt.sourceMap
// Not using the `this.sourceMap` flag because css source maps are different
// @see https://github.com/webpack/css-loader/pull/40
if (loaderOptions.sourceMap) {
if (useSourceMap) {
// Deliberately overriding the sourceMap option here.
// node-sass won't produce source maps if the data option is used and options.sourceMap is not a string.
// In case it is a string, options.sourceMap should be a path where the source map is written.
Expand Down
2 changes: 1 addition & 1 deletion src/index.js
Expand Up @@ -62,7 +62,7 @@ function loader(content) {
render(sassOptions, (error, result) => {
if (error) {
if (error.file) {
this.dependency(error.file);
addNormalizedDependency(error.file);
}

callback(new SassError(error, this.resourcePath));
Expand Down
96 changes: 72 additions & 24 deletions test/__snapshots__/sourceMap-options.test.js.snap
@@ -1,49 +1,97 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`sourceMap option false (dart-sass) (sass): errors 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value has "true" value and the "devtool" option has "false" value (dart-sass) (sass): errors 1`] = `Array []`;

exports[`sourceMap option false (dart-sass) (sass): warnings 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value has "true" value and the "devtool" option has "false" value (dart-sass) (sass): warnings 1`] = `Array []`;

exports[`sourceMap option false (dart-sass) (scss): errors 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value has "true" value and the "devtool" option has "false" value (dart-sass) (scss): errors 1`] = `Array []`;

exports[`sourceMap option false (dart-sass) (scss): warnings 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value has "true" value and the "devtool" option has "false" value (dart-sass) (scss): warnings 1`] = `Array []`;

exports[`sourceMap option false (node-sass) (sass): errors 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value has "true" value and the "devtool" option has "false" value (node-sass) (sass): errors 1`] = `Array []`;

exports[`sourceMap option false (node-sass) (sass): warnings 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value has "true" value and the "devtool" option has "false" value (node-sass) (sass): warnings 1`] = `Array []`;

exports[`sourceMap option false (node-sass) (scss): errors 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value has "true" value and the "devtool" option has "false" value (node-sass) (scss): errors 1`] = `Array []`;

exports[`sourceMap option false (node-sass) (scss): warnings 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value has "true" value and the "devtool" option has "false" value (node-sass) (scss): warnings 1`] = `Array []`;

exports[`sourceMap option not specify (dart-sass) (sass): errors 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value has "true" value and the "devtool" option has "source-map" value (dart-sass) (sass): errors 1`] = `Array []`;

exports[`sourceMap option not specify (dart-sass) (sass): warnings 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value has "true" value and the "devtool" option has "source-map" value (dart-sass) (sass): warnings 1`] = `Array []`;

exports[`sourceMap option not specify (dart-sass) (scss): errors 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value has "true" value and the "devtool" option has "source-map" value (dart-sass) (scss): errors 1`] = `Array []`;

exports[`sourceMap option not specify (dart-sass) (scss): warnings 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value has "true" value and the "devtool" option has "source-map" value (dart-sass) (scss): warnings 1`] = `Array []`;

exports[`sourceMap option not specify (node-sass) (sass): errors 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value has "true" value and the "devtool" option has "source-map" value (node-sass) (sass): errors 1`] = `Array []`;

exports[`sourceMap option not specify (node-sass) (sass): warnings 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value has "true" value and the "devtool" option has "source-map" value (node-sass) (sass): warnings 1`] = `Array []`;

exports[`sourceMap option not specify (node-sass) (scss): errors 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value has "true" value and the "devtool" option has "source-map" value (node-sass) (scss): errors 1`] = `Array []`;

exports[`sourceMap option not specify (node-sass) (scss): warnings 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value has "true" value and the "devtool" option has "source-map" value (node-sass) (scss): warnings 1`] = `Array []`;

exports[`sourceMap option true (dart-sass) (sass): errors 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value is not specify and the "devtool" option has "source-map" value (dart-sass) (sass): errors 1`] = `Array []`;

exports[`sourceMap option true (dart-sass) (sass): warnings 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value is not specify and the "devtool" option has "source-map" value (dart-sass) (sass): warnings 1`] = `Array []`;

exports[`sourceMap option true (dart-sass) (scss): errors 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value is not specify and the "devtool" option has "source-map" value (dart-sass) (scss): errors 1`] = `Array []`;

exports[`sourceMap option true (dart-sass) (scss): warnings 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value is not specify and the "devtool" option has "source-map" value (dart-sass) (scss): warnings 1`] = `Array []`;

exports[`sourceMap option true (node-sass) (sass): errors 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value is not specify and the "devtool" option has "source-map" value (node-sass) (sass): errors 1`] = `Array []`;

exports[`sourceMap option true (node-sass) (sass): warnings 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value is not specify and the "devtool" option has "source-map" value (node-sass) (sass): warnings 1`] = `Array []`;

exports[`sourceMap option true (node-sass) (scss): errors 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value is not specify and the "devtool" option has "source-map" value (node-sass) (scss): errors 1`] = `Array []`;

exports[`sourceMap option true (node-sass) (scss): warnings 1`] = `Array []`;
exports[`sourceMap option should generate source maps when value is not specify and the "devtool" option has "source-map" value (node-sass) (scss): warnings 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value has "false" and the "devtool" option has "false" value (dart-sass) (sass): errors 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value has "false" and the "devtool" option has "false" value (dart-sass) (sass): warnings 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value has "false" and the "devtool" option has "false" value (dart-sass) (scss): errors 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value has "false" and the "devtool" option has "false" value (dart-sass) (scss): warnings 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value has "false" and the "devtool" option has "false" value (node-sass) (sass): errors 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value has "false" and the "devtool" option has "false" value (node-sass) (sass): warnings 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value has "false" and the "devtool" option has "false" value (node-sass) (scss): errors 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value has "false" and the "devtool" option has "false" value (node-sass) (scss): warnings 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value has "false" and the "devtool" option has "source-map" value (dart-sass) (sass): errors 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value has "false" and the "devtool" option has "source-map" value (dart-sass) (sass): warnings 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value has "false" and the "devtool" option has "source-map" value (dart-sass) (scss): errors 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value has "false" and the "devtool" option has "source-map" value (dart-sass) (scss): warnings 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value has "false" and the "devtool" option has "source-map" value (node-sass) (sass): errors 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value has "false" and the "devtool" option has "source-map" value (node-sass) (sass): warnings 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value has "false" and the "devtool" option has "source-map" value (node-sass) (scss): errors 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value has "false" and the "devtool" option has "source-map" value (node-sass) (scss): warnings 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value is not specify and the "devtool" option has "false" value (dart-sass) (sass): errors 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value is not specify and the "devtool" option has "false" value (dart-sass) (sass): warnings 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value is not specify and the "devtool" option has "false" value (dart-sass) (scss): errors 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value is not specify and the "devtool" option has "false" value (dart-sass) (scss): warnings 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value is not specify and the "devtool" option has "false" value (node-sass) (sass): errors 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value is not specify and the "devtool" option has "false" value (node-sass) (sass): warnings 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value is not specify and the "devtool" option has "false" value (node-sass) (scss): errors 1`] = `Array []`;

exports[`sourceMap option should not generate source maps when value is not specify and the "devtool" option has "false" value (node-sass) (scss): warnings 1`] = `Array []`;
82 changes: 76 additions & 6 deletions test/sourceMap-options.test.js
Expand Up @@ -22,12 +22,28 @@ describe('sourceMap option', () => {
syntaxStyles.forEach((syntax) => {
const [implementationName] = implementation.info.split('\t');

it(`not specify (${implementationName}) (${syntax})`, async () => {
it(`should generate source maps when value is not specify and the "devtool" option has "source-map" value (${implementationName}) (${syntax})`, async () => {
const testId = getTestId('language', syntax);
const options = {
implementation: getImplementationByName(implementationName),
};
const stats = await compile(testId, {
devtool: 'source-map',
loader: { options },
});
const { css, sourceMap } = getCodeFromBundle(stats);

expect(css).toBeDefined();
expect(sourceMap).toBeDefined();

expect(stats.compilation.warnings).toMatchSnapshot('warnings');
expect(stats.compilation.errors).toMatchSnapshot('errors');
});

it(`should not generate source maps when value is not specify and the "devtool" option has "false" value (${implementationName}) (${syntax})`, async () => {
const testId = getTestId('language', syntax);
const options = {
implementation: getImplementationByName(implementationName),
// eslint-disable-next-line no-undefined
sourceMap: undefined,
};
const stats = await compile(testId, { loader: { options } });
const { css, sourceMap } = getCodeFromBundle(stats);
Expand All @@ -39,7 +55,26 @@ describe('sourceMap option', () => {
expect(stats.compilation.errors).toMatchSnapshot('errors');
});

it(`false (${implementationName}) (${syntax})`, async () => {
it(`should not generate source maps when value has "false" and the "devtool" option has "source-map" value (${implementationName}) (${syntax})`, async () => {
const testId = getTestId('language', syntax);
const options = {
implementation: getImplementationByName(implementationName),
sourceMap: false,
};
const stats = await compile(testId, {
devtool: 'source-map',
loader: { options },
});
const { css, sourceMap } = getCodeFromBundle(stats);

expect(css).toBeDefined();
expect(sourceMap).toBeUndefined();

expect(stats.compilation.warnings).toMatchSnapshot('warnings');
expect(stats.compilation.errors).toMatchSnapshot('errors');
});

it(`should not generate source maps when value has "false" and the "devtool" option has "false" value (${implementationName}) (${syntax})`, async () => {
const testId = getTestId('language', syntax);
const options = {
implementation: getImplementationByName(implementationName),
Expand All @@ -55,15 +90,50 @@ describe('sourceMap option', () => {
expect(stats.compilation.errors).toMatchSnapshot('errors');
});

it(`true (${implementationName}) (${syntax})`, async () => {
it(`should generate source maps when value has "true" value and the "devtool" option has "source-map" value (${implementationName}) (${syntax})`, async () => {
expect.assertions(9);

const testId = getTestId('language', syntax);
const options = {
implementation: getImplementationByName(implementationName),
sourceMap: true,
};
const stats = await compile(testId, { loader: { options } });
const stats = await compile(testId, {
devtool: 'source-map',
loader: { options },
});
const { css, sourceMap } = getCodeFromBundle(stats);

expect(css).toBeDefined();
expect(sourceMap).toBeDefined();

expect(sourceMap.file).toBeUndefined();
expect(sourceMap.sourceRoot).toBeDefined();

expect(sourceMap.sources).toHaveLength(2);

sourceMap.sources.forEach((sourcePath) => {
expect(
fs.existsSync(path.resolve(sourceMap.sourceRoot, sourcePath))
).toBe(true);
});

expect(stats.compilation.warnings).toMatchSnapshot('warnings');
expect(stats.compilation.errors).toMatchSnapshot('errors');
});

it(`should generate source maps when value has "true" value and the "devtool" option has "false" value (${implementationName}) (${syntax})`, async () => {
expect.assertions(9);

const testId = getTestId('language', syntax);
const options = {
implementation: getImplementationByName(implementationName),
sourceMap: true,
};
const stats = await compile(testId, {
devtool: false,
loader: { options },
});
const { css, sourceMap } = getCodeFromBundle(stats);

expect(css).toBeDefined();
Expand Down