解决webpack多页面内存溢出的方法示例

作者:模板散步时间:2026-10-23 11:44:50浏览:142

本文针对Vue CLI3多页面项目编译慢及内存溢出问题,提供三种解决方案:通过修改cmd或package.json增加Node最大内存;按需配置编译文件减少编译量;利用webpack-dev-server的before钩子实现访问即编译。此外还介绍了升级html-webpack-plugin及使用HappyPack插件优化编译速度的技巧。

Vue CLI3多页面内存溢出问题背景

由于项目基于vue-cli3开发,本文仅讨论该环境下的解决方案。

多页面开发初期文件较少,编译速度尚可;但随着项目规模扩大,webpack编译速度显著下降,且频繁出现内存溢出。

以下介绍几种尝试过的方法,旨在提升编译速度。

增加Node运行内存方案

增加Node运行内存。

Node通过JavaScript使用内存时,64位系统下约为1.4 GB,32位系统下约为0.7 GB。无论电脑实际运行内存多大,Node编译时可用内存上限不变,易导致内存溢出。可通过增加Node运行内存解决,具体有两种方法。

修改cmd文件。

在node_modules/.bin/vue-cli-server.cmd中复制以下代码:


@IF EXIST "%~dp0\node.exe" (
 "%~dp0\node.exe" --max_old_space_size=4096 "%~dp0\..\@vue\cli-service\bin\vue-cli-service.js" %*
) ELSE (
 @SETLOCAL
 @SET PATHEXT=%PATHEXT:;.JS;=;%
 node --max_old_space_size=4096 "%~dp0\..\@vue\cli-service\bin\vue-cli-service.js" %*
)

修改package.json。

调整启动Node服务的命令:


node --max_old_space_size=4096 node_modules/@vue/cli-service/bin/vue-cli-service.js serve

两者本质相同,均通过强行增加Node运行内存解决溢出问题。但这并非根本解决之道,编译速度依然较慢,完成编译仍需等待较长时间。

按需配置编译文件

配置需要编译的文件。

按需配置编译文件。内存溢出的本质是需编译文件过多,通过减少编译页面数量可解决此问题。

所有页面配置位于page.config.js。若需对特定页面配置,需过滤所有页面以获取需编译的页面,编译文件写法如下:


const path = require('path');
const fs = require('fs');
const pages = require('../pages.config');

const params = JSON.parse(process.env.npm_config_argv).original;
const buildPath = params[params.length - 1].match(/[a-zA-Z0-9]+/)[0] || '';

let buildConfig = {
 pages: [],
};


if (!/(test|online|serve)/gi.test(buildPath)) {
 const configJsPath = path.resolve(__dirname, `${buildPath}.js`);

 // 如果该路径存在
 if (fs.existsSync(configJsPath)) {
  // eslint-disable-next-line import/no-dynamic-require
  buildConfig = require(configJsPath);
 } else if (pages[buildPath]) {
  buildConfig.pages = buildPath.split(',');
 } else {
  throw new Error('该路径不存在');
 }
} else {
 buildConfig = require('./default');
}
module.exports = buildConfig.pages;

通常产品由多条业务线构成,每次可能仅修改某一条业务线。可单独创建该业务线的配置文件,写入需编译的页面名称,从而单独编译该页面;或通过传入字符串指定编译页面。

利用webpack-dev-server钩子单独编译

使用webpack-dev-server钩子进行单独编译。

Webpack热更新基于webpack-dev-server服务。若存在钩子,访问某页面时仅编译该页面代码。幸运的是,devServer中存在before钩子,可在vue.config.js中修改:


const compiledPages = [];
before(app) {
   app.get('*.html', (req, res, next) => {
    const result = req.url.match(/[^/]+?(?=\.)/);
    const pageName = result && result[0];
    const pagesName = Object.keys(multiPageConfig);

    if (pageName) {
     if (pagesName.includes(pageName)) {
      if (!compiledPages.includes(pageName)) {
       const page = multiPageConfig[pageName];
       fs.writeFileSync(`dev-entries/${pageName}.js`, `import '../${page.tempEntry}'; // eslint-disable-line`);
       compiledPages.push(pageName);
      }
     } else {
      // 没这个入口
      res.writeHead(200, { 'content-type': 'text/html; charset=utf-8' });
      res.end('<p style="font-size: 50px;">不存在的入口</p>');
     }
    }
    next();
   });
  },

multPageConfig为多页面配置,开发环境中做如下修改:


{
  pageName: {
    entry: entryPath,
    chunks: [array]
  }
}
const fs = require('fs');
const util = require('util');

const outputFile = util.promisify(fs.writeFile);
async function main() {
 const tasks = [];
 if (!fs.lstatSync('dev-entries').isDirectory()) {
  fs.mkdirSync('dev-entries');
 }
 Object.keys(pages).forEach((key) => {
  const entry = `dev-entries/${key}.js`;
  pages[key].tempEntry = pages[key].entry; // 暂存真正的入口文件地址
  pages[key].entry = entry;
  tasks.push(outputFile(entry, ''));
 });
 await Promise.all(tasks);
}

if (process.env.NODE_ENV === 'development') {
 main();
}

module.exports = pages;

上述文件中,首先需更改多页面配置,创建一个包含所有页面js文件的目录。需注意这些文件均为空文件,然后在vue.config.js中配置多页面:


pages: multiPageConfig, // 配置多页应用

因所有页面js已置空,编译速度极快。访问页面时,webpack拦截访问页面(即需更改的页面),此时手动往dev-entries目录下写入需编译的文件,实现访问某页面即编译该页面代码。

升级html-webpack-plugin版本

升级html-webpack-plugin版本。

多页面内存溢出是因为编译时实际是一次更改,却编译了多个文件,这是html-webpack-plugin的问题。生成每个页面需调用new htmlWebpackPlugin(),多页面时内存不足。因此修改该webpack插件版本至4.0.0-beta.8,并在vue.config.js中添加配置,可避免内存溢出。


const htmlPlugins = [];
Object.keys(multiPageConfig).forEach((key) => {
  htmlPlugins.push(multiPageConfig[key])
})
configureWebpack: {
  plugins: [
   ...htmlPlugins,
  ],
}

其他编译优化技巧

其他加快编译的技巧。

Webpack插件便捷,网上有happypack等类似插件。因运行在Node.js之上的Webpack是单线程模型,需依次处理任务,无法并行。

需Webpack同时处理多个任务以发挥多核CPU威力,HappyPack可将任务分解给多个子进程并发执行,子进程处理完将结果发回主进程。因电脑配置原因,安装后提升不明显,具体用法可参考文章webpack优化之HappyPack 实战。其他细节如部分包需加入编译,但调试时仅需在chrome上进行,开发环境无需加入编译;多处使用的代码单独打包等,此处不再赘述,建议多尝试。

上述解决多页面内存溢出的方法各有优劣,读者可根据项目自行选择,有时需组合使用多种方法,以效果为准。

解决此问题同时研究了webpack,其配置博大精深,难怪市面有流传webpack配置工程师。推广一波自己的github,近期正抓紧学习,会持续更新文章,希望大家多多关注。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

作者最新文章