我们想从Webpack中获得两个输出-整个应用程序具有所有依赖项,而一个单独的页面只有一个依赖项(主应用程序不共享)。
执行此操作的方法似乎是利用Webpack配置的entry
属性。但是,这还不够,因为我们还使用HtmlWebpackPlugin来输出HTML文件以及Webpack编译动态添加的build.js
(以及编译的LESS等)。根据HtmlWebpackPlugin文档:
如果您有多个Webpack入口点,则将它们全部包括在内 在生成的HTML中包含脚本标签。
这对我们不起作用,因此我需要利用他们的filterChunks
选项。这个GitHub issue response最简洁地说:
module.exports = {
entry: {
'page1': './apps/page1/scripts/main.js',
'page2': './apps/page2/src/main.js'
},
output: {
path: __dirname,
filename: "apps/[name]/build/bundle.js"
},
plugins: [
new HtmlWebpackPlugin({
inject: false,
chunks: ['page1'],
filename: 'apps/page1/build/index.html'
}),
new HtmlWebpackPlugin({
inject: false,
chunks: ['page2'],
filename: 'apps/page2/build/index.html'
})
]
};
(在HtmlWebpackPlugin文档中,这在“过滤块”部分下)
所以,我像这样修改了我们的代码:
module.exports = {
entry: {
app: './public/js/ide.js',
resetPassword: './public/js/reset_password.js'
},
output: {
path: path.resolve(__dirname, '../build'),
filename: '[name].js',
publicPath: '/'
},
...
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'public/html/ide.html',
inject: true,
chunks: ['app']
}),
new HtmlWebpackPlugin({
filename: 'reset_password.html',
template: 'public/html/reset_password.html',
inject: true,
chunks: ['resetPassword']
}),
],
}
现在,当我重建项目(现在仅尝试使用WebpackDevServer)并导航到/index.html
时,我可以在网络选项卡中看到庞大的捆绑文件,其中index.html
的内容(基于ide.html
模板),以及对各种外部资源的请求。但是,不会运行任何实际的JavaScript(例如,ide.js
中的console.log)。显示文件中的所有HTML。
对于reset_password.html
,将显示所有HTML,并且显示reset_password.js
文件,但运行中的JavaScript均不显示。
如何确保entry
文件中的JavaScript运行?
编辑:我已经ide.js
工作了,因为我没有意识到以下内容是“大块的”:
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'all'
}
}
}
},
因此,我将vendor
添加到了index.html
HtmlWebpackPlugin chunks
属性中。现在,它看起来像这样:
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'public/html/ide.html',
inject: true,
chunks: ['app', 'vendor']
}),
reset_password
在node_modules文件夹中不需要任何内容,这也不能解释为什么ide.js
中根本不运行JavaScript,所以我还是很困惑。此外,reset_password
仍然无法正常工作。
EDIT2 :加载reset_password.js
时,通过看似附加的reset_password.html
文件,可以看到这一行
eval("\n\nconsole.log('DRAGONHELLO');//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9wdWJsaWMvanMvcmVzZXRfcGFzc3dvcmQuanM/ZjY5ZSJdLCJuYW1lcyI6WyJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiOztBQUNBQSxRQUFRQyxHQUFSLENBQVksYUFBWiIsImZpbGUiOiIuL3B1YmxpYy9qcy9yZXNldF9wYXNzd29yZC5qcy5qcyIsInNvdXJjZXNDb250ZW50IjpbIlxuY29uc29sZS5sb2coJ0RSQUdPTkhFTExPJylcbiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./public/js/reset_password.js\n");
因此,显然我的console.log('DRAGONHELLO')
是“可见的”,但我不知道为什么它没有运行。
EDIT3 :将vendor
的{{1}}添加到chunks
会导致JavaScript运行,但是我不知道为什么,这是不理想的,因为整个练习的重点是拥有两个不同的捆绑包,一个捆绑包非常小,不需要我们所有的reset_password.html
。
EDIT4 :我使用node_modules
运行了Webpack,可以看到我没有弄错“块名称”:
profile:true
EDIT5 :我都尝试过
js/app.3d18b43294ebd54ed083.js 1.34 MiB 0 [emitted] [big] app
js/resetPassword.198485be2b163cc258ed.js 1.02 KiB 1 [emitted] resetPassword
js/2.e7f92193ea3c611a0b36.js 2.23 MiB 2 [emitted] [big] vendor
js/app.3d18b43294ebd54ed083.js.map 2.71 MiB 0 [emitted] app
js/resetPassword.198485be2b163cc258ed.js.map 4.57 KiB 1 [emitted] resetPassword
js/2.e7f92193ea3c611a0b36.js.map 7.12 MiB 2 [emitted] vendor
和
module.exports = {
//...
optimization: {
runtimeChunk: {
name: entrypoint => `runtime~${entrypoint.name}`
}
}
};
基于PlayMa256的评论和webpack docs on runtimeChunk。两者均未导致JavaScript执行。
答案 0 :(得分:3)
设置时:
module.exports = {
//...
optimization: {
runtimeChunk: true
}
};
它生成一个运行时块。什么是运行时?运行时是webpack用来加载其他文件的所有代码所在的位置。这是运行build时webpack的核心。
由于您有2个单独的捆绑文件:resetPassword
和app
。
好的,您拥有了所需的所有文件。您可能同时也需要供应商,因为您的供应商包含了node_modules中的所有内容。所以基本上您将拥有:
html 1:app
,vendor
,runtimeChunk
。
html 2:reset_password
,vendor
,runtimeChunk
。
这样做,您的应用程序应该运行。
答案 1 :(得分:2)
这是一个多方面的问题。
首先,there is a bug in Html-Webpack-Plugin使其与Webpack4和多个入口点不兼容。必须至少将其升级到v4.0.0-alpha.2才能正常工作。
第二,在新版本中,您无需使用optimization.splitChunks.cacheGroups
来手动分离出node_modules。进行optimization.splitChunks.chunks = 'all'
足以使给定的入口点仅进入其vendors-app-{{chunk_name}}
个节点模块的import
块中。
所以,如果您这样做
optimization: {
splitChunks: {
chunks: 'all'
},
},
与
结合plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'public/html/ide.html',
inject: true,
chunks: ['app']
}),
new HtmlWebpackPlugin({
filename: 'reset_password.html',
template: 'public/html/reset_password.html',
inject: true,
chunks: ['resetPassword']
}),
]
与
结合entry: {
app: './public/js/ide.js',
resetPassword: './public/js/reset_password.js'
},
然后,您的Webpack输出将具有
除非您的imports
文件中没有resetPassword.js
,否则它将看起来像
https://github.com/jantimon/html-webpack-plugin/issues/1053上的更多信息,图像和对话
请注意,对于最新版本,chunksSortMode:
不再是HtmlWebpackPlugin对象上的有效选项,它显然是在webpack4中默认完成的。