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

因为自己的项目是基于vue-cli3进行开发,所以这里只讨论这种情况下的解决办法

在进行多页面开发的时候,项目刚开始阶段,因为文件较少,所以代码编译速度还行,但是随着项目逐渐增大,webpack编译的速度越来越慢,并且经常出现内存溢出的情况。

下面就是几种尝试的方法,加快编译的速度

增加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;

大多数情况下,一个产品都是由多个业务线构成,每次可能需要更改的就是某一条业务线,就完全可以单独创建一个这条业务线的配置文件,然后再这个文件写入你需要编译的页面名称,就可以单独编译这个页面,或者说在调用通过传入的字符串来编译那些页面

使用webbpack-dev-serve钩子进行单独编译

在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的问题。因为没生成一个页面,就需要调用一下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需要处理的事情需要一件一件的做,不能多件事一起做。

我们需要Webpack能同一时间处理多个任务,发挥多核CPU电脑的威力,HappyPack就能让Webpack 做到这点,它把任务分解给多个子进程去并发的执行,子进程处理完后再把结果发送给主进程。可能是我电脑太烂了,装上没啥太大的提升,具体使用方法可以参照这篇文章webpack优化之HappyPack 实战。还有一些细节的地方比如说有些包需要加入编译,但是一般我们在调试的时候只需要在chrome上进行调试,开发环境就不用加入编译,多处使用的代码单独打包,这些也就不说了,大家多多尝试

这几种解决多页面内存溢出的方法各有优缺点,读者可根据自己的项目自行决定使用哪种方法,可能有时还需要多种方式组合使用,就看看那个好使好用了。

解决这个问题顺便研究了一下webpack,配置果然博大精深,难怪市面有流传webpack配置工程师。推销一波自己的github最近在抓紧学习,会持续更新文章,希望大家多多关注。

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

(0)

相关推荐

  • webpack多页面开发实践

    写在前面 webpack是一款模块加载器兼打包工具,能把js,css,页面,图片,视频等各种资源,进行模块化处理.而现在网上流传很多单页面的webpack模型,那多页面呢?比较少,现在我提供一个多页面的前端模型.希望大家适合使用. 在最开始接触webpack的时候,我都觉得webpack只适用于单页面应用,比如webpack+react,webpack+vue.我自己在使用webpack+vue构建项目及开发的过程中感受到了webpack的强大和方便.基于实际项目需求,我在想,多页面站点是否也能

  • webpack打包多页面的方法

    前言 一开始接触webpack是因为使用Vue的关系,因为Vue的脚手架就是使用webpack构建的.刚开始的时候觉得webpack就是为了打包单页面而生的,后来想想,这么好的打包方案,只在单页面上使用是否太浪费资源了呢?如果能在传统多页面上使用webpack,开始效率是否会事半功倍呢?好在众多优秀的前端开发者已经写了许多demo和文章供人学习.我也写了一个小项目,希望对大家学习webpack有帮助. 好吧其实上面说的都是废话,接下来附上项目地址和干货,配合食用更佳. webpack-multi

  • 浅谈如何使用webpack构建多页面应用

    前言 之前使用 vue2.x + webpack3.x 撸了一个 vue 单页脚手架 vue 版 spa 脚手架 有兴趣的同学可以看下,内附详细注释,适合刚学习 webpack 的童鞋. react 版 spa 脚手架 但在一些场景下,单页应用显然无法满足我们的需求,于是便有了 mulXc-cli 好了,废话不多说,进入正题!!!! 文件结构  ├── build 构建服务和webpack配置 ├──── build.js 构建全量压缩包 (打包项目) ├──── setting.js 多页面入

  • 详解webpack 多页面/入口支持&公共组件单独打包

    webpack系列目录 webpack 系列 二:webpack 介绍&安装 webpack 系列 三:webpack 如何集成第三方js库 webpack 系列 四:webpack 多页面支持 & 公共组件单独打包 webpack 系列 五:webpack Loaders 模块加载器 webpack 系列 六:前端项目模板-webpack+gulp实现自动构建部署 基于webpack搭建纯静态页面型前端工程解决方案模板, 最终形态源码见github: https://github.com

  • 详解webpack+ES6+Sass搭建多页面应用

    webpack同之前的gulp相比,gulp属于非模块化打包工具,webpack属于模块化打包工具,两者的优劣这里不做过多分析(可自行百度). 目的:是为了分享一下使用过程中,用到的插件.loader.遇到的各种问题以及解决办法,最后会附上最终代码. 在这个项目中,用 webpack打包css.scss.js.图片文件.jquery.第三方插件.字体图标,编译es6.压缩html.压缩js.压缩css ,基本涵盖了常用的东西. 代码结构如下 下面单独说几个难点 1.打包多页面,使用到的插件是ht

  • 详解webpack编译多页面vue项目的配置问题

    本文主要介绍了webpack编译多页面vue项目的配置问题,分享给大家,具体如下: 一般情况下,构建一个vue项目的步骤为: 1,安装nodejs环境 2,安装vue-cli cnpm install vue-cli -g 3,构建vue项目 vue init webpack-simple vue-cli-multipage-demo 4, 安装项目依赖包 cnpm install 5,在开发环境下运行该项目: npm run dev 通过上面这几步一个简单的vue项目的开发环境基本就搭建起来,

  • 详解webpack多页面配置记录

    之前也写过webpack学习记录,项目中需要一个常用的webpack多页面配置,所以才动手,本着能写一行是一行的原则,开始了配置webpack之旅. 定目录结构 首先我只需要开发环境(包含自动更新)和打包环境,初定的目录结构是这样的 app主要写业务代码,config里写webpack配置和一些打包.开发的配置,经过一番计较,最后根据自己习惯,目录结构如下: app -libs # 第三方插件库,可以是css也可以是js,eg:jq -static # 公共的静态资源文件夹 -temlates

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

    因为自己的项目是基于vue-cli3进行开发,所以这里只讨论这种情况下的解决办法 在进行多页面开发的时候,项目刚开始阶段,因为文件较少,所以代码编译速度还行,但是随着项目逐渐增大,webpack编译的速度越来越慢,并且经常出现内存溢出的情况. 下面就是几种尝试的方法,加快编译的速度 增加Node运行内存 在Node中通过JavaScript使用内存时只能使用部分内存(64位系统下约为1.4 GB,32位系统下约为0.7 GB).所以不管电脑实际的运行内存是多少,Node在运行代码编译的时候,使用

  • python 含子图的gif生成时内存溢出的方法

    今天想用python做个demo,含两个子图的动态gif,代码如下: import matplotlib.pyplot as plt import imageio,os import matplotlib # plt.ion() fig=plt.figure(0) ax1=plt.subplot(121) ax2=plt.subplot(122) ax1.set_title('input') ax2.set_title('GT') for i in range(1000): img1=plt.i

  • 详解vue-cli + webpack 多页面实例配置优化方法

    本文介绍了vue-cli + webpack 多页面实例配置优化方法,分享给大家 vue+webpack是否有多页面 目前使用vue来做项目,估计大部分都是单页面(SPA)应用,一个轻型的 MVVM 框架,谁用了MVVM框架,就再也回不去JQ时代了,哈哈. 在手机端的项目,使用vue + vue-router是high到爆,不仅仅是我们开发的而言,最主要的用户体检也是开足马力,体检感杠杠的. 那问题来了,使用vue+webpack的单页面是爽到爆,那如果是多页面也能不能high到爆呢?那当然呀,

  • 解决Mybatis-plus和pagehelper依赖冲突的方法示例

    简介 MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发.提高效率而生. 启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作 Mybati-plus本身自带分页功能,但是我个人一直是使用pagehelper进行分页,所以在pom中添加了pagehelper依赖,但是运行项目后发现jar包冲突,面对冲突我们应该怎么解决它呢,看完如下内容便可轻松解决 先看依赖 <!-- mbatis-plus --> &

  • 解决golang内存溢出的方法

    最近在项目中出现golang内存溢出的问题,master刚开始运行时只有10多M,运行几天后,竟然达到了10多个G.而且到凌晨流量变少内存也没有明显降低,内存状态呈现一种很不健康的曲线. 像这种情况肯定是golang内存溢出了,为此我持续排查了两天,终于找到问题所在,特此记录下. 准备工作 一台较好的环境测试机,单台运行无污染. 压测工具,无论服务是http还是websocket服务,都必须准备好压测工具模拟最真实的用户场景. 将master引入net/http/pprof包,通过http访问获

  • Android加载图片内存溢出问题解决方法

    1. 在Android软件开发过程中,图片处理是经常遇到的. 在将图片转换成Bitmap的时候,由于图片的大小不一样,当遇到很大的图片的时候会出现超出内存的问题,为了解决这个问题Android API提供了BitmapFactory.Options这个类. 2. 由于Android对图片使用内存有限制,若是加载几兆的大图片便内存溢出.Bitmap会将图片的所有像素(即长x宽)加载到内存中,如果图片分辨率过大,会直接导致内存OOM,只有在BitmapFactory加载图片时使用BitmapFact

  • 解决运行vue项目内存溢出问题

    目录 运行vue项目内存溢出 记录一下 JavaScript heap out of memory(Vue项目运行内存溢出) 解决方法 运行vue项目内存溢出 npm clone下拉的项目,start时,报超出内存.查询各种方法,下面这种,解决了问题. 记录一下 (1)全局安装increase-memory-limit npm install -g increase-memory-limit (2)进入相应的项目目录下,执行 increase-memory-limit 然后再运行就不会内存溢出了

  • Android 异步获取网络图片并处理导致内存溢出问题解决方法

    测试环境为Adnroid 2.1以上. 1.AndroidManifest.xml 权限配置: 添加互联网访问权限: 复制代码 代码如下: <uses-permission android:name="android.permission.INTERNET" /> 2.异步图片类 ImageDownloadTask 复制代码 代码如下: import java.io.ByteArrayOutputStream; import java.io.IOException; imp

  • tomcat6.0 /7.0安装版内存溢出设置方法

    下面是使用服务形式启动tomcat6.0的内存配置方法: D:\Program Files\Apache Software Foundation\Tomcat 6.0\bin下打开tomcat6w.exe,切换到java选项卡 在Java Options选项的最后面加入(这个和修改注册表的效果一样): -XX:PermSize=256M -XX:MaxPermSize=386m -Xms1024m -Xmx1024m (后面都不能有空格哦,不然会报错,一般情况下PermSize和Xmx之和不能超

  • 用juery的ajax方法调用aspx.cs页面中的webmethod方法示例

    首先在 aspx.cs文件里建一个公开的静态方法,然后加上WebMethod属性. 如: [WebMethod] public static string GetUserName() { //...... } 如果要在这个方法里操作session,那还得将WebMethod的EnableSession 属性设为true .即: [WebMethod(EnableSession = true)]//或[WebMethod(true)] public static string GetUserNam

随机推荐