diff --git a/README.md b/README.md index dc02a7f2..9b71fa86 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ module.exports = { new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional - filename: "[name].css", + filename: "[name].css", // [contenthash] is supported chunkFilename: "[id].css" }) ], diff --git a/src/index.js b/src/index.js index 8449af47..4de41376 100644 --- a/src/index.js +++ b/src/index.js @@ -2,6 +2,7 @@ import fs from 'fs'; import path from 'path'; import webpack from 'webpack'; import sources from 'webpack-sources'; +import loaderUtils from 'loader-utils'; const { ConcatSource, SourceMapSource, OriginalSource } = sources; const { Template } = webpack; @@ -95,6 +96,19 @@ class MiniCssExtractPlugin { } apply(compiler) { + // add contenthash support + compiler.hooks.emit.tap(pluginName, (compilation) => { + const regexp = /\[(?:(\w+):)?contenthash(?::([a-z]+\d*))?(?::(\d+))?\]/ig; + Object.keys(compilation.assets).forEach((filename) => { + if (regexp.test(filename)) { + const source = compilation.assets[filename].source(); + const getHashDigest = (...args) => loaderUtils.getHashDigest(source, args[1], args[2], parseInt(args[3], 10)); + const newFilename = filename.replace(regexp, getHashDigest); + compilation.assets[newFilename] = compilation.assets[filename]; // eslint-disable-line no-param-reassign + delete compilation.assets[filename]; // eslint-disable-line no-param-reassign + } + }); + }); compiler.hooks.thisCompilation.tap(pluginName, (compilation) => { compilation.hooks.normalModuleLoader.tap(pluginName, (lc, m) => { const loaderContext = lc; diff --git a/test/cases/simple-contenthash/expected/main.b90cb67ebad35ad4d10bd6ba71a70638.css b/test/cases/simple-contenthash/expected/main.b90cb67ebad35ad4d10bd6ba71a70638.css new file mode 100644 index 00000000..aea53e43 --- /dev/null +++ b/test/cases/simple-contenthash/expected/main.b90cb67ebad35ad4d10bd6ba71a70638.css @@ -0,0 +1,2 @@ +body { background: red; } + diff --git a/test/cases/simple-contenthash/index.js b/test/cases/simple-contenthash/index.js new file mode 100644 index 00000000..aa3357bf --- /dev/null +++ b/test/cases/simple-contenthash/index.js @@ -0,0 +1 @@ +import './style.css'; diff --git a/test/cases/simple-contenthash/style.css b/test/cases/simple-contenthash/style.css new file mode 100644 index 00000000..31fc5b8a --- /dev/null +++ b/test/cases/simple-contenthash/style.css @@ -0,0 +1 @@ +body { background: red; } diff --git a/test/cases/simple-contenthash/webpack.config.js b/test/cases/simple-contenthash/webpack.config.js new file mode 100644 index 00000000..eed25f76 --- /dev/null +++ b/test/cases/simple-contenthash/webpack.config.js @@ -0,0 +1,21 @@ +const Self = require('../../../'); + +module.exports = { + entry: './index.js', + module: { + rules: [ + { + test: /\.css$/, + use: [ + Self.loader, + 'css-loader', + ], + }, + ], + }, + plugins: [ + new Self({ + filename: '[name].[contenthash].css', + }), + ], +};