diff --git a/src/index.js b/src/index.js index 182f3ad7..088ab5fb 100644 --- a/src/index.js +++ b/src/index.js @@ -2,6 +2,7 @@ import webpack from 'webpack'; import sources from 'webpack-sources'; +import { contextify } from 'webpack/lib/util/identifier'; import validateOptions from 'schema-utils'; @@ -24,6 +25,29 @@ const REGEXP_NAME = /\[name\]/i; const REGEXP_PLACEHOLDERS = /\[(name|id|chunkhash)\]/g; const DEFAULT_FILENAME = '[name].css'; +const contextifySourceMap = (context, sourceMap) => { + if (!sourceMap || !Array.isArray(sourceMap.sources)) return sourceMap; + const { sourceRoot, ...rest } = sourceMap; + const mapper = (source) => { + if (!sourceRoot) return source; + if (sourceRoot.endsWith('/')) { + return source.startsWith('/') + ? `${sourceRoot.slice(0, -1)}${source}` + : `${sourceRoot}${source}`; + } + return source.startsWith('/') + ? `${sourceRoot}${source}` + : `${sourceRoot}/${source}`; + }; + const newSources = sourceMap.sources.map((source) => + contextify(context, mapper(source)) + ); + return { + ...rest, + sources: newSources, + }; +}; + class CssDependencyTemplate { apply() {} } @@ -37,7 +61,7 @@ class CssModule extends webpack.Module { this._identifierIndex = dependency.identifierIndex; this.content = dependency.content; this.media = dependency.media; - this.sourceMap = dependency.sourceMap; + this.sourceMap = contextifySourceMap(this.context, dependency.sourceMap); } // no source() so webpack doesn't do add stuff to the bundle @@ -70,7 +94,7 @@ class CssModule extends webpack.Module { updateCacheModule(module) { this.content = module.content; this.media = module.media; - this.sourceMap = module.sourceMap; + this.sourceMap = contextifySourceMap(this.context, module.sourceMap); } needRebuild() { @@ -88,7 +112,10 @@ class CssModule extends webpack.Module { hash.update(this.content); hash.update(this.media || ''); - hash.update(this.sourceMap ? JSON.stringify(this.sourceMap) : ''); + + if (this.useSourceMap && this.sourceMap) { + hash.update(JSON.stringify(this.sourceMap)); + } } } diff --git a/test/cases/contenthash-source-map/expected/1.main.0161cbb7ed9c98e1f941.css b/test/cases/contenthash-source-map/expected/1.main.0161cbb7ed9c98e1f941.css new file mode 100644 index 00000000..e62cee21 --- /dev/null +++ b/test/cases/contenthash-source-map/expected/1.main.0161cbb7ed9c98e1f941.css @@ -0,0 +1,6 @@ +body { + background: red; +} + + +/*# sourceMappingURL=1.main.0161cbb7ed9c98e1f941.css.map*/ \ No newline at end of file diff --git a/test/cases/contenthash-source-map/expected/2.main.77435aabc088bf763690.css b/test/cases/contenthash-source-map/expected/2.main.77435aabc088bf763690.css new file mode 100644 index 00000000..12d7559a --- /dev/null +++ b/test/cases/contenthash-source-map/expected/2.main.77435aabc088bf763690.css @@ -0,0 +1,6 @@ +body { + background: green; +} + + +/*# sourceMappingURL=2.main.77435aabc088bf763690.css.map*/ \ No newline at end of file diff --git a/test/cases/contenthash-source-map/index.js b/test/cases/contenthash-source-map/index.js new file mode 100644 index 00000000..b2998624 --- /dev/null +++ b/test/cases/contenthash-source-map/index.js @@ -0,0 +1,2 @@ +// eslint-disable-next-line import/no-unresolved +import './style.css'; diff --git a/test/cases/contenthash-source-map/style1.css b/test/cases/contenthash-source-map/style1.css new file mode 100644 index 00000000..67ce83e4 --- /dev/null +++ b/test/cases/contenthash-source-map/style1.css @@ -0,0 +1,3 @@ +body { + background: red; +} diff --git a/test/cases/contenthash-source-map/style2.css b/test/cases/contenthash-source-map/style2.css new file mode 100644 index 00000000..90439bac --- /dev/null +++ b/test/cases/contenthash-source-map/style2.css @@ -0,0 +1,3 @@ +body { + background: green; +} diff --git a/test/cases/contenthash-source-map/webpack.config.js b/test/cases/contenthash-source-map/webpack.config.js new file mode 100644 index 00000000..a4bd0055 --- /dev/null +++ b/test/cases/contenthash-source-map/webpack.config.js @@ -0,0 +1,39 @@ +import Self from '../../../src'; + +module.exports = [1, 2].map((n) => { + return { + entry: './index.js', + devtool: 'source-map', + module: { + rules: [ + { + test: /\.css$/, + use: [ + { + loader: Self.loader, + }, + { + loader: 'css-loader', + options: { + sourceMap: true, + }, + }, + ], + }, + ], + }, + output: { + filename: `${n}.[name].js`, + }, + resolve: { + alias: { + './style.css': `./style${n}.css`, + }, + }, + plugins: [ + new Self({ + filename: `${n}.[name].[contenthash].css`, + }), + ], + }; +});