Est*_*ask 8 javascript webpack vue.js vue-cli webpack-splitchunks
Webpack 配置是 Vue CLI 设置的一部分(可以使用 进行检查vue inspect)。这是其中的一个相关部分:
entry: {
foo: [
'.../src/foo.js'
],
barWidget: [
'.../src/barWidget.js'
],
},
optimization: {
splitChunks: {
cacheGroups: {
vendors: {
name: 'chunk-vendors',
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: 'initial'
},
common: {
name: 'chunk-common',
minChunks: 2,
priority: -20,
chunks: 'initial',
reuseExistingChunk: true
}
}
},
...
Run Code Online (Sandbox Code Playgroud)
而 HTML 输出是:
<script type="text/javascript" src="/assets/js/chunk-vendors.[HASH].js"></script>
<script type="text/javascript" src="/assets/js/foo.[HASH].js"></script>
Run Code Online (Sandbox Code Playgroud)
和
<script type="text/javascript" src="/assets/js/chunk-vendors.[HASH].js"></script>
<script type="text/javascript" src="/assets/js/barWidget.[HASH].js"></script>
Run Code Online (Sandbox Code Playgroud)
foo根据需要拥有尽可能多的脚本标签没有问题,但barWidget小部件入口点应该立即加载,没有初始块依赖性。我的目的是barWidget加载一行代码(为此可能会禁用散列):
<script type="text/javascript" src="/assets/js/barWidget.js"></script>
Run Code Online (Sandbox Code Playgroud)
但在当前状态下,如果chunk-vendors省略则无法加载。
我更喜欢保持vendors和common块原样,因为它们以合理的方式拆分,并且可以在客户端的入口点之间重用,但我需要barWidget自动加载它所依赖的块。一种不太可取的方法是禁用块,但barWidget仅此而已,其他入口点中的块拆分应保持不变。
一种重现它的方法基本上是一个添加了 2 个入口点的新 Vue CLI 项目,或者任何具有类似配置拆分的 Webpack 项目。
这是项目(为了完整性而列出):
包.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/compiler-sfc": "^3.0.0"
}
}
Run Code Online (Sandbox Code Playgroud)
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'
},
},
};
Run Code Online (Sandbox Code Playgroud)
公共/foo.html
公共/barWidget.html
<!DOCTYPE html>
<html>
<body>
<div id="app"></div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
源代码/foo.js
import { createApp } from 'vue'
import Foo from './Foo.vue'
createApp(Foo).mount('#app')
Run Code Online (Sandbox Code Playgroud)
Foo.vue
<template>
<HelloWorld msg="Foo"/>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
components: {
HelloWorld
}
}
</script>
Run Code Online (Sandbox Code Playgroud)
src/barWidget.js
import { createApp } from 'vue'
import BarWidget from './BarWidget.vue'
createApp(BarWidget).mount('#app')
Run Code Online (Sandbox Code Playgroud)
小工具.vue
<template>
<HelloWorld msg="Bar widget"/>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
components: {
HelloWorld
}
}
</script>
Run Code Online (Sandbox Code Playgroud)
可以通过WebpackbarWidget强制自动加载chunk-vendors.[HASH].js,不用在barWidget.[HASH].js正在使用的地方显式加载吗?
是否可以barWidget强制入口点不使用其他初始块(chunk-vendors等)并输出自给自足的barWidget.js包,而不影响其他入口点中拆分的工作方式?
所描述的场景还有其他选择吗?
我认为你想要的是这个webpack 问题回复中描述的内容
回复使用一个函数来排除特定入口点的依赖项,使其不包含在块中:
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.com/webpack/webpack/pull/6791
chunks: chunk => chunk.name !== "barWidget"
}
}
}
},
Run Code Online (Sandbox Code Playgroud)
要使用 vue 执行此操作,只需更改 vue.config.js 文件中的 webpack 配置,如下所示:
module.exports = {
configureWebpack: config => {
config.optimization.splitChunks.cacheGroups.vendors.chunks =
chunk => chunk.name !== "barWidget";
}
}
Run Code Online (Sandbox Code Playgroud)
我还没有尝试过,但我认为它应该按原样工作或进行一些最小的调整