Skip to content

Commit 87334cf

Browse files
fix(src): CSS Modules HMR [PATCH] (#82)
* fix(src): CSS Modules HMR [PATCH] Short term solution to get css modules to hot reload for everyone. fix #80, #77 * style: Linting and generalized updates basic updates to code, linting, new yarn lock and so on
1 parent 345509e commit 87334cf

10 files changed

+316
-335
lines changed

.github/CODEOWNERS

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# extract-css-chunks-webpack-plugin maintainers
2-
* @faceyspacey @zackljackson
2+
* @faceyspacey @ScriptedAlchemy

src/hotLoader.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ function hotReload(content) {
1717
if(module.hot) {
1818
// ${Date.now()}
1919
var cssReload = require(${loaderUtils.stringifyRequest(
20-
this,
21-
`!${path.join(__dirname, 'hotModuleReplacement.js')}`,
22-
)})(module.id, ${JSON.stringify(options)});
20+
this,
21+
`!${path.join(__dirname, 'hotModuleReplacement.js')}`,
22+
)})(module.id, ${JSON.stringify(options)});
2323
module.hot.dispose(cssReload);
2424
module.hot.accept(undefined, cssReload);
2525
}

src/hotModuleReplacement.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const srcByModuleId = Object.create(null);
44
const debounce = require('lodash/debounce');
55

66
const noDocument = typeof document === 'undefined';
7-
const forEach = Array.prototype.forEach;
7+
const { forEach } = Array.prototype;
88

99
const noop = function () {};
1010

@@ -13,13 +13,13 @@ const getCurrentScriptUrl = function (moduleId) {
1313

1414
if (!src) {
1515
if (document.currentScript) {
16-
src = document.currentScript.src;
16+
src = document.currentScript.src; // eslint-disable-line prefer-destructuring
1717
} else {
1818
const scripts = document.getElementsByTagName('script');
1919
const lastScriptTag = scripts[scripts.length - 1];
2020

2121
if (lastScriptTag) {
22-
src = lastScriptTag.src;
22+
src = lastScriptTag.src; // eslint-disable-line prefer-destructuring
2323
}
2424
}
2525
srcByModuleId[moduleId] = src;
@@ -43,7 +43,7 @@ const getCurrentScriptUrl = function (moduleId) {
4343

4444
function updateCss(el, url) {
4545
if (!url) {
46-
url = el.href.split('?')[0];
46+
[url] = el.href.split('?');
4747
}
4848
if (el.isLoaded === false) {
4949
// We seem to be about to replace a css link that hasn't loaded yet.
@@ -80,7 +80,7 @@ function getReloadUrl(href, src) {
8080
return ret;
8181
}
8282

83-
function reloadStyle(src) {
83+
function reloadStyle(src) { // eslint-disable-line no-unused-vars
8484
const elements = document.querySelectorAll('link');
8585
let loaded = false;
8686

@@ -114,7 +114,7 @@ module.exports = function (moduleId, options) {
114114

115115
function update() {
116116
const src = getScriptSrc(options.fileMap);
117-
const reloaded = reloadStyle(src);
117+
const reloaded = false; // hack of all hacks...for now
118118
if (reloaded) {
119119
console.log('[HMR] css reload %s', src.join(' ')); // eslint-disable-line no-console
120120
} else {

src/index.js

+16-17
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const isHMR = (compiler) => {
2424
}
2525

2626
if (compiler.options.entry) {
27-
const entry = typeof compiler.options.entry === 'function' ? compiler.options.entry() : compiler.options.entry;
27+
const entry = typeof compiler.options.entry === 'function' ? compiler.options.entry() : compiler.options.entry;
2828
const entryString = JSON.stringify(entry);
2929
return entryString.includes('hot') || entryString.includes('hmr');
3030
}
@@ -34,7 +34,9 @@ const isHMR = (compiler) => {
3434

3535
class CssDependency extends webpack.Dependency {
3636
constructor(
37-
{ identifier, content, media, sourceMap },
37+
{
38+
identifier, content, media, sourceMap,
39+
},
3840
context,
3941
identifierIndex,
4042
) {
@@ -80,7 +82,7 @@ class CssModule extends webpack.Module {
8082
readableIdentifier(requestShortener) {
8183
return `css ${requestShortener.shorten(this._identifier)}${
8284
this._identifierIndex ? ` (${this._identifierIndex})` : ''
83-
}`;
85+
}`;
8486
}
8587

8688
nameForCondition() {
@@ -208,11 +210,10 @@ class ExtractCssChunks {
208210
);
209211
if (renderedModules.length > 0) {
210212
result.push({
211-
render: () =>
212-
this.renderContentAsset(
213-
renderedModules,
214-
compilation.runtimeTemplate.requestShortener,
215-
),
213+
render: () => this.renderContentAsset(
214+
renderedModules,
215+
compilation.runtimeTemplate.requestShortener,
216+
),
216217
filenameTemplate: this.options.filename,
217218
pathOptions: {
218219
chunk,
@@ -232,11 +233,10 @@ class ExtractCssChunks {
232233
);
233234
if (renderedModules.length > 0) {
234235
result.push({
235-
render: () =>
236-
this.renderContentAsset(
237-
renderedModules,
238-
compilation.runtimeTemplate.requestShortener,
239-
),
236+
render: () => this.renderContentAsset(
237+
renderedModules,
238+
compilation.runtimeTemplate.requestShortener,
239+
),
240240
filenameTemplate: this.options.chunkFilename,
241241
pathOptions: {
242242
chunk,
@@ -306,8 +306,7 @@ class ExtractCssChunks {
306306
JSON.stringify(this.options.chunkFilename),
307307
{
308308
hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`,
309-
hashWithLength: length =>
310-
`" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`,
309+
hashWithLength: length => `" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`,
311310
chunk: {
312311
id: '" + chunkId + "',
313312
hash: `" + ${JSON.stringify(chunkMaps.hash)}[chunkId] + "`,
@@ -317,7 +316,7 @@ class ExtractCssChunks {
317316
if (typeof chunkMaps.hash[chunkId] === 'string') {
318317
shortChunkHashMap[chunkId] = chunkMaps.hash[
319318
chunkId
320-
].substring(0, length);
319+
].substring(0, length);
321320
}
322321
}
323322
return `" + ${JSON.stringify(
@@ -337,7 +336,7 @@ class ExtractCssChunks {
337336
if (typeof contentHash[chunkId] === 'string') {
338337
shortContentHashMap[chunkId] = contentHash[
339338
chunkId
340-
].substring(0, length);
339+
].substring(0, length);
341340
}
342341
}
343342
return `" + ${JSON.stringify(

src/loader.js

+39-43
Original file line numberDiff line numberDiff line change
@@ -35,66 +35,62 @@ export function pitch(request) {
3535
const loaders = this.loaders.slice(this.loaderIndex + 1);
3636
this.addDependency(this.resourcePath);
3737
const childFilename = '*'; // eslint-disable-line no-path-concat
38-
const publicPath =
39-
typeof query.publicPath === 'string'
40-
? query.publicPath
41-
: this._compilation.outputOptions.publicPath;
38+
const publicPath = typeof query.publicPath === 'string'
39+
? query.publicPath
40+
: this._compilation.outputOptions.publicPath;
4241
const outputOptions = {
4342
filename: childFilename,
4443
publicPath,
4544
};
4645
const childCompiler = this._compilation.createChildCompiler(
47-
`extract-css-chunks-webpack-plugin ${request}`,
48-
outputOptions,
49-
);
46+
`extract-css-chunks-webpack-plugin ${request}`,
47+
outputOptions,
48+
);
5049
new NodeTemplatePlugin(outputOptions).apply(childCompiler);
5150
new LibraryTemplatePlugin(null, 'commonjs2').apply(childCompiler);
5251
new NodeTargetPlugin().apply(childCompiler);
5352
new SingleEntryPlugin(
54-
this.context,
55-
`!!${request}`,
56-
'extract-css-chunks-webpack-plugin',
57-
).apply(childCompiler);
53+
this.context,
54+
`!!${request}`,
55+
'extract-css-chunks-webpack-plugin',
56+
).apply(childCompiler);
5857
new LimitChunkCountPlugin({ maxChunks: 1 }).apply(childCompiler);
59-
// We set loaderContext[NS] = false to indicate we already in
60-
// a child compiler so we don't spawn another child compilers from there.
58+
// We set loaderContext[NS] = false to indicate we already in
59+
// a child compiler so we don't spawn another child compilers from there.
6160
childCompiler.hooks.thisCompilation.tap(
61+
'extract-css-chunks-webpack-plugin loader',
62+
(compilation) => {
63+
compilation.hooks.normalModuleLoader.tap(
6264
'extract-css-chunks-webpack-plugin loader',
63-
(compilation) => {
64-
compilation.hooks.normalModuleLoader.tap(
65-
'extract-css-chunks-webpack-plugin loader',
66-
(loaderContext, module) => {
67-
loaderContext[NS] = false; // eslint-disable-line no-param-reassign
68-
if (module.request === request) {
69-
module.loaders = loaders.map(loader =>
70-
// eslint-disable-line no-param-reassign
71-
({
72-
loader: loader.path,
73-
options: loader.options,
74-
ident: loader.ident,
75-
}));
76-
}
77-
},
78-
);
65+
(loaderContext, module) => {
66+
loaderContext[NS] = false; // eslint-disable-line no-param-reassign
67+
if (module.request === request) {
68+
module.loaders = loaders.map(loader => ({
69+
loader: loader.path,
70+
options: loader.options,
71+
ident: loader.ident,
72+
}));
73+
}
7974
},
80-
);
75+
);
76+
},
77+
);
8178

8279
let source;
8380
childCompiler.hooks.afterCompile.tap(
84-
'extract-css-chunks-webpack-plugin',
85-
(compilation) => {
86-
source =
87-
compilation.assets[childFilename] &&
88-
compilation.assets[childFilename].source();
81+
'extract-css-chunks-webpack-plugin',
82+
(compilation) => {
83+
source = compilation.assets[childFilename]
84+
&& compilation.assets[childFilename].source();
8985

90-
// Remove all chunk assets
91-
compilation.chunks.forEach((chunk) => {
92-
chunk.files.forEach((file) => {
93-
delete compilation.assets[file]; // eslint-disable-line no-param-reassign
94-
});
95-
});
96-
},
97-
);
86+
// Remove all chunk assets
87+
compilation.chunks.forEach((chunk) => {
88+
chunk.files.forEach((file) => {
89+
delete compilation.assets[file]; // eslint-disable-line no-param-reassign
90+
});
91+
});
92+
},
93+
);
9894

9995
const callback = this.async();
10096
childCompiler.runAsChild((err, entries, compilation) => {

test/cases/js-hash/expected/style.52045f9d3d70ab1f399c.js

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/cases/js-hash/expected/style.e67f14693c61017dad40.js

-10
This file was deleted.

0 commit comments

Comments
 (0)