From 1edac29eba1a621339105f5adef73d4c30388fee Mon Sep 17 00:00:00 2001 From: pooya parsa Date: Tue, 30 Jun 2020 19:47:42 +0200 Subject: [PATCH] fix(webpack): use compact name for concatenated modules (#7639) [release] --- packages/config/src/config/build.js | 11 ++++--- .../test/__snapshots__/options.test.js.snap | 7 ++-- .../config/__snapshots__/index.test.js.snap | 14 +++++--- packages/config/test/config/build.test.js | 4 +-- packages/utils/src/resolve.js | 5 ++- packages/webpack/src/config/client.js | 32 +++++++++++-------- test/dev/modern.client.test.js | 20 ++++++------ test/dev/modern.server.test.js | 24 +++++++------- test/dev/modern.spa.test.js | 20 ++++++------ test/dev/spa.test.js | 2 +- test/dev/with-config.test.js | 5 --- test/fixtures/modern/nuxt.config.js | 8 ++--- .../shared-chunk/components/shared-vendor.vue | 19 +++++++++++ .../shared-chunk/components/shared.vue | 5 +++ test/fixtures/shared-chunk/nuxt.config.js | 3 ++ .../shared-chunk/pages/_cat/_id/_sub.vue | 6 ++++ test/fixtures/shared-chunk/pages/index.vue | 5 +++ .../shared-chunk/pages/product/_id.vue | 6 ++++ 18 files changed, 124 insertions(+), 72 deletions(-) create mode 100644 test/fixtures/shared-chunk/components/shared-vendor.vue create mode 100644 test/fixtures/shared-chunk/components/shared.vue create mode 100644 test/fixtures/shared-chunk/nuxt.config.js create mode 100644 test/fixtures/shared-chunk/pages/_cat/_id/_sub.vue create mode 100644 test/fixtures/shared-chunk/pages/index.vue create mode 100644 test/fixtures/shared-chunk/pages/product/_id.vue diff --git a/packages/config/src/config/build.js b/packages/config/src/config/build.js index b45d01e19c..6d38d5335f 100644 --- a/packages/config/src/config/build.js +++ b/packages/config/src/config/build.js @@ -14,8 +14,8 @@ export default () => ({ serverURLPolyfill: 'url', filenames: { // { isDev, isClient, isServer } - app: ({ isDev, isModern }) => isDev ? `${isModern ? 'modern-' : ''}[name].js` : '[name].[contenthash:7].js', - chunk: ({ isDev, isModern }) => isDev ? `${isModern ? 'modern-' : ''}[name].js` : '[name].[contenthash:7].js', + app: ({ isDev, isModern }) => isDev ? `[name]${isModern ? '.modern' : ''}.js` : `[name].[contenthash:7]${isModern ? '.modern' : ''}.js`, + chunk: ({ isDev, isModern }) => isDev ? `[name]${isModern ? '.modern' : ''}.js` : `[name].[contenthash:7]${isModern ? '.modern' : ''}.js`, css: ({ isDev }) => isDev ? '[name].css' : '[name].[contenthash:7].css', img: ({ isDev }) => isDev ? '[path][name].[ext]' : 'img/[name].[contenthash:7].[ext]', font: ({ isDev }) => isDev ? '[path][name].[ext]' : 'fonts/[name].[contenthash:7].[ext]', @@ -62,9 +62,12 @@ export default () => ({ minimizer: undefined, splitChunks: { chunks: 'all', - automaticNameDelimiter: '.', name: undefined, - cacheGroups: {} + cacheGroups: { + default: { + name: undefined + } + } } }, splitChunks: { diff --git a/packages/config/test/__snapshots__/options.test.js.snap b/packages/config/test/__snapshots__/options.test.js.snap index 9855fbb8b7..1df80864a6 100644 --- a/packages/config/test/__snapshots__/options.test.js.snap +++ b/packages/config/test/__snapshots__/options.test.js.snap @@ -112,8 +112,11 @@ Object { "minimizer": undefined, "runtimeChunk": "single", "splitChunks": Object { - "automaticNameDelimiter": ".", - "cacheGroups": Object {}, + "cacheGroups": Object { + "default": Object { + "name": undefined, + }, + }, "chunks": "all", "name": undefined, }, diff --git a/packages/config/test/config/__snapshots__/index.test.js.snap b/packages/config/test/config/__snapshots__/index.test.js.snap index 474a2a3591..4b231057bb 100644 --- a/packages/config/test/config/__snapshots__/index.test.js.snap +++ b/packages/config/test/config/__snapshots__/index.test.js.snap @@ -88,8 +88,11 @@ Object { "minimizer": undefined, "runtimeChunk": "single", "splitChunks": Object { - "automaticNameDelimiter": ".", - "cacheGroups": Object {}, + "cacheGroups": Object { + "default": Object { + "name": undefined, + }, + }, "chunks": "all", "name": undefined, }, @@ -458,8 +461,11 @@ Object { "minimizer": undefined, "runtimeChunk": "single", "splitChunks": Object { - "automaticNameDelimiter": ".", - "cacheGroups": Object {}, + "cacheGroups": Object { + "default": Object { + "name": undefined, + }, + }, "chunks": "all", "name": undefined, }, diff --git a/packages/config/test/config/build.test.js b/packages/config/test/config/build.test.js index f9336df0e8..769574db04 100644 --- a/packages/config/test/config/build.test.js +++ b/packages/config/test/config/build.test.js @@ -26,7 +26,7 @@ describe('config: build', () => { test('should return modern filenames', () => { const { filenames } = buildConfig() const env = { isDev: true, isModern: true } - expect(filenames.app(env)).toEqual('modern-[name].js') - expect(filenames.chunk(env)).toEqual('modern-[name].js') + expect(filenames.app(env)).toEqual('[name].modern.js') + expect(filenames.chunk(env)).toEqual('[name].modern.js') }) }) diff --git a/packages/utils/src/resolve.js b/packages/utils/src/resolve.js index 79d43f516a..4a54c6cfba 100644 --- a/packages/utils/src/resolve.js +++ b/packages/utils/src/resolve.js @@ -17,10 +17,9 @@ export const wp = function wp (p = '') { return p } +// Kept for backward compat (modules may use it from template context) export const wChunk = function wChunk (p = '') { - // workaround for SplitChunksPlugin that generate names starting from . for catchAll pages _.vue - // consider using https://webpack.js.org/configuration/output/#outputfilename for more robust control over filename generation - return p.replace('_', '[_]') + return p } const reqSep = /\//g diff --git a/packages/webpack/src/config/client.js b/packages/webpack/src/config/client.js index 559ed7c1b6..095c4ecfdf 100644 --- a/packages/webpack/src/config/client.js +++ b/packages/webpack/src/config/client.js @@ -38,16 +38,6 @@ export default class WebpackClientConfig extends WebpackBaseConfig { } } - getFileName (...args) { - if (this.buildContext.buildOptions.analyze) { - const [key] = args - if (['app', 'chunk'].includes(key)) { - return `${this.isModern ? 'modern-' : ''}[name].js` - } - } - return super.getFileName(...args) - } - env () { return Object.assign( super.env(), @@ -63,18 +53,34 @@ export default class WebpackClientConfig extends WebpackBaseConfig { optimization () { const optimization = super.optimization() + const { splitChunks } = optimization + const { cacheGroups } = splitChunks // Small, known and common modules which are usually used project-wise // Sum of them may not be more than 244 KiB if ( this.buildContext.buildOptions.splitChunks.commons === true && - optimization.splitChunks.cacheGroups.commons === undefined + cacheGroups.commons === undefined ) { - optimization.splitChunks.cacheGroups.commons = { + cacheGroups.commons = { test: /node_modules[\\/](vue|vue-loader|vue-router|vuex|vue-meta|core-js|@babel\/runtime|axios|webpack|setimmediate|timers-browserify|process|regenerator-runtime|cookie|js-cookie|is-buffer|dotprop|nuxt\.js)[\\/]/, chunks: 'all', priority: 10, - name: true + name: true, + automaticNameDelimiter: '/' + } + } + + if (!this.dev && cacheGroups.default && cacheGroups.default.name === undefined) { + cacheGroups.default.name = (_module, chunks) => { + // Use default name for single chunks + if (chunks.length === 1) { + return chunks[0].name || '' + } + // Use compact name for concatinated modules + return 'commons/' + chunks.filter(c => c.name).map(c => + c.name.replace(/\//g, '.').replace(/_/g, '').replace('pages.', '') + ).join('~') } } diff --git a/test/dev/modern.client.test.js b/test/dev/modern.client.test.js index 251085667b..88f531426f 100644 --- a/test/dev/modern.client.test.js +++ b/test/dev/modern.client.test.js @@ -1,4 +1,4 @@ -import { loadFixture, getPort, Nuxt, rp, wChunk } from '../utils' +import { loadFixture, getPort, Nuxt, rp } from '../utils' let nuxt, port const url = route => 'http://localhost:' + port + route @@ -16,28 +16,28 @@ describe('modern client mode (SSR)', () => { test('should contain nomodule legacy resources', async () => { const { body: response } = await rp(url('/')) expect(response).toContain('script nomodule crossorigin="use-credentials" src="/_nuxt/app.js') - expect(response).toContain('script nomodule crossorigin="use-credentials" src="/_nuxt/commons.app.js') + expect(response).toContain('script nomodule crossorigin="use-credentials" src="/_nuxt/commons/app.js') }) test('should contain module modern resources', async () => { const { body: response } = await rp(url('/')) - expect(response).toContain(' diff --git a/test/fixtures/shared-chunk/components/shared.vue b/test/fixtures/shared-chunk/components/shared.vue new file mode 100644 index 0000000000..8dc155c8a0 --- /dev/null +++ b/test/fixtures/shared-chunk/components/shared.vue @@ -0,0 +1,5 @@ + diff --git a/test/fixtures/shared-chunk/nuxt.config.js b/test/fixtures/shared-chunk/nuxt.config.js new file mode 100644 index 0000000000..140850c613 --- /dev/null +++ b/test/fixtures/shared-chunk/nuxt.config.js @@ -0,0 +1,3 @@ +export default { + components: true +} diff --git a/test/fixtures/shared-chunk/pages/_cat/_id/_sub.vue b/test/fixtures/shared-chunk/pages/_cat/_id/_sub.vue new file mode 100644 index 0000000000..d6b76befeb --- /dev/null +++ b/test/fixtures/shared-chunk/pages/_cat/_id/_sub.vue @@ -0,0 +1,6 @@ + diff --git a/test/fixtures/shared-chunk/pages/index.vue b/test/fixtures/shared-chunk/pages/index.vue new file mode 100644 index 0000000000..d380811d60 --- /dev/null +++ b/test/fixtures/shared-chunk/pages/index.vue @@ -0,0 +1,5 @@ + diff --git a/test/fixtures/shared-chunk/pages/product/_id.vue b/test/fixtures/shared-chunk/pages/product/_id.vue new file mode 100644 index 0000000000..d6b76befeb --- /dev/null +++ b/test/fixtures/shared-chunk/pages/product/_id.vue @@ -0,0 +1,6 @@ +