3.6.3
System:
OS: macOS 10.14.4
CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
Binaries:
Node: 10.15.3 - ~/.nvm/versions/node/v10.15.3/bin/node
Yarn: 1.15.2 - ~/.nvm/versions/node/v10.15.3/bin/yarn
npm: 6.9.0 - ~/.nvm/versions/node/v10.15.3/bin/npm
Browsers:
Chrome: 73.0.3683.103
Firefox: Not Found
Safari: 12.1
npmPackages:
@vue/babel-helper-vue-jsx-merge-props: 1.0.0-beta.3
@vue/babel-plugin-transform-vue-jsx: 1.0.0-beta.3
@vue/babel-preset-app: 3.5.5
@vue/babel-preset-jsx: 1.0.0-beta.3
@vue/babel-sugar-functional-vue: 1.0.0-beta.3
@vue/babel-sugar-inject-h: 1.0.0-beta.3
@vue/babel-sugar-v-model: 1.0.0-beta.3
@vue/babel-sugar-v-on: 1.0.0-beta.3
@vue/cli-overlay: 3.5.1
@vue/cli-plugin-babel: ^3.2.0 => 3.5.5
@vue/cli-plugin-eslint: ^3.2.0 => 3.5.1
@vue/cli-service: ^3.2.0 => 3.5.3
@vue/cli-shared-utils: 3.5.1
@vue/component-compiler-utils: 2.6.0
@vue/eslint-config-standard: ^4.0.0 => 4.0.0
@vue/preload-webpack-plugin: 1.1.0
@vue/web-component-wrapper: 1.2.0
babel-helper-vue-jsx-merge-props: 2.0.3
eslint-plugin-vue: ^5.0.0-0 => 5.1.0
vue: ^2.5.17 => 2.5.21
vue-eslint-parser: 4.0.3
vue-hot-reload-api: 2.3.3
vue-loader: 15.7.0
vue-router: ^3.0.1 => 3.0.2
vue-style-loader: 4.1.2
vue-template-compiler: ^2.5.17 => 2.5.21
vue-template-es2015-compiler: 1.9.1
vuex: ^3.0.1 => 3.0.1
npmGlobalPackages:
@vue/cli: 3.6.2
把一个单页面项目修改为多页面,即复制入口文件和模板文件,然后在vue.config.js中的pages字段添加模板和入口。根据项目大小的不同,会存在添加7个页面后,修改文件重新编译的时候node内存溢出,即webpack进程运行的内存超过node默认分配的内存大小导致进程结束。在单页面的时候也存在性能问题,特别是修改入口文件的时候,编译速度非常慢。
<--- Last few GCs --->
io[86760:0x10284b000] 331522 ms: Mark-sweep 1403.5 (1429.1) -> 1403.4 (1430.6) MB, 392.4 / 0.0 ms ( 16.8 ms in 16 steps since start of marking,
biggest step 7.8 ms, walltime since start of marking 413 ms) (average mu = 0.146, current mu = 0.014) allocat[86760:0x10284b000] 331955 ms: Mark
-sweep 1404.5 (1430.6) -> 1404.3 (1431.1) MB, 412.1 / 0.0 ms ( 17.9 ms in 17 steps since start of marking, biggest step 6.2 ms, walltime since st
art of marking 433 ms) (average mu = 0.083, current mu = 0.009) allocat
<--- JS stacktrace --->
==== JS stack trace =========================================
0: ExitFrame [pc: 0x28fbee7cfc7d]
1: StubFrame [pc: 0x28fbee7d0fea]
2: StubFrame [pc: 0x28fbee7c69e2]
Security context: 0x02cce911d9d1 <JSObject>
经过我这边测试,导致以上问题的主要原因是在开发的是后没有使用webpack的optimization.splitChunks配置来分包,每个入口都是完整编译所有文件,不能共享node_modules下的编译文件,所以导致内存不足。单页面的时候,修改入口文件也会重新编译node_modules下面的文件,所以速度较慢。
在开发模式下添加webpack的optimization.splitChunks配置
请给出重现仓库地址。
Windows、Mac、Linux都可复现问题
master分支npm run dev启动项目打开活动监视器,找到 webpack 的 node 进程,记录下 node 进程内存使用值

找到src/main.js或者其他的文件,编辑然后保存,目的是触发 webpack 编译,记录下编译时长(friendly-errors-webpack-plugin 会打印出时间),如果连续快速保存文件多次,webpack 会一直编译,同时 node 进程内存会快速增长,就有可能内存不足导致进程结束

切换到splitChunks分支,并运行npm run dev启动项目
在活动监视器中可以看到启动项目后内存占用比前面要低很多,并且连续保存文件,内存上升幅度较小,并且编译时间低了很多
启动项目后

多次修改文件后内存使用情况

splitChunks 分支添加了optimization.splitChunks配置
module.exports = {
// ...其他的配置
chainWebpack: config => {
config.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
}
}
})
}
}
使用了splitChunks,使得多个入口共用一份chunk-vendors和chunk-common,这样就不会每个入口都编译一次node_modules下面的文件和其他公共的文件,并且由于提取了公共chunk,所以文件保存触发webpack重新编译时,只要提取的chunk没改变就不会重新编译提取出来的chunk,重新编译的速度也会明显上升
非常感谢如此详细的复现和分析。
这个确实可以优化。我看了一下提交记录,当初默认在 dev 环境下不开启 splitChunks 应该是从 webpack 2 时期迁移过来的旧的配置逻辑,并且以前 splitChunks 曾经引发过 hot module replacement 相关的 bug,所以出于维护方便的考虑就一直留着这个逻辑了。
现在看来相关 bug 应该都修复了,可以考虑默认开启。不过因为这样一来目录结构变动较大,应该不会在 v3 中加入,会放到 v4 中实现(首个 beta 版预计在未来两周内发布)。
速度很快,点赞👍
diy一个webpack4多页面遇到过类似的状况,后来发现是html-webpack-plugin的问题,替换成beta版本就明显速度提升了,也未从发现内存泄露
👍👍👍
@wzc0x0 能贴出具体的代码吗,现在升级了版本,但是在vue.config.js配置中出现了BASE_URL没找到的问题
Most helpful comment
非常感谢如此详细的复现和分析。
这个确实可以优化。我看了一下提交记录,当初默认在 dev 环境下不开启 splitChunks 应该是从 webpack 2 时期迁移过来的旧的配置逻辑,并且以前 splitChunks 曾经引发过 hot module replacement 相关的 bug,所以出于维护方便的考虑就一直留着这个逻辑了。
现在看来相关 bug 应该都修复了,可以考虑默认开启。不过因为这样一来目录结构变动较大,应该不会在 v3 中加入,会放到 v4 中实现(首个 beta 版预计在未来两周内发布)。