act*_*mel 5 chunks webpack splitchunksplugin webpack-splitchunks
我有一个问题,了解Webpack splitChunks插件的行为.我正在研究的是将现有站点上的旧脚本重写为组件并使用Webpack进行捆绑.捆绑只是JS,大多数是在身体的末端加载.但是一个小脚本需要位于页面的标题中,因为它还会在标题和正文中创建很少的全局方法,主要用作内联脚本.由于它用于GA跟踪,它不会改变,事件必须尽快发送.
下面的配置工作适合我,但问题是,为什么它的工作原理只是这样?
确切的问题是在下面的代码中的注释,但我也把它放在这里:我不明白为什么有必要也包括!isUsedInAppHeader在common块的条件.如果没有!isUsedInAppHeader条件,则不会common.header创建块.然后,当我尝试通过为common.header块添加更高优先级来修复它时,它会导致脚本中的脚本异步初始化app.header.js.
异步行为是我根本不理解的,因为它从未发生过app.js.
实际上,我有另一个问题.是否可以导出一个同时立即初始化的公共块?或者你会提出另一个解决方案吗?标题中的脚本无法移动,也必须同步初始化,因为它的主要作用是为GA跟踪创建全局方法,这些方法必须立即用于以下代码中.
谢谢!
Webpack配置:
...
gulp.task('webpack', function(callback) {
var settings = {
...
entry: {
'app.header': './js/app.header.js',
'app': './js/app.js',
... // page specific files etc.
},
...
optimization: {
splitChunks: {
cacheGroups: {
// Node modules used in app.js
vendorsApp: {
test(module, chunks) {
let isInAppEntryPoint = chunks.map(chunk => chunk.name).includes('app');
let isNodeModule = /\/node_modules\//.test(upath.normalize(module.resource));
return isInAppEntryPoint && isNodeModule;
},
name: 'vendors',
chunks: 'all',
enforce: true,
},
// Modules shared between app.header and any other file
commonHeader: {
test(module, chunks) {
let isUsedInHeader = chunks.map(chunk => chunk.name).includes('app.header');
return isUsedInHeader;
},
name: 'common.header',
chunks: 'initial',
minChunks: 2,
minSize: 0,
// priority: 2 // (*)
},
// Modules shared between app.js and any other file
common: {
test(module, chunks) {
// QUESTION I don't understand why is it necessary to also include !isUsedInAppHeader into the condition.
// Without the !isUsedInAppHeader in the condition no common.header chunk is created.
// Then, when I try to fix it via adding priority (*) for common.header, it results
// in asynchronous initialisation of the scripts in the app.header.js
let isUsedInApp = chunks.map(chunk => chunk.name).includes('app');
let isUsedInAppHeader = chunks.map(chunk => chunk.name).includes('app.header');
return isUsedInApp && !isUsedInAppHeader;
},
name: 'common',
chunks: 'initial',
minChunks: 2,
},
}
}
},
};
var bundle = webpack(settings, function(error, stats) {
...
});
return bundle;
});
Run Code Online (Sandbox Code Playgroud)
这是在页面中加载脚本的方式:
<!DOCTYPE html>
<html lang="en">
<head>
...
<script src="/js/common.header.js"></script>
<script src="/js/app.header.js"></script>
<script>
... // Immediate calling of some of the the global methods defined in app.header
</script>
</head>
<body>
...
<script src="/js/vendors.js"></script>
<script src="/js/common.js"></script>
<script src="/js/app.js"></script>
<script src="..."></script> // page specific files etc.
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
正如SplitChunks 插件所说:
默认情况下,它仅影响按需块,因为更改初始块会影响 HTML 文件运行项目时应包含的脚本标记。
为了使事情更符合您的预期,您需要使用默认chunks: async设置,这样初始块将保留在您的入口点中。我相信您的设置中的另一个选项是用于chunks: all公共。如果您想这样做,请参阅本指南。
但我不推荐这种策略。由于大多数 cdns 支持 webpack4 和 HTML2,因此最好让 webpack 自动分割块,以及您通过导入语法定义的异步、延迟加载部分。。
因此,您有 1 个入口点,以及您明确指定的代码分割点。如果您不想在 webpack 构建中支持 es6 模块导入,可以使用require.ensure语法。如果您的代码库不强迫您使用它,我不推荐它。
通过魔术注释预加载是该语法的另一个好处import.then()。/* webpackHint */您可以在调用中添加注释前缀import以指示加载行为。
| 归档时间: |
|
| 查看次数: |
420 次 |
| 最近记录: |