admin管理员组文章数量:1405564
Webpack configuration is a part of Vue CLI setup (can be checked with vue inspect
). This is a relevant part of it:
entry: {
foo: [
'.../src/foo.js'
],
barWidget: [
'.../src/barWidget.js'
],
},
optimization: {
splitChunks: {
cacheGroups: {
vendors: {
name: 'chunk-vendors',
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: 'initial'
},
mon: {
name: 'chunk-mon',
minChunks: 2,
priority: -20,
chunks: 'initial',
reuseExistingChunk: true
}
}
},
...
And HTML output is:
<script type="text/javascript" src="/assets/js/chunk-vendors.[HASH].js"></script>
<script type="text/javascript" src="/assets/js/foo.[HASH].js"></script>
and
<script type="text/javascript" src="/assets/js/chunk-vendors.[HASH].js"></script>
<script type="text/javascript" src="/assets/js/barWidget.[HASH].js"></script>
There's no problem for foo
to have as many script tags as needed, but barWidget
is widget entry point that is supposed to be loaded at once with no initial chunk dependencies. My intention is to make barWidget
be loaded with a single line of code (hash will likely be disabled for this purpose):
<script type="text/javascript" src="/assets/js/barWidget.js"></script>
But in its current state it fails to load if chunk-vendors
is omitted.
I'd prefer to keep vendors
and mon
chunks as they are because they are splitted in a reasonable way and can be reused on client side between entry points, but I need barWidget
to auto-load a chunk it depends on. A less preferable way would be to disable chunks but for barWidget
only, chunk splitting in other entry points should remain unchanged.
A way to reproduce it is basically a new Vue CLI project with 2 entry points added, or any Webpack project with similarly configured splitting.
Here is the project (listed for pleteness):
package.json
{
"name": "foobar",
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"core-js": "^3.6.5",
"vue": "^3.0.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/piler-sfc": "^3.0.0"
}
}
vue.config.js
module.exports = {
pages: {
foo: {
entry: 'src/foo.js',
template: 'public/foo.html',
filename: 'foo.html'
},
barWidget: {
entry: 'src/barWidget.js',
template: 'public/barWidget.html',
filename: 'barWidget.html'
},
},
};
public/foo.html
public/barWidget.html
<!DOCTYPE html>
<html>
<body>
<div id="app"></div>
</body>
</html>
src/foo.js
import { createApp } from 'vue'
import Foo from './Foo.vue'
createApp(Foo).mount('#app')
Foo.vue
<template>
<HelloWorld msg="Foo"/>
</template>
<script>
import HelloWorld from './ponents/HelloWorld.vue'
export default {
ponents: {
HelloWorld
}
}
</script>
src/barWidget.js
import { createApp } from 'vue'
import BarWidget from './BarWidget.vue'
createApp(BarWidget).mount('#app')
BarWidget.vue
<template>
<HelloWorld msg="Bar widget"/>
</template>
<script>
import HelloWorld from './ponents/HelloWorld.vue'
export default {
ponents: {
HelloWorld
}
}
</script>
Can
barWidget
be forced to automatically loadchunk-vendors.[HASH].js
by means of Webpack, without loading it explicitly in the place wherebarWidget.[HASH].js
is being used?Can
barWidget
entry point be forced to not use other initial chunks (chunk-vendors
, etc) and output self-sufficientbarWidget.js
bundle, without affecting the way splitting works in other entry points?Are there other options for the described scenario?
Webpack configuration is a part of Vue CLI setup (can be checked with vue inspect
). This is a relevant part of it:
entry: {
foo: [
'.../src/foo.js'
],
barWidget: [
'.../src/barWidget.js'
],
},
optimization: {
splitChunks: {
cacheGroups: {
vendors: {
name: 'chunk-vendors',
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: 'initial'
},
mon: {
name: 'chunk-mon',
minChunks: 2,
priority: -20,
chunks: 'initial',
reuseExistingChunk: true
}
}
},
...
And HTML output is:
<script type="text/javascript" src="/assets/js/chunk-vendors.[HASH].js"></script>
<script type="text/javascript" src="/assets/js/foo.[HASH].js"></script>
and
<script type="text/javascript" src="/assets/js/chunk-vendors.[HASH].js"></script>
<script type="text/javascript" src="/assets/js/barWidget.[HASH].js"></script>
There's no problem for foo
to have as many script tags as needed, but barWidget
is widget entry point that is supposed to be loaded at once with no initial chunk dependencies. My intention is to make barWidget
be loaded with a single line of code (hash will likely be disabled for this purpose):
<script type="text/javascript" src="/assets/js/barWidget.js"></script>
But in its current state it fails to load if chunk-vendors
is omitted.
I'd prefer to keep vendors
and mon
chunks as they are because they are splitted in a reasonable way and can be reused on client side between entry points, but I need barWidget
to auto-load a chunk it depends on. A less preferable way would be to disable chunks but for barWidget
only, chunk splitting in other entry points should remain unchanged.
A way to reproduce it is basically a new Vue CLI project with 2 entry points added, or any Webpack project with similarly configured splitting.
Here is the project (listed for pleteness):
package.json
{
"name": "foobar",
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"core-js": "^3.6.5",
"vue": "^3.0.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/piler-sfc": "^3.0.0"
}
}
vue.config.js
module.exports = {
pages: {
foo: {
entry: 'src/foo.js',
template: 'public/foo.html',
filename: 'foo.html'
},
barWidget: {
entry: 'src/barWidget.js',
template: 'public/barWidget.html',
filename: 'barWidget.html'
},
},
};
public/foo.html
public/barWidget.html
<!DOCTYPE html>
<html>
<body>
<div id="app"></div>
</body>
</html>
src/foo.js
import { createApp } from 'vue'
import Foo from './Foo.vue'
createApp(Foo).mount('#app')
Foo.vue
<template>
<HelloWorld msg="Foo"/>
</template>
<script>
import HelloWorld from './ponents/HelloWorld.vue'
export default {
ponents: {
HelloWorld
}
}
</script>
src/barWidget.js
import { createApp } from 'vue'
import BarWidget from './BarWidget.vue'
createApp(BarWidget).mount('#app')
BarWidget.vue
<template>
<HelloWorld msg="Bar widget"/>
</template>
<script>
import HelloWorld from './ponents/HelloWorld.vue'
export default {
ponents: {
HelloWorld
}
}
</script>
Can
barWidget
be forced to automatically loadchunk-vendors.[HASH].js
by means of Webpack, without loading it explicitly in the place wherebarWidget.[HASH].js
is being used?Can
barWidget
entry point be forced to not use other initial chunks (chunk-vendors
, etc) and output self-sufficientbarWidget.js
bundle, without affecting the way splitting works in other entry points?Are there other options for the described scenario?
-
If
barWidget
depends onnode_modules
there's obviously no way considering avendor
cache group defined. Generally it's hard to say anything without minimal reproducible test case – Andrey Commented Apr 6, 2021 at 19:19 - @Andrey Yes, the reason vendor chunk appears is that node_modules is being used, this would be true for virtually any app. I believe the thing that the thing that the question describes is natural to Webpack and can be reproduced with any setup that has initial chunks. But I'll try to add an example that shows this. – Estus Flask Commented Apr 7, 2021 at 14:19
-
For the
barWidget
entry, ifbarWidget.js
imports anything fromnode_modules
, then vendor chunk will be created. Or if some other code is including something fromnode_modules
(i.e. something from webpack config). It's likely that "vendor" chunk won't be created if nothing needs it for the entry, but it looks like that's not the case, so you need to find why code fromnode_modules
is needed for thebarWidget
entry – Andrey Commented Apr 7, 2021 at 17:46 - maybe specifying a different chunk name on the barWidget imports with the ments annotations would help. see webpack.js/api/module-methods/#magic-ments – Tiago Coelho Commented Apr 8, 2021 at 8:27
-
@Andrey Yes, it imports something from node_modules, this is the case for >99% modular web projects. In this case it's Vue project and it imports at least
vue
itself. To make it clear, the reason why vendor chunk is produced is obvious (same for other possible initial chunks), the question is how to make it unnecessary to explicitly load chunk-vendors.js with<script>
or else where a specific bundle is being used. I provided a project for pleteness, it's currently based on Vue CLI setup with described Webpack config under the hood. – Estus Flask Commented Apr 8, 2021 at 11:20
2 Answers
Reset to default 3I think that what you want is what is described in this webpack issue reply
the reply uses a function to exclude the dependencies of a specific entrypoint from being included in a chunk:
optimization: {
splitChunks: {
cacheGroups: {
vendors: {
// ... your current config, just change the chunks property
// Exclude pre-main dependencies going into vendors, as doing so
// will result in webpack only loading pre-main once vendors loaded.
// But pre-main is the one loading vendors.
// Currently undocument feature: https://github./webpack/webpack/pull/6791
chunks: chunk => chunk.name !== "barWidget"
}
}
}
},
to do this with vue should be just a matter of changing the webpack config in the vue.config.js file like this:
module.exports = {
configureWebpack: config => {
config.optimization.splitChunks.cacheGroups.vendors.chunks =
chunk => chunk.name !== "barWidget";
}
}
I haven't tried this but I think it should work as is or with some minimal tweaks
You can use a function to filter the chunks. See this Webpack issue
vue.config.js
module.exports = {
pages: {
foo: {
entry: 'src/foo.js',
template: 'public/foo.html',
filename: 'foo.html'
},
barWidget: {
entry: 'src/barWidget.js',
template: 'public/barWidget.html',
filename: 'barWidget.html',
chunks: ['barWidget']
},
},
chainWebpack: config => {
if (process.env.NODE_ENV !== 'test') {
config.optimization.splitChunks({
cacheGroups: {
defaultVendors: {
name: `chunk-vendors`,
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: chunk => chunk.name !== "barWidget"
},
mon: {
name: `chunk-mon`,
minChunks: 2,
priority: -20,
chunks: 'initial',
reuseExistingChunk: true
}
}
})
}
}
}
Note the pages.barWidget.chunks
- it is needed because otherwise HtmlWebpackPlugin includes vendors chunk into barWidget.html
even it is not needed at all...
Result:
本文标签: javascriptAutoload a chunk in entry pointStack Overflow
版权声明:本文标题:javascript - Auto-load a chunk in entry point - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744342390a2601554.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论