diff --git a/.eslintrc.js b/.eslintrc.js index 12a376a4..41c10cb5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -21,6 +21,7 @@ module.exports = { 'prefer-destructuring': 0, 'array-callback-return': 0, 'prefer-template': 0, - 'class-methods-use-this': 0 + 'class-methods-use-this': 0, + 'no-plusplus': 0 } }; diff --git a/README.md b/README.md index dbce0e7b..9d67323b 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ module.exports = { // both options are optional filename: "[name].css", chunkFilename: "[id].css", - hot: true, // optional as the plugin cannot automatically detect if you are using HOT, not for production use + hot: true, // if you want HMR - we try to automatically inject hot reloading but if it's not working, add it to the config orderWarning: true, // Disable to remove warnings about conflicting order between imports reloadAll: true, // when desperation kicks in - this is a brute force HMR flag cssModules: true // if you use cssModules, this can help. @@ -281,6 +281,30 @@ new ExtractCssChunk({ >Keep in mind, by default `[name].css` is used when `process.env.NODE_ENV === 'development'` and `[name].[contenthash].css` during production, so you can likely forget about having to pass anything. +### HMR Troubleshooting +**Blank array in HMR script?** + +If you have issues with HMR, but enabled the loader, plugin, and already tried `hot: true, reloadAll:true`, then your webpack config might be more abstract than my simple lookup functions. In this case, Ive exported out the actual hot loader, you can add this manually and as long as you've got the plugin and loader -- it'll work + +```js + rules: [ + { + test: /\.css$/, + use: [ + ExtractCssChunks.hotLoader, // for those who want to manually force hotLoading + ExtractCssChunks.loader, + { + loader: 'css-loader', + options: { + modules: true, + localIdentName: '[name]__[local]--[hash:base64:5]', + }, + }, + ], + }, + ] +``` + ### HMR Pitfall The most common workflow when working with webpack is to write a "development" / "production" value in to the diff --git a/index.d.ts b/index.d.ts index 8b273f06..39ae31ce 100644 --- a/index.d.ts +++ b/index.d.ts @@ -18,6 +18,8 @@ declare module 'extract-css-chunks-webpack-plugin' { * we try to automatically inject hot reloading, but if it's not working, use this config */ hot?: boolean; + reloadAll?: boolean; + cssModules?: boolean; } } diff --git a/package.json b/package.json index 0773cf1f..452f4e16 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "extract-css-chunks-webpack-plugin", - "version": "3.2.0", + "version": "3.2.1-alpha.1", "author": "James Gillmore ", "contributors": [ "Zack Jackson (https://github.com/ScriptedAlchemy)" diff --git a/src/index.js b/src/index.js index 935d8203..e2a77449 100644 --- a/src/index.js +++ b/src/index.js @@ -427,13 +427,29 @@ class ExtractCssChunks { if (node && node.use && Array.isArray(node.use)) { const isMiniCss = node.use.some((l) => { const needle = l.loader || l; + if (typeof l === 'function') { + return false; + } return needle.includes(pluginName); }); if (isMiniCss) { node.use.unshift(this.hotLoaderObject); } } + if (node && node.loader && Array.isArray(node.loader)) { + const isMiniCss = node.loader.some((l) => { + const needle = l.loader || l; + if (typeof l === 'function') { + return false; + } + return needle.includes(pluginName); + }); + if (isMiniCss) { + node.loader.unshift(this.hotLoaderObject); + } + } }); + rules.push(rule); return rules; @@ -592,5 +608,6 @@ class ExtractCssChunks { } ExtractCssChunks.loader = require.resolve('./loader'); +ExtractCssChunks.hotLoader = require.resolve('./hotLoader'); export default ExtractCssChunks; diff --git a/src/loader.js b/src/loader.js index 66e55049..f5d0b97d 100644 --- a/src/loader.js +++ b/src/loader.js @@ -12,7 +12,8 @@ const pluginName = 'extract-css-chunks-webpack-plugin'; const exec = (loaderContext, code, filename) => { const module = new NativeModule(filename, loaderContext); - module.paths = NativeModule._nodeModulePaths(loaderContext.context); // eslint-disable-line no-underscore-dangle + // eslint-disable-line no-underscore-dangle + module.paths = NativeModule._nodeModulePaths(loaderContext.context); module.filename = filename; module._compile(code, filename); // eslint-disable-line no-underscore-dangle return module.exports; diff --git a/test/cases/function-loader/expected/main.css b/test/cases/function-loader/expected/main.css new file mode 100644 index 00000000..aea53e43 --- /dev/null +++ b/test/cases/function-loader/expected/main.css @@ -0,0 +1,2 @@ +body { background: red; } + diff --git a/test/cases/function-loader/index.js b/test/cases/function-loader/index.js new file mode 100644 index 00000000..74f07de1 --- /dev/null +++ b/test/cases/function-loader/index.js @@ -0,0 +1 @@ +import './main.css'; diff --git a/test/cases/function-loader/main.css b/test/cases/function-loader/main.css new file mode 100644 index 00000000..31fc5b8a --- /dev/null +++ b/test/cases/function-loader/main.css @@ -0,0 +1 @@ +body { background: red; } diff --git a/test/cases/function-loader/webpack.config.js b/test/cases/function-loader/webpack.config.js new file mode 100644 index 00000000..821ab161 --- /dev/null +++ b/test/cases/function-loader/webpack.config.js @@ -0,0 +1,25 @@ + + +const Self = require('../../../'); + +module.exports = { + entry: './index.js', + module: { + rules: [ + { + test: /\.css$/, + use: [ + () => [ + Self.loader, + 'css-loader', + ], + ], + }, + ], + }, + plugins: [ + new Self({ + filename: '[name].css', + }), + ], +};