From a55bc136384154a53e3acb9b2e7f1cea0fa86ad9 Mon Sep 17 00:00:00 2001 From: dustin horton Date: Wed, 31 Oct 2018 17:20:26 -0700 Subject: [PATCH] feat(gatsby-plugin-sass): Accept css-loader options (#9462) v2 changed how dashes/hyphens in class names handled by css modules were treated: https://github.com/gatsbyjs/gatsby/issues/5458. This was burdensome as it required changing all `className`s that utilized dashes. This allows overriding that change, almost entirely by copying prior art from @yeskunall & @pieh (https://github.com/gatsbyjs/gatsby/pull/9237). --- docs/docs/migrating-from-v1-to-v2.md | 73 ++++++ packages/gatsby-plugin-sass/README.md | 16 ++ .../__snapshots__/gatsby-node.js.snap | 244 ++++++++++++++---- .../src/__tests__/gatsby-node.js | 8 +- .../gatsby-plugin-sass/src/gatsby-node.js | 6 +- 5 files changed, 287 insertions(+), 60 deletions(-) diff --git a/docs/docs/migrating-from-v1-to-v2.md b/docs/docs/migrating-from-v1-to-v2.md index a100d84a8b544..c95e6222f6f6d 100644 --- a/docs/docs/migrating-from-v1-to-v2.md +++ b/docs/docs/migrating-from-v1-to-v2.md @@ -674,6 +674,79 @@ export default ({ children }) => ( ) ``` +The Gatsby v1 behavior can be restored by adjusting [CSS Loader options](https://github.com/webpack-contrib/css-loader#options). + +For vanilla CSS without a preprocessor: + +```javascript:title=gatsby-node.js +const cssLoaderRe = /\/css-loader\// +const targetFile = `.module.css` + +const processRule = rule => { + if (rule.oneOf) { + return { + ...rule, + oneOf: rule.oneOf.map(processRule), + } + } + + if (!rule.test.test(targetFile)) { + return rule + } + + if (Array.isArray(rule.use)) { + return { + ...rule, + use: rule.use.map(use => { + if (!cssLoaderRe.test(use.loader)) { + return use + } + + // adjust css-loader options + return { + ...use, + options: { + ...use.options, + camelCase: false, + }, + } + }), + } + } + + return rule +} + +exports.onCreateWebpackConfig = ({ getConfig, actions }) => { + const config = getConfig() + + const newConfig = { + ...config, + module: { + ...config.module, + rules: config.module.rules.map(processRule), + }, + } + actions.replaceWebpackConfig(newConfig) +} +``` + +If you're using a preprocessor, you can pass in CSS Loader options when configuring [`gatsby-plugin-sass`](/packages/gatsby-plugin-sass/README.md#how-to-use) or [`gatsby-plugin-less`](/packages/gatsby-plugin-less/README.md#how-to-use): + +```javascript +// in gatsby-config.js +plugins: [ + { + resolve: `gatsby-plugin-sass`, + options: { + cssLoaderOptions: { + camelCase: false, + }, + }, + }, +] +``` + ### Update Jest configuration If you were using Jest with Gatsby V1, you will need to make some updates to your configuration when upgrading to Gatsby V2. You can view the complete details of setting up your test environment on the [Unit Testing](/docs/unit-testing/) page of the docs. diff --git a/packages/gatsby-plugin-sass/README.md b/packages/gatsby-plugin-sass/README.md index 86c0576b1ab7f..21c107b49a674 100644 --- a/packages/gatsby-plugin-sass/README.md +++ b/packages/gatsby-plugin-sass/README.md @@ -31,6 +31,22 @@ plugins: [ ] ``` +If you need to override the default options passed into [`css-loader`](https://github.com/webpack-contrib/css-loader): + + ```javascript +// in gatsby-config.js +plugins: [ + { + resolve: `gatsby-plugin-sass`, + options: { + cssLoaderOptions: { + camelCase: false, + }, + }, + }, +] +``` + ### With CSS Modules Using CSS Modules requires no additional configuration. Simply prepend `.module` to the extension. For example: `App.scss` -> `App.module.scss`. diff --git a/packages/gatsby-plugin-sass/src/__tests__/__snapshots__/gatsby-node.js.snap b/packages/gatsby-plugin-sass/src/__tests__/__snapshots__/gatsby-node.js.snap index 9c0b588f4151d..596fb253670d8 100644 --- a/packages/gatsby-plugin-sass/src/__tests__/__snapshots__/gatsby-node.js.snap +++ b/packages/gatsby-plugin-sass/src/__tests__/__snapshots__/gatsby-node.js.snap @@ -12,13 +12,12 @@ exports[`gatsby-plugin-sass Stage: build-html / No options 1`] = ` Object { "test": /\\\\\\.module\\\\\\.s\\(a\\|c\\)ss\\$/, "use": Array [ - "miniCssExtract", "css({\\"modules\\":true,\\"importLoaders\\":2})", "postcss({})", Object { "loader": "/resolved/path/sass-loader", "options": Object { - "sourceMap": true, + "sourceMap": false, }, }, ], @@ -26,15 +25,7 @@ exports[`gatsby-plugin-sass Stage: build-html / No options 1`] = ` Object { "test": /\\\\\\.s\\(a\\|c\\)ss\\$/, "use": Array [ - "miniCssExtract", - "css({\\"importLoaders\\":2})", - "postcss({})", - Object { - "loader": "/resolved/path/sass-loader", - "options": Object { - "sourceMap": true, - }, - }, + "null", ], }, ], @@ -65,13 +56,12 @@ exports[`gatsby-plugin-sass Stage: build-html / PostCss plugins 1`] = ` Object { "test": /\\\\\\.module\\\\\\.s\\(a\\|c\\)ss\\$/, "use": Array [ - "miniCssExtract", "css({\\"modules\\":true,\\"importLoaders\\":2})", "postcss({\\"plugins\\":[\\"test1\\"]})", Object { "loader": "/resolved/path/sass-loader", "options": Object { - "sourceMap": true, + "sourceMap": false, }, }, ], @@ -79,15 +69,7 @@ exports[`gatsby-plugin-sass Stage: build-html / PostCss plugins 1`] = ` Object { "test": /\\\\\\.s\\(a\\|c\\)ss\\$/, "use": Array [ - "miniCssExtract", - "css({\\"importLoaders\\":2})", - "postcss({\\"plugins\\":[\\"test1\\"]})", - Object { - "loader": "/resolved/path/sass-loader", - "options": Object { - "sourceMap": true, - }, - }, + "null", ], }, ], @@ -118,7 +100,6 @@ exports[`gatsby-plugin-sass Stage: build-html / Sass options 1`] = ` Object { "test": /\\\\\\.module\\\\\\.s\\(a\\|c\\)ss\\$/, "use": Array [ - "miniCssExtract", "css({\\"modules\\":true,\\"importLoaders\\":2})", "postcss({})", Object { @@ -128,7 +109,7 @@ exports[`gatsby-plugin-sass Stage: build-html / Sass options 1`] = ` "absolute/path/a", "absolute/path/b", ], - "sourceMap": true, + "sourceMap": false, }, }, ], @@ -136,21 +117,53 @@ exports[`gatsby-plugin-sass Stage: build-html / Sass options 1`] = ` Object { "test": /\\\\\\.s\\(a\\|c\\)ss\\$/, "use": Array [ - "miniCssExtract", - "css({\\"importLoaders\\":2})", + "null", + ], + }, + ], + }, + ], + }, + }, + ], + ], + "results": Array [ + Object { + "isThrow": false, + "value": undefined, + }, + ], +} +`; + +exports[`gatsby-plugin-sass Stage: build-html / css-loader options 1`] = ` +[MockFunction] { + "calls": Array [ + Array [ + Object { + "module": Object { + "rules": Array [ + Object { + "oneOf": Array [ + Object { + "test": /\\\\\\.module\\\\\\.s\\(a\\|c\\)ss\\$/, + "use": Array [ + "css({\\"camelCase\\":false,\\"modules\\":true,\\"importLoaders\\":2})", "postcss({})", Object { "loader": "/resolved/path/sass-loader", "options": Object { - "includePaths": Array [ - "absolute/path/a", - "absolute/path/b", - ], - "sourceMap": true, + "sourceMap": false, }, }, ], }, + Object { + "test": /\\\\\\.s\\(a\\|c\\)ss\\$/, + "use": Array [ + "null", + ], + }, ], }, ], @@ -185,7 +198,7 @@ exports[`gatsby-plugin-sass Stage: build-javascript / No options 1`] = ` Object { "loader": "/resolved/path/sass-loader", "options": Object { - "sourceMap": true, + "sourceMap": false, }, }, ], @@ -199,7 +212,7 @@ exports[`gatsby-plugin-sass Stage: build-javascript / No options 1`] = ` Object { "loader": "/resolved/path/sass-loader", "options": Object { - "sourceMap": true, + "sourceMap": false, }, }, ], @@ -238,7 +251,7 @@ exports[`gatsby-plugin-sass Stage: build-javascript / PostCss plugins 1`] = ` Object { "loader": "/resolved/path/sass-loader", "options": Object { - "sourceMap": true, + "sourceMap": false, }, }, ], @@ -252,7 +265,7 @@ exports[`gatsby-plugin-sass Stage: build-javascript / PostCss plugins 1`] = ` Object { "loader": "/resolved/path/sass-loader", "options": Object { - "sourceMap": true, + "sourceMap": false, }, }, ], @@ -295,7 +308,7 @@ exports[`gatsby-plugin-sass Stage: build-javascript / Sass options 1`] = ` "absolute/path/a", "absolute/path/b", ], - "sourceMap": true, + "sourceMap": false, }, }, ], @@ -313,7 +326,60 @@ exports[`gatsby-plugin-sass Stage: build-javascript / Sass options 1`] = ` "absolute/path/a", "absolute/path/b", ], - "sourceMap": true, + "sourceMap": false, + }, + }, + ], + }, + ], + }, + ], + }, + }, + ], + ], + "results": Array [ + Object { + "isThrow": false, + "value": undefined, + }, + ], +} +`; + +exports[`gatsby-plugin-sass Stage: build-javascript / css-loader options 1`] = ` +[MockFunction] { + "calls": Array [ + Array [ + Object { + "module": Object { + "rules": Array [ + Object { + "oneOf": Array [ + Object { + "test": /\\\\\\.module\\\\\\.s\\(a\\|c\\)ss\\$/, + "use": Array [ + "miniCssExtract", + "css({\\"camelCase\\":false,\\"modules\\":true,\\"importLoaders\\":2})", + "postcss({})", + Object { + "loader": "/resolved/path/sass-loader", + "options": Object { + "sourceMap": false, + }, + }, + ], + }, + Object { + "test": /\\\\\\.s\\(a\\|c\\)ss\\$/, + "use": Array [ + "miniCssExtract", + "css({\\"camelCase\\":false,\\"importLoaders\\":2})", + "postcss({})", + Object { + "loader": "/resolved/path/sass-loader", + "options": Object { + "sourceMap": false, }, }, ], @@ -501,7 +567,7 @@ exports[`gatsby-plugin-sass Stage: develop / Sass options 1`] = ` } `; -exports[`gatsby-plugin-sass Stage: develop-html / No options 1`] = ` +exports[`gatsby-plugin-sass Stage: develop / css-loader options 1`] = ` [MockFunction] { "calls": Array [ Array [ @@ -514,7 +580,7 @@ exports[`gatsby-plugin-sass Stage: develop-html / No options 1`] = ` "test": /\\\\\\.module\\\\\\.s\\(a\\|c\\)ss\\$/, "use": Array [ "miniCssExtract", - "css({\\"modules\\":true,\\"importLoaders\\":2})", + "css({\\"camelCase\\":false,\\"modules\\":true,\\"importLoaders\\":2})", "postcss({})", Object { "loader": "/resolved/path/sass-loader", @@ -528,7 +594,7 @@ exports[`gatsby-plugin-sass Stage: develop-html / No options 1`] = ` "test": /\\\\\\.s\\(a\\|c\\)ss\\$/, "use": Array [ "miniCssExtract", - "css({\\"importLoaders\\":2})", + "css({\\"camelCase\\":false,\\"importLoaders\\":2})", "postcss({})", Object { "loader": "/resolved/path/sass-loader", @@ -554,7 +620,7 @@ exports[`gatsby-plugin-sass Stage: develop-html / No options 1`] = ` } `; -exports[`gatsby-plugin-sass Stage: develop-html / PostCss plugins 1`] = ` +exports[`gatsby-plugin-sass Stage: develop-html / No options 1`] = ` [MockFunction] { "calls": Array [ Array [ @@ -566,13 +632,12 @@ exports[`gatsby-plugin-sass Stage: develop-html / PostCss plugins 1`] = ` Object { "test": /\\\\\\.module\\\\\\.s\\(a\\|c\\)ss\\$/, "use": Array [ - "miniCssExtract", "css({\\"modules\\":true,\\"importLoaders\\":2})", - "postcss({\\"plugins\\":[\\"test1\\"]})", + "postcss({})", Object { "loader": "/resolved/path/sass-loader", "options": Object { - "sourceMap": true, + "sourceMap": false, }, }, ], @@ -580,17 +645,53 @@ exports[`gatsby-plugin-sass Stage: develop-html / PostCss plugins 1`] = ` Object { "test": /\\\\\\.s\\(a\\|c\\)ss\\$/, "use": Array [ - "miniCssExtract", - "css({\\"importLoaders\\":2})", + "null", + ], + }, + ], + }, + ], + }, + }, + ], + ], + "results": Array [ + Object { + "isThrow": false, + "value": undefined, + }, + ], +} +`; + +exports[`gatsby-plugin-sass Stage: develop-html / PostCss plugins 1`] = ` +[MockFunction] { + "calls": Array [ + Array [ + Object { + "module": Object { + "rules": Array [ + Object { + "oneOf": Array [ + Object { + "test": /\\\\\\.module\\\\\\.s\\(a\\|c\\)ss\\$/, + "use": Array [ + "css({\\"modules\\":true,\\"importLoaders\\":2})", "postcss({\\"plugins\\":[\\"test1\\"]})", Object { "loader": "/resolved/path/sass-loader", "options": Object { - "sourceMap": true, + "sourceMap": false, }, }, ], }, + Object { + "test": /\\\\\\.s\\(a\\|c\\)ss\\$/, + "use": Array [ + "null", + ], + }, ], }, ], @@ -619,7 +720,6 @@ exports[`gatsby-plugin-sass Stage: develop-html / Sass options 1`] = ` Object { "test": /\\\\\\.module\\\\\\.s\\(a\\|c\\)ss\\$/, "use": Array [ - "miniCssExtract", "css({\\"modules\\":true,\\"importLoaders\\":2})", "postcss({})", Object { @@ -629,7 +729,7 @@ exports[`gatsby-plugin-sass Stage: develop-html / Sass options 1`] = ` "absolute/path/a", "absolute/path/b", ], - "sourceMap": true, + "sourceMap": false, }, }, ], @@ -637,21 +737,53 @@ exports[`gatsby-plugin-sass Stage: develop-html / Sass options 1`] = ` Object { "test": /\\\\\\.s\\(a\\|c\\)ss\\$/, "use": Array [ - "miniCssExtract", - "css({\\"importLoaders\\":2})", + "null", + ], + }, + ], + }, + ], + }, + }, + ], + ], + "results": Array [ + Object { + "isThrow": false, + "value": undefined, + }, + ], +} +`; + +exports[`gatsby-plugin-sass Stage: develop-html / css-loader options 1`] = ` +[MockFunction] { + "calls": Array [ + Array [ + Object { + "module": Object { + "rules": Array [ + Object { + "oneOf": Array [ + Object { + "test": /\\\\\\.module\\\\\\.s\\(a\\|c\\)ss\\$/, + "use": Array [ + "css({\\"camelCase\\":false,\\"modules\\":true,\\"importLoaders\\":2})", "postcss({})", Object { "loader": "/resolved/path/sass-loader", "options": Object { - "includePaths": Array [ - "absolute/path/a", - "absolute/path/b", - ], - "sourceMap": true, + "sourceMap": false, }, }, ], }, + Object { + "test": /\\\\\\.s\\(a\\|c\\)ss\\$/, + "use": Array [ + "null", + ], + }, ], }, ], diff --git a/packages/gatsby-plugin-sass/src/__tests__/gatsby-node.js b/packages/gatsby-plugin-sass/src/__tests__/gatsby-node.js index eb1d0d9223617..8c78b608b54d8 100644 --- a/packages/gatsby-plugin-sass/src/__tests__/gatsby-node.js +++ b/packages/gatsby-plugin-sass/src/__tests__/gatsby-node.js @@ -10,6 +10,7 @@ describe(`gatsby-plugin-sass`, () => { miniCssExtract: () => `miniCssExtract`, css: args => `css(${JSON.stringify(args)})`, postcss: args => `postcss(${JSON.stringify(args)})`, + null: () => `null`, } const { onCreateWebpackConfig } = require(`../gatsby-node`) @@ -28,6 +29,11 @@ describe(`gatsby-plugin-sass`, () => { "PostCss plugins": { postCssPlugins: [`test1`], }, + "css-loader options": { + cssLoaderOptions: { + camelCase: false, + }, + }, }, } @@ -35,7 +41,7 @@ describe(`gatsby-plugin-sass`, () => { for (let label in tests.options) { const options = tests.options[label] it(`Stage: ${stage} / ${label}`, () => { - onCreateWebpackConfig({ actions, loaders, stage: `develop` }, options) + onCreateWebpackConfig({ actions, loaders, stage }, options) expect(actions.setWebpackConfig).toMatchSnapshot() }) } diff --git a/packages/gatsby-plugin-sass/src/gatsby-node.js b/packages/gatsby-plugin-sass/src/gatsby-node.js index 8481dd23de4cc..f3ef735ecd060 100644 --- a/packages/gatsby-plugin-sass/src/gatsby-node.js +++ b/packages/gatsby-plugin-sass/src/gatsby-node.js @@ -2,7 +2,7 @@ import resolve from "./resolve" exports.onCreateWebpackConfig = ( { actions, stage, rules, plugins, loaders }, - { postCssPlugins, ...sassOptions } + { cssLoaderOptions = {}, postCssPlugins, ...sassOptions } ) => { const { setWebpackConfig } = actions const PRODUCTION = stage !== `develop` @@ -22,7 +22,7 @@ exports.onCreateWebpackConfig = ( ? [loaders.null()] : [ loaders.miniCssExtract(), - loaders.css({ importLoaders: 2 }), + loaders.css({ ...cssLoaderOptions, importLoaders: 2 }), loaders.postcss({ plugins: postCssPlugins }), sassLoader, ], @@ -31,7 +31,7 @@ exports.onCreateWebpackConfig = ( test: /\.module\.s(a|c)ss$/, use: [ !isSSR && loaders.miniCssExtract(), - loaders.css({ modules: true, importLoaders: 2 }), + loaders.css({ ...cssLoaderOptions, modules: true, importLoaders: 2 }), loaders.postcss({ plugins: postCssPlugins }), sassLoader, ].filter(Boolean),