mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-17 06:01:34 +00:00
fix(webpack): use compact name for concatenated modules (#7639)
[release]
This commit is contained in:
parent
250a1c3918
commit
1edac29eba
@ -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: {
|
||||
|
@ -112,8 +112,11 @@ Object {
|
||||
"minimizer": undefined,
|
||||
"runtimeChunk": "single",
|
||||
"splitChunks": Object {
|
||||
"automaticNameDelimiter": ".",
|
||||
"cacheGroups": Object {},
|
||||
"cacheGroups": Object {
|
||||
"default": Object {
|
||||
"name": undefined,
|
||||
},
|
||||
},
|
||||
"chunks": "all",
|
||||
"name": undefined,
|
||||
},
|
||||
|
@ -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,
|
||||
},
|
||||
|
@ -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')
|
||||
})
|
||||
})
|
||||
|
@ -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
|
||||
|
@ -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('~')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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('<script type="module" crossorigin="use-credentials" src="/_nuxt/modern-app.js"')
|
||||
expect(response).toContain('<script type="module" crossorigin="use-credentials" src="/_nuxt/modern-commons.app.js"')
|
||||
expect(response).toContain('<script type="module" crossorigin="use-credentials" src="/_nuxt/app.modern.js"')
|
||||
expect(response).toContain('<script type="module" crossorigin="use-credentials" src="/_nuxt/commons/app.modern.js"')
|
||||
})
|
||||
|
||||
test('should contain module preload resources', async () => {
|
||||
const { body: response } = await rp(url('/'))
|
||||
expect(response).toContain('<link rel="modulepreload" crossorigin="use-credentials" href="/_nuxt/modern-app.js" as="script">')
|
||||
expect(response).toContain('<link rel="modulepreload" crossorigin="use-credentials" href="/_nuxt/modern-commons.app.js" as="script">')
|
||||
expect(response).toContain('<link rel="modulepreload" crossorigin="use-credentials" href="/_nuxt/app.modern.js" as="script">')
|
||||
expect(response).toContain('<link rel="modulepreload" crossorigin="use-credentials" href="/_nuxt/commons/app.modern.js" as="script">')
|
||||
})
|
||||
|
||||
test('should contain module http2 pushed resources', async () => {
|
||||
const { headers: { link } } = await rp(url('/'))
|
||||
expect(link).toEqual([
|
||||
'</_nuxt/modern-runtime.js>; rel=modulepreload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/modern-commons.app.js>; rel=modulepreload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/modern-app.js>; rel=modulepreload; crossorigin=use-credentials; as=script',
|
||||
`</_nuxt/modern-${wChunk('pages/index.js')}>; rel=modulepreload; crossorigin=use-credentials; as=script`
|
||||
'</_nuxt/runtime.modern.js>; rel=modulepreload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/commons/app.modern.js>; rel=modulepreload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/app.modern.js>; rel=modulepreload; crossorigin=use-credentials; as=script',
|
||||
`</_nuxt/pages/index.modern.js>; rel=modulepreload; crossorigin=use-credentials; as=script`
|
||||
].join(', '))
|
||||
})
|
||||
|
||||
|
@ -24,30 +24,30 @@ describe('modern server mode', () => {
|
||||
test('should use legacy resources by default', async () => {
|
||||
const { body: response } = await rp(url('/'))
|
||||
expect(response).toContain('/_nuxt/app.js')
|
||||
expect(response).toContain('/_nuxt/commons.app.js')
|
||||
expect(response).toContain('/_nuxt/commons/app.js')
|
||||
})
|
||||
|
||||
test('should use modern resources for modern resources', async () => {
|
||||
const { body: response } = await rp(url('/'), { headers: { 'user-agent': modernUA } })
|
||||
expect(response).toContain('/_nuxt/modern-app.js')
|
||||
expect(response).toContain('/_nuxt/modern-commons.app.js')
|
||||
expect(response).toContain('/_nuxt/app.modern.js')
|
||||
expect(response).toContain('/_nuxt/commons/app.modern.js')
|
||||
})
|
||||
|
||||
test('should include es6 syntax in modern resources', async () => {
|
||||
const { body: response } = await rp(url(`/_nuxt/modern-${wChunk('pages/index.js')}`))
|
||||
expect(response).toContain('arrow: () => {')
|
||||
const { body: response } = await rp(url(`/_nuxt/pages/index.modern.js`))
|
||||
expect(response).toContain('=>')
|
||||
})
|
||||
|
||||
test('should not include es6 syntax in normal resources', async () => {
|
||||
const { body: response } = await rp(url(`/_nuxt/${wChunk('pages/index.js')}`))
|
||||
expect(response).toContain('arrow: function arrow() {')
|
||||
const { body: response } = await rp(url(`/_nuxt/pages/index.js`))
|
||||
expect(response).not.toContain('=>')
|
||||
})
|
||||
|
||||
test('should contain legacy http2 pushed resources', async () => {
|
||||
const { headers: { link } } = await rp(url('/'))
|
||||
expect(link).toEqual([
|
||||
'</_nuxt/runtime.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/commons.app.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/commons/app.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/app.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
`</_nuxt/${wChunk('pages/index.js')}>; rel=preload; crossorigin=use-credentials; as=script`
|
||||
].join(', '))
|
||||
@ -58,10 +58,10 @@ describe('modern server mode', () => {
|
||||
headers: { 'user-agent': modernUA }
|
||||
})
|
||||
expect(link).toEqual([
|
||||
'</_nuxt/modern-runtime.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/modern-commons.app.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/modern-app.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
`</_nuxt/modern-${wChunk('pages/index.js')}>; rel=preload; crossorigin=use-credentials; as=script`
|
||||
'</_nuxt/runtime.modern.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/commons/app.modern.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/app.modern.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
`</_nuxt/pages/index.modern.js>; rel=preload; crossorigin=use-credentials; as=script`
|
||||
].join(', '))
|
||||
})
|
||||
|
||||
|
@ -24,34 +24,34 @@ describe('modern client mode (SPA)', () => {
|
||||
test('should contain nomodule legacy resources', async () => {
|
||||
const { body: response } = await rp(url('/'))
|
||||
expect(response).toContain('src="/_nuxt/app.js" crossorigin="use-credentials" nomodule')
|
||||
expect(response).toContain('src="/_nuxt/commons.app.js" crossorigin="use-credentials" nomodule')
|
||||
expect(response).toContain('src="/_nuxt/commons/app.js" crossorigin="use-credentials" nomodule')
|
||||
})
|
||||
|
||||
test('should contain module modern resources', async () => {
|
||||
const { body: response } = await rp(url('/'))
|
||||
expect(response).toContain('<script src="/_nuxt/modern-app.js" type="module" crossorigin="use-credentials"')
|
||||
expect(response).toContain('<script src="/_nuxt/modern-commons.app.js" type="module" crossorigin="use-credentials"')
|
||||
expect(response).toContain('<script src="/_nuxt/app.modern.js" type="module" crossorigin="use-credentials"')
|
||||
expect(response).toContain('<script src="/_nuxt/commons/app.modern.js" type="module" crossorigin="use-credentials"')
|
||||
})
|
||||
|
||||
test('should contain legacy preload resources', async () => {
|
||||
const { body: response } = await rp(url('/'))
|
||||
expect(response).toContain('<link rel="preload" crossorigin="use-credentials" href="/_nuxt/app.js" as="script">')
|
||||
expect(response).toContain('<link rel="preload" crossorigin="use-credentials" href="/_nuxt/commons.app.js" as="script">')
|
||||
expect(response).toContain('<link rel="preload" crossorigin="use-credentials" href="/_nuxt/commons/app.js" as="script">')
|
||||
})
|
||||
|
||||
test('should contain legacy http2 pushed resources', async () => {
|
||||
const { headers: { link } } = await rp(url('/'))
|
||||
expect(link).toEqual([
|
||||
'</_nuxt/runtime.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/commons.app.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/commons/app.js>; rel=preload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/app.js>; rel=preload; crossorigin=use-credentials; as=script'
|
||||
].join(', '))
|
||||
})
|
||||
|
||||
test('should contain modern preload resources', async () => {
|
||||
const { body: response } = await rp(url('/'), { headers: { 'user-agent': modernUA } })
|
||||
expect(response).toContain('<link rel="modulepreload" crossorigin="use-credentials" href="/_nuxt/modern-app.js" as="script">')
|
||||
expect(response).toContain('<link rel="modulepreload" crossorigin="use-credentials" href="/_nuxt/modern-commons.app.js" as="script">')
|
||||
expect(response).toContain('<link rel="modulepreload" crossorigin="use-credentials" href="/_nuxt/app.modern.js" as="script">')
|
||||
expect(response).toContain('<link rel="modulepreload" crossorigin="use-credentials" href="/_nuxt/commons/app.modern.js" as="script">')
|
||||
})
|
||||
|
||||
test('should contain safari nomodule fix', async () => {
|
||||
@ -62,9 +62,9 @@ describe('modern client mode (SPA)', () => {
|
||||
test('should contain modern http2 pushed resources', async () => {
|
||||
const { headers: { link } } = await rp(url('/'), { headers: { 'user-agent': modernUA } })
|
||||
expect(link).toEqual([
|
||||
'</_nuxt/modern-runtime.js>; rel=modulepreload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/modern-commons.app.js>; rel=modulepreload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/modern-app.js>; rel=modulepreload; crossorigin=use-credentials; as=script'
|
||||
'</_nuxt/runtime.modern.js>; rel=modulepreload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/commons/app.modern.js>; rel=modulepreload; crossorigin=use-credentials; as=script',
|
||||
'</_nuxt/app.modern.js>; rel=modulepreload; crossorigin=use-credentials; as=script'
|
||||
].join(', '))
|
||||
})
|
||||
|
||||
|
@ -35,7 +35,7 @@ function spaTests ({ isHashMode }) {
|
||||
test('/ (include preload and prefetch resources)', async () => {
|
||||
const { head } = await renderRoute('/')
|
||||
expect(head).toMatch('<link rel="preload" href="/_nuxt/runtime.js" as="script">')
|
||||
expect(head).toMatch('<link rel="preload" href="/_nuxt/commons.app.js" as="script">')
|
||||
expect(head).toMatch('<link rel="preload" href="/_nuxt/commons/app.js" as="script">')
|
||||
expect(head).toMatch('<link rel="preload" href="/_nuxt/app.js" as="script">')
|
||||
expect(head).toMatch(`<link rel="prefetch" href="/_nuxt/${wChunk('pages/custom.js')}">`)
|
||||
expect(head).toMatch(`<link rel="prefetch" href="/_nuxt/${wChunk('pages/error-handler-async.js')}">`)
|
||||
|
@ -34,11 +34,6 @@ describe('with-config', () => {
|
||||
expect(html).toContain('<h1>I have custom configurations</h1>')
|
||||
})
|
||||
|
||||
test('/ (asset name for analyze mode)', async () => {
|
||||
const { html } = await nuxt.server.renderRoute('/')
|
||||
expect(html).toContain('<script src="/test/orion/app.js"')
|
||||
})
|
||||
|
||||
test('/ (global styles inlined)', async () => {
|
||||
const window = await nuxt.server.renderAndGetWindow(url('/test/'))
|
||||
const html = window.document.head.innerHTML
|
||||
|
8
test/fixtures/modern/nuxt.config.js
vendored
8
test/fixtures/modern/nuxt.config.js
vendored
@ -2,12 +2,8 @@ export default {
|
||||
modern: true,
|
||||
build: {
|
||||
filenames: {
|
||||
app: ({ isModern }) => {
|
||||
return `${isModern ? 'modern-' : ''}[name].js`
|
||||
},
|
||||
chunk: ({ isModern }) => {
|
||||
return `${isModern ? 'modern-' : ''}[name].js`
|
||||
}
|
||||
app: ({ isModern }) => `[name]${isModern ? '.modern' : ''}.js`,
|
||||
chunk: ({ isModern }) => `[name]${isModern ? '.modern' : ''}.js`
|
||||
}
|
||||
},
|
||||
render: {
|
||||
|
19
test/fixtures/shared-chunk/components/shared-vendor.vue
vendored
Normal file
19
test/fixtures/shared-chunk/components/shared-vendor.vue
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<div>
|
||||
{{ test }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import $ from 'cheerio'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
$('<a>A</a>')
|
||||
return {
|
||||
test: _.startCase('lodash')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
5
test/fixtures/shared-chunk/components/shared.vue
vendored
Normal file
5
test/fixtures/shared-chunk/components/shared.vue
vendored
Normal file
File diff suppressed because one or more lines are too long
3
test/fixtures/shared-chunk/nuxt.config.js
vendored
Normal file
3
test/fixtures/shared-chunk/nuxt.config.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
components: true
|
||||
}
|
6
test/fixtures/shared-chunk/pages/_cat/_id/_sub.vue
vendored
Normal file
6
test/fixtures/shared-chunk/pages/_cat/_id/_sub.vue
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<Shared />
|
||||
<SharedVendor />
|
||||
</div>
|
||||
</template>
|
5
test/fixtures/shared-chunk/pages/index.vue
vendored
Normal file
5
test/fixtures/shared-chunk/pages/index.vue
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<SharedVendor />
|
||||
</div>
|
||||
</template>
|
6
test/fixtures/shared-chunk/pages/product/_id.vue
vendored
Normal file
6
test/fixtures/shared-chunk/pages/product/_id.vue
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<Shared />
|
||||
<SharedVendor />
|
||||
</div>
|
||||
</template>
|
Loading…
Reference in New Issue
Block a user