From 6f4ea37eca98ed48305634416391f8a4c95a7e81 Mon Sep 17 00:00:00 2001 From: Evilebot Tnawi Date: Tue, 20 Aug 2019 16:35:39 +0300 Subject: [PATCH] feat: `webpackImporter` option (#732) --- README.md | 33 +++++++++ src/index.js | 13 +++- .../webpackImporter-options.test.js.snap | 49 +++++++++++++ test/webpackImporter-options.test.js | 71 +++++++++++++++++++ 4 files changed, 163 insertions(+), 3 deletions(-) create mode 100644 test/__snapshots__/webpackImporter-options.test.js.snap create mode 100644 test/webpackImporter-options.test.js diff --git a/README.md b/README.md index 968b5f94..aed1276c 100644 --- a/README.md +++ b/README.md @@ -346,6 +346,39 @@ module.exports = { > ℹ In some rare case `node-sass` can output invalid source maps (it is `node-sass` bug), to avoid try to update node-sass to latest version or you can try to set the `outputStyle` option to `compressed` value. +### `webpackImporter` + +Type: `Boolean` +Default: `true` + +Allows to disable default `webpack` importer. + +This can improve performance in some cases. Use it with caution because aliases and `@import` at-rules starts with `~` will not work, but you can pass own `importer` to solve this (see [`importer docs`](https://github.com/sass/node-sass#importer--v200---experimental)). + +**webpack.config.js** + +```js +module.exports = { + module: { + rules: [ + { + test: /\.s[ac]ss$/i, + use: [ + 'style-loader', + 'css-loader', + { + loader: 'sass-loader', + options: { + webpackImporter: false, + }, + }, + ], + }, + ], + }, +}; +``` + ## Examples ### Extracts CSS into separate files diff --git a/src/index.js b/src/index.js index b57e1dd3..b9fd17f4 100644 --- a/src/index.js +++ b/src/index.js @@ -62,9 +62,16 @@ function loader(content) { const sassOptions = getSassOptions(this, options, content); - sassOptions.importer.push( - webpackImporter(this.resourcePath, resolve, addNormalizedDependency) - ); + const shouldUseWebpackImporter = + typeof options.webpackImporter === 'boolean' + ? options.webpackImporter + : true; + + if (shouldUseWebpackImporter) { + sassOptions.importer.push( + webpackImporter(this.resourcePath, resolve, addNormalizedDependency) + ); + } // Skip empty files, otherwise it will stop webpack, see issue #21 if (sassOptions.data.trim() === '') { diff --git a/test/__snapshots__/webpackImporter-options.test.js.snap b/test/__snapshots__/webpackImporter-options.test.js.snap new file mode 100644 index 00000000..4e752081 --- /dev/null +++ b/test/__snapshots__/webpackImporter-options.test.js.snap @@ -0,0 +1,49 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`webpackImporter option false (dart-sass) (sass): errors 1`] = `Array []`; + +exports[`webpackImporter option false (dart-sass) (sass): warnings 1`] = `Array []`; + +exports[`webpackImporter option false (dart-sass) (scss): errors 1`] = `Array []`; + +exports[`webpackImporter option false (dart-sass) (scss): warnings 1`] = `Array []`; + +exports[`webpackImporter option false (node-sass) (sass): errors 1`] = `Array []`; + +exports[`webpackImporter option false (node-sass) (sass): warnings 1`] = `Array []`; + +exports[`webpackImporter option false (node-sass) (scss): errors 1`] = `Array []`; + +exports[`webpackImporter option false (node-sass) (scss): warnings 1`] = `Array []`; + +exports[`webpackImporter option not specify (dart-sass) (sass): errors 1`] = `Array []`; + +exports[`webpackImporter option not specify (dart-sass) (sass): warnings 1`] = `Array []`; + +exports[`webpackImporter option not specify (dart-sass) (scss): errors 1`] = `Array []`; + +exports[`webpackImporter option not specify (dart-sass) (scss): warnings 1`] = `Array []`; + +exports[`webpackImporter option not specify (node-sass) (sass): errors 1`] = `Array []`; + +exports[`webpackImporter option not specify (node-sass) (sass): warnings 1`] = `Array []`; + +exports[`webpackImporter option not specify (node-sass) (scss): errors 1`] = `Array []`; + +exports[`webpackImporter option not specify (node-sass) (scss): warnings 1`] = `Array []`; + +exports[`webpackImporter option true (dart-sass) (sass): errors 1`] = `Array []`; + +exports[`webpackImporter option true (dart-sass) (sass): warnings 1`] = `Array []`; + +exports[`webpackImporter option true (dart-sass) (scss): errors 1`] = `Array []`; + +exports[`webpackImporter option true (dart-sass) (scss): warnings 1`] = `Array []`; + +exports[`webpackImporter option true (node-sass) (sass): errors 1`] = `Array []`; + +exports[`webpackImporter option true (node-sass) (sass): warnings 1`] = `Array []`; + +exports[`webpackImporter option true (node-sass) (scss): errors 1`] = `Array []`; + +exports[`webpackImporter option true (node-sass) (scss): warnings 1`] = `Array []`; diff --git a/test/webpackImporter-options.test.js b/test/webpackImporter-options.test.js new file mode 100644 index 00000000..c8e6aa79 --- /dev/null +++ b/test/webpackImporter-options.test.js @@ -0,0 +1,71 @@ +/** + * @jest-environment node + */ +import nodeSass from 'node-sass'; +import dartSass from 'sass'; + +import { + compile, + getTestId, + getCodeFromBundle, + getCodeFromSass, + getImplementationByName, +} from './helpers'; + +const implementations = [nodeSass, dartSass]; +const syntaxStyles = ['scss', 'sass']; + +describe('webpackImporter option', () => { + implementations.forEach((implementation) => { + syntaxStyles.forEach((syntax) => { + const [implementationName] = implementation.info.split('\t'); + + it(`not specify (${implementationName}) (${syntax})`, async () => { + const testId = getTestId('language', syntax); + const options = { + implementation: getImplementationByName(implementationName), + }; + const stats = await compile(testId, { loader: { options } }); + + expect(getCodeFromBundle(stats).css).toBe( + getCodeFromSass(testId, options).css + ); + + expect(stats.compilation.warnings).toMatchSnapshot('warnings'); + expect(stats.compilation.errors).toMatchSnapshot('errors'); + }); + + it(`false (${implementationName}) (${syntax})`, async () => { + const testId = getTestId('language', syntax); + const options = { + webpackImporter: false, + implementation: getImplementationByName(implementationName), + }; + const stats = await compile(testId, { loader: { options } }); + + expect(getCodeFromBundle(stats).css).toBe( + getCodeFromSass(testId, options).css + ); + + expect(stats.compilation.warnings).toMatchSnapshot('warnings'); + expect(stats.compilation.errors).toMatchSnapshot('errors'); + }); + + it(`true (${implementationName}) (${syntax})`, async () => { + const testId = getTestId('language', syntax); + const options = { + webpackImporter: true, + implementation: getImplementationByName(implementationName), + }; + const stats = await compile(testId, { loader: { options } }); + + expect(getCodeFromBundle(stats).css).toBe( + getCodeFromSass(testId, options).css + ); + + expect(stats.compilation.warnings).toMatchSnapshot('warnings'); + expect(stats.compilation.errors).toMatchSnapshot('errors'); + }); + }); + }); +});