Skip to content

Commit 5ca96e9

Browse files
committed
feature #21 Use NamedModulesPlugin for HMR debugging (weaverryan)
This PR was squashed before being merged into the master branch (closes #21). Discussion ---------- Use NamedModulesPlugin for HMR debugging When using HMR, the name of your module shows up in the console. By default, since numbers are used, it looks like: ``` [HMR] Updated modules: [HMR] - 21 [HMR] - 241 ``` After: ``` [HMR] Updated modules: [HMR] - ./node_modules/css-loader/index.js?sourceMap!./node_modules/vue-loader/lib/style-compiler/index.js?{"vue":true,"id":"data-v-504ecf1c","scoped":true,"hasInlineConfig":false}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./app/Resources/assets/vuejs/components/Hello.vue [HMR] - ./node_modules/style-loader/addStyles.js ``` ... which at least makes a bit more sense :). This adds a bit more logic: 1) In dev, always add `NamedModulesPlugin`. We actually only need this if you're using HMR... but I don't think there's a disadvantage of including it always, so I've done it to try to keep the dev environment as consistent as possible with itself. 2) In prod, we *only* add `HashedModuleIdsPlugin` when versioning is enabled. We could at it always (for consistency), but it slightly increases the size of the built assets, because the module ids are longer. 3) Enable `WebpackChunkHash` only when versioning is used, because it's the only time we use the `[chunkhash]` Commits ------- a0ee75d Use NamedModulesPlugin for HMR debugging
2 parents 0efcd3e + a0ee75d commit 5ca96e9

File tree

4 files changed

+59
-16
lines changed

4 files changed

+59
-16
lines changed

lib/config-generator.js

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -243,20 +243,20 @@ class ConfigGenerator {
243243
* * https://github.com/webpack/webpack.js.org/issues/652#issuecomment-273324529
244244
* * https://webpack.js.org/guides/caching/#deterministic-hashes
245245
*/
246-
// when not using versioning, none of this is important
246+
if (this.webpackConfig.isProduction()) {
247+
// shorter, and obfuscated module ids (versus NamedModulesPlugin)
248+
// makes the final assets *slightly* larger, but prevents contents
249+
// from sometimes changing when nothing really changed
250+
plugins.push(new webpack.HashedModuleIdsPlugin());
251+
} else {
252+
// human-readable module names, helps debug in HMR
253+
// enable always when not in production for consistency
254+
plugins.push(new webpack.NamedModulesPlugin());
255+
}
256+
247257
if (this.webpackConfig.useVersioning) {
248-
let moduleNamePlugin;
249-
if (this.webpackConfig.isProduction()) {
250-
// shorter, and obfuscated module ids
251-
moduleNamePlugin = new webpack.HashedModuleIdsPlugin();
252-
} else {
253-
// human-readable module names, helps debug in HMR
254-
moduleNamePlugin = new webpack.NamedModulesPlugin();
255-
}
256-
plugins = plugins.concat([
257-
moduleNamePlugin,
258-
new WebpackChunkHash()
259-
]);
258+
// enables the [chunkhash] ability
259+
plugins.push(new WebpackChunkHash());
260260
}
261261

262262
if (Object.keys(this.webpackConfig.providedVariables).length > 0) {

lib/config/path-util.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,12 @@ module.exports = {
4141
// eventually, you (may) get to the right path
4242
let contentBase = outputPath;
4343
while (path.dirname(contentBase) !== contentBase) {
44-
contentBase = path.dirname(contentBase);
45-
4644
if (path.join(contentBase, publicPath) === outputPath) {
4745
return contentBase;
4846
}
47+
48+
// go up one directory
49+
contentBase = path.dirname(contentBase);
4950
}
5051

5152
throw new Error(`Unable to determine contentBase option for webpack's devServer configuration. The ${webpackConfig.manifestKeyPrefix ? 'manifestKeyPrefix' : 'publicPath'} (${webpackConfig.manifestKeyPrefix ? webpackConfig.manifestKeyPrefix : webpackConfig.publicPath}) string does not exist in the outputPath (${webpackConfig.outputPath}), and so the "document root" cannot be determined.`);

test/config-generator.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ const ManifestPlugin = require('./../lib/webpack/webpack-manifest-plugin');
1818
const CleanWebpackPlugin = require('clean-webpack-plugin');
1919
const webpack = require('webpack');
2020

21+
const isWindows = (process.platform === 'win32');
22+
2123
function createConfig(runtimeConfig = null) {
2224
runtimeConfig = runtimeConfig ? runtimeConfig : new RuntimeConfig();
2325

@@ -236,7 +238,6 @@ describe('The config-generator function', () => {
236238
config.outputPath = '/tmp/output/public-path';
237239
config.publicPath = '/public-path';
238240
config.addEntry('main', './main');
239-
config.enableVersioning(true);
240241

241242
const actualConfig = configGenerator(config);
242243

@@ -373,6 +374,33 @@ describe('The config-generator function', () => {
373374
const actualConfig = configGenerator(config);
374375
expect(actualConfig.devServer).to.be.undefined;
375376
});
377+
378+
it('devServer no hot mode', () => {
379+
const config = createConfig();
380+
config.runtimeConfig.useDevServer = true;
381+
config.runtimeConfig.devServerUrl = 'http://localhost:8080/';
382+
config.runtimeConfig.useHotModuleReplacement = false;
383+
config.outputPath = isWindows ? 'C:\\tmp\\public' : '/tmp/public';
384+
config.setPublicPath('/');
385+
config.addEntry('main', './main');
386+
387+
const actualConfig = configGenerator(config);
388+
expect(actualConfig.devServer).to.not.be.undefined;
389+
expect(actualConfig.devServer.hot).to.be.false;
390+
});
391+
392+
it('hot mode', () => {
393+
const config = createConfig();
394+
config.runtimeConfig.useDevServer = true;
395+
config.runtimeConfig.devServerUrl = 'http://localhost:8080/';
396+
config.runtimeConfig.useHotModuleReplacement = true;
397+
config.outputPath = isWindows ? 'C:\\tmp\\public' : '/tmp/public';
398+
config.setPublicPath('/');
399+
config.addEntry('main', './main');
400+
401+
const actualConfig = configGenerator(config);
402+
expect(actualConfig.devServer.hot).to.be.true;
403+
});
376404
});
377405

378406
describe('test for addPlugin config', () => {

test/config/path-util.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,20 @@ describe('path-util getContentBase()', () => {
5555
const actualContentBase = pathUtil.getContentBase(config);
5656
expect(actualContentBase).to.equal(isWindows ? 'C:\\tmp\\public' : '/tmp/public');
5757
});
58+
59+
it('contentBase is calculated correctly with no public path', function() {
60+
const config = createConfig();
61+
config.runtimeConfig.useDevServer = true;
62+
config.runtimeConfig.devServerUrl = 'http://localhost:8080/';
63+
config.outputPath = isWindows ? 'C:\\tmp\\public' : '/tmp/public';
64+
config.setPublicPath('/');
65+
config.addEntry('main', './main');
66+
67+
const actualContentBase = pathUtil.getContentBase(config);
68+
// contentBase should point to the "document root", which
69+
// is calculated as outputPath, but without the publicPath portion
70+
expect(actualContentBase).to.equal(isWindows ? 'C:\\tmp\\public' : '/tmp/public');
71+
});
5872
});
5973

6074
describe('validatePublicPathAndManifestKeyPrefix', () => {

0 commit comments

Comments
 (0)