diff --git a/docs/migration-guide.md b/docs/migration-guide.md index a474d17ed..84d4bc954 100644 --- a/docs/migration-guide.md +++ b/docs/migration-guide.md @@ -320,6 +320,7 @@ module.exports = { } ``` +- **BREAKING CHANGE** `@neutrinojs/style-loader` now creates a single `style` rule with `oneOfs`, instead of multiple rules for handling css modules ((#1281)[https://github.com/neutrinojs/neutrino/pull/1281]). - ESLint caching is now enabled by default for new projects, so it is recommended to specify `.eslintcache` as being ignored from your source control commits. diff --git a/packages/style-loader/README.md b/packages/style-loader/README.md index db2c8398b..51157632a 100644 --- a/packages/style-loader/README.md +++ b/packages/style-loader/README.md @@ -57,12 +57,8 @@ neutrino.use(styles, { loaders: [], test: /\.css$/, ruleId: 'style', - styleUseId: 'style', - cssUseId: 'css', modules: true, - modulesSuffix: '-modules', modulesTest: /\.module.css$/, - extractId: 'extract', extract: { enabled: process.env.NODE_ENV === 'production', loader: {}, @@ -83,32 +79,11 @@ module.exports = { use: ['@neutrinojs/style-loader'] }; -// Usage showing default options +// Usage with options module.exports = { use: [ ['@neutrinojs/style-loader', { - style: {}, - css: { - importLoaders: opts.loaders ? opts.loaders.length : 0 - }, - loaders: [], - test: /\.css$/, - ruleId: 'style', - styleUseId: 'style', - cssUseId: 'css', - modules: true, - modulesSuffix: '-modules', - modulesTest: /\.module.css$/, - extractId: 'extract', - extract: { - enabled: process.env.NODE_ENV === 'production', - loader: {}, - plugin: { - filename: process.env.NODE_ENV === 'production' - ? 'assets/[name].[contenthash:8].css' - : 'assets/[name].css' - } - } + modules: false, }] ] }; @@ -119,14 +94,8 @@ module.exports = { - `loaders`: Provide an array of custom loaders used when loading stylesheets - `test`: File extensions which support stylesheets - `ruleId`: The ID of the webpack-chain rule used to identify the stylesheet loaders -- `styleUseId`: The ID of the webpack-chain `use` used to identify the style-loader -- `cssUseId`: The ID of the webpack-chain `use` used to identify the css-loader - `modules`: Enable usage of CSS modules via `*.module.css` files. Set to `false` to disable and skip defining these rules. -- `modulesSuffix`: A suffix added to `ruleId`, `styleUseId`, `cssUseId`, `hotUseId`, and `extractId` to derive names for -modules-related rules. For example, the default `-modules` suffix will generate a rule ID for the CSS modules rules of -`style-modules`, while the normal rule remains as `style`. - `modulesTest`: File extensions which support CSS Modules stylesheets -- `extractId`: The ID of the webpack-chain plugin used to identify the `ExtractTextPlugin` - `extract`: Options relating to the `ExtractTextPlugin` instance. Override `extract.plugin` to override plugin options. Override `extract.loader` to override the loader options. Set to `false` to disable stylesheet extraction. @@ -145,7 +114,7 @@ by other consuming middleware. Each loader object can specify 3 properties: Using a string to define loaders will cause `@neutrinojs/style-loader` to still generate a loader object. The string will be used as the `loader` property, `options` will be left blank, and the `useId` will be derived from -`cssUseId` option above plus the index of this loader within the `loaders` array. +the index of this loader within the `loaders` array. **Important:** The `useId` for string-defined loaders will start at `2`, since all loaders are preceded by the included `style-loader` and `css-loader`. @@ -243,12 +212,13 @@ ready to make changes. ### Rules -The following is a list of default rules and their identifiers which can be overridden: +The following is a list of default rules/oneOfs and their identifiers which can be overridden: | Name | Description | NODE_ENV | | --- | --- | --- | -| `style` | Allows importing CSS stylesheets from modules. By default contains two loaders named `extract` and `css` which use `MiniCssExtractPlugin.loader` and `css-loader`, respectively. If `options.extract` is `false`, then the `extract` loader is replaced by `style`, which uses `style-loader`. | all | -| `style-modules` | Allows importing CSS Modules styles from modules. By default contains two loaders named `extract` and `css` which use `MiniCssExtractPlugin.loader` and `css-loader`, respectively. If `options.extract` is `false`, then the `extract` loader is replaced by `style`, which uses `style-loader`. | all | +| `style` | A parent rule containing `oneOf` rules for importing stylesheets. | all | +| `style.normal` | Allows importing CSS stylesheets from modules. By default contains two loaders named `extract` and `css` which use `MiniCssExtractPlugin.loader` and `css-loader`, respectively. If `options.extract` is `false`, then the `extract` loader is replaced by `style`, which uses `style-loader`. | all | +| `style.modules` | Allows importing CSS Modules styles from modules. By default contains two loaders named `extract` and `css` which use `MiniCssExtractPlugin.loader` and `css-loader`, respectively. If `options.extract` is `false`, then the `extract` loader is replaced by `style`, which uses `style-loader`. | all | ### Plugins diff --git a/packages/style-loader/index.js b/packages/style-loader/index.js index 6c58af203..5ae9f6d1d 100644 --- a/packages/style-loader/index.js +++ b/packages/style-loader/index.js @@ -8,18 +8,13 @@ module.exports = (neutrino, opts = {}) => { const options = merge({ test: neutrino.regexFromExtensions(['css']), ruleId: 'style', - styleUseId: 'style', - cssUseId: 'css', css: { importLoaders: opts.loaders ? opts.loaders.length : 0 }, style: {}, modules, modulesTest, - modulesSuffix: '-modules', - exclude: modules && modulesTest, loaders: [], - extractId: 'extract', extract: { enabled: isProduction, loader: {}, @@ -36,17 +31,15 @@ module.exports = (neutrino, opts = {}) => { } const extractEnabled = options.extract && options.extract.enabled; - const rules = [options]; + const rules = [merge(options, { + oneOfId: 'normal' + })]; if (options.modules) { - rules.push( + rules.unshift( merge(options, { test: options.modulesTest, - exclude: options.modulesExclude, - ruleId: `${options.ruleId}${options.modulesSuffix}`, - styleUseId: `${options.styleUseId}${options.modulesSuffix}`, - cssUseId: `${options.cssUseId}${options.modulesSuffix}`, - extractId: `${options.extractId}${options.modulesSuffix}`, + oneOfId: 'modules', css: { modules: options.modules } @@ -60,33 +53,33 @@ module.exports = (neutrino, opts = {}) => { { loader: extractEnabled ? require.resolve('mini-css-extract-plugin/dist/loader') : require.resolve('style-loader'), options: extractEnabled ? options.extract.loader : options.style, - useId: extractEnabled ? options.extractId : options.styleUseId + useId: extractEnabled ? 'extract' : 'style' }, { loader: require.resolve('css-loader'), options: options.css, - useId: options.cssUseId + useId: 'css' }, ...options.loaders ] .map((loader, index) => ({ - useId: `${options.cssUseId}-${index}`, + useId: `css-${index}`, ...(typeof loader === 'object' ? loader : { loader }) })); loaders.forEach(loader => { styleRule - .test(options.test) - .when(options.exclude, rule => rule.exclude.add(options.exclude)) - .use(loader.useId) - .loader(loader.loader) - .when(loader.options, use => use.options(loader.options)); + .oneOf(options.oneOfId) + .test(options.test) + .use(loader.useId) + .loader(loader.loader) + .when(loader.options, use => use.options(loader.options)); }); }); if (extractEnabled) { neutrino.config - .plugin(options.extractId) + .plugin('extract') .use(require.resolve('mini-css-extract-plugin'), [options.extract.plugin]); } }; diff --git a/packages/style-loader/test/middleware_test.js b/packages/style-loader/test/middleware_test.js index 2db7a4032..5cbe5e063 100644 --- a/packages/style-loader/test/middleware_test.js +++ b/packages/style-loader/test/middleware_test.js @@ -43,11 +43,12 @@ test('uses CSS modules by default', t => { api.use(mw()); - t.true(api.config.module.rules.has('style-modules')); + t.true(api.config.module.rule('style').oneOfs.has('modules')); const options = api.config.module - .rule('style-modules') - .use('css-modules') + .rule('style') + .oneOf('modules') + .use('css') .get('options'); t.truthy(options && options.modules); @@ -58,12 +59,14 @@ test('respects disabling of CSS modules', t => { api.use(mw(), { modules: false }); - t.false(api.config.module.rules.has('style-modules')); + t.false(api.config.module.rule('style').oneOfs.has('modules')); const style = api.config.module.rule('style').toConfig(); - style.use.forEach(use => { - t.falsy(use.options && use.options.css && use.options.css.modules); + style.oneOf.forEach(oneOf => { + oneOf.use.forEach(use => { + t.falsy(use.options && use.options.css && use.options.css.modules); + }); }); }); @@ -73,8 +76,8 @@ test('does not extract in development by default', t => { api.use(mw()); - t.true(api.config.module.rule('style').uses.has('style')); - t.false(api.config.module.rule('style').uses.has('extract')); + t.true(api.config.module.rule('style').oneOf('normal').uses.has('style')); + t.false(api.config.module.rule('style').oneOf('normal').uses.has('extract')); }); test('extracts in production by default', t => { @@ -83,8 +86,8 @@ test('extracts in production by default', t => { api.use(mw()); - t.false(api.config.module.rule('style').uses.has('style')); - t.true(api.config.module.rule('style').uses.has('extract')); + t.false(api.config.module.rule('style').oneOf('normal').uses.has('style')); + t.true(api.config.module.rule('style').oneOf('normal').uses.has('extract')); }); test('respects enabling of extract in development using extract.enabled', t => { @@ -93,8 +96,8 @@ test('respects enabling of extract in development using extract.enabled', t => { api.use(mw(), { extract: { enabled: true } }); - t.false(api.config.module.rule('style').uses.has('style')); - t.true(api.config.module.rule('style').uses.has('extract')); + t.false(api.config.module.rule('style').oneOf('normal').uses.has('style')); + t.true(api.config.module.rule('style').oneOf('normal').uses.has('extract')); }); test('respects disabling of extract in production using false', t => { @@ -103,8 +106,8 @@ test('respects disabling of extract in production using false', t => { api.use(mw(), { extract: false }); - t.true(api.config.module.rule('style').uses.has('style')); - t.false(api.config.module.rule('style').uses.has('extract')); + t.true(api.config.module.rule('style').oneOf('normal').uses.has('style')); + t.false(api.config.module.rule('style').oneOf('normal').uses.has('extract')); }); test('respects disabling of extract in production using extract.enabled', t => { @@ -113,8 +116,8 @@ test('respects disabling of extract in production using extract.enabled', t => { api.use(mw(), { extract: { enabled: false } }); - t.true(api.config.module.rule('style').uses.has('style')); - t.false(api.config.module.rule('style').uses.has('extract')); + t.true(api.config.module.rule('style').oneOf('normal').uses.has('style')); + t.false(api.config.module.rule('style').oneOf('normal').uses.has('extract')); }); test('throws when used twice', t => { diff --git a/packages/web/README.md b/packages/web/README.md index 727370dfa..62a4a3163 100644 --- a/packages/web/README.md +++ b/packages/web/README.md @@ -464,8 +464,7 @@ The following is a list of rules and their identifiers which can be overridden: | --- | --- | --- | | `compile` | Compiles JS files from the `src` directory using Babel. Contains a single loader named `babel`. From `@neutrinojs/compile-loader`. | all | | `html` | Allows importing HTML files from modules. Contains a single loader named `html`. From `@neutrinojs/html-loader`. | all | -| `style` | Allows importing CSS stylesheets from modules. In production contains two loaders named `extract` and `css` which use `MiniCssExtractPlugin.loader` and `css-loader`, respectively. In development the `extract` loader is replaced by `style`, which uses `style-loader`. From `@neutrinojs/style-loader`. | all | -| `style-modules` | Allows importing CSS Modules styles from modules. In production contains two loaders named `extract` and `css` which use `MiniCssExtractPlugin.loader` and `css-loader`, respectively. In development the `extract` loader is replaced by `style`, which uses `style-loader`. From `@neutrinojs/style-loader`. | all | +| `style` | A parent rule containing `oneOf` rules for importing stylesheets. From `@neutrinojs/style-loader`. | all | | `image` | Allows importing ICO, JPEG, PNG, GIF, SVG and WEBP files from modules. Contains a single loader named `url`. From `@neutrinojs/image-loader`. | all | | `font` | Allows importing EOT, TTF, WOFF and WOFF2 font files from modules. Contains a single loader named `file`. From `@neutrinojs/font-loader`. | all |