基于webpack工程化的思考

简介: 本文章是在基于webpack多入口配置工程并且项目需要持续迭代作为基础去讨论的,单页面不作讨论。文章适合对webpack有一定了解的人看,主要讨论工程化中关于缓存利用率的问题。

本文章是在基于webpack多入口配置工程并且项目需要持续迭代作为基础去讨论的,单页面不作讨论。文章适合对webpack有一定了解的人看,主要讨论工程化中关于缓存利用率的问题。

一、如何打包文件让缓存利用率增高

在webpack中,我们通常会打包一个vendor和一个common文件作为基础包,vendor通常是将npm中的依赖打包、而common则是让达到一定引用次数的模块进行打包。具体配置如下:


4323278d2252c7b5d7df13ffa5f49802e61e9515

以上的配置,在持续迭代中,是不利于持久性缓存的,因为需要持续迭代,不可避免的是业务文件的修改,前端做缓存主要依靠的是通过给文件名加上hash值去控制文件缓存,而webpack1中一旦修改了某个文件,会导致整体的文件hash值的变化,包括vendor和common的hash值,但是这一个缺点在webpack2以后就被处理得比较好了,可以用HashedModuleIdsPlugin稳定模块的id,以保证vendor在单个业务文件修改时,其他文件的hash值保持稳定。

但是在持续增长的业务中,这样的方式对持久化就是可靠的吗?如果你在增量迭代时,突然需要引入某一些npm包呢?导致vendor的hash值在这个时候也会发生变化,所有的用户不得不重新下载一个庞大的vendor文件。

根据这种场景我们可以如何去优化这个缓存呢?这里我采用的方案是,将整个项目依赖的基础包,单独放在vendor中进行手动配置打包,在入口配置中加入自己手动配置的vendor列表,这一个列表是整个项目最基础依赖的包。

例如:在一个多入口vue建立的项目中,我们项目几乎每个入口页面都要引入vue,那么我们的vendor列表中就可以配置上vue

2ef520fce4c0a02b2fe3bab389bf09d84e9ed1bf

那么vendor包中就只会将vue打包进vendor,而其余的模块则按照引用次数将包打包进common中,这么做的好处是什么?在项目迭代中,vendor的打包是我们可以控制的,也就是这个列表我们不修改,则vendor的hash值不变,也就是说在用户不清除缓存的情况下,我们的vendor包可以一直在缓存中,对于页面的性能来说是有保证的,变化的模块也仅仅在common模块和其他的业务文件。

比如,在vue的项目中,我们集成了vuex、rxjs、axios等库,在多页面开发中这些库基本在每一个入口中都会有引用到,那么我们是不是可以将vendor的列表配置成[ 'vue', 'vuex', 'rxjs', 'axios' ],通过commonPlugin则可以将列表中的模块打包成vendor,在迭代中,其他npm包的引入并不会影响到vendor hash值的改变,等到你需要更新vendor时,则可以手动往列表中添加依赖。

二、dll文件构建自动化

dll文件是在开发时,先对所有的npm包预先打包,每一个入口都会引入,之后根据manifest去对npm包资源进行引用,这样做,在开发时就不需要对npm包进行打包构建,节省一部分时间,具体可google。

91d6dd37f170749aa0132eb732f9225403e9154e

这里就会涉及到一个问题,每一次npm依赖更新了,都需要重新进行dll文件的打包。作为一个程序员,很显然,这么做不够偷懒。那我们可以如何去做dll文件构建的自动化呢?这里提供一下我的思路。

一般我们在开始时,通常使用npm script进行项目构建、而dll文件需要单独运行命令,之后再构建项目


webpack --config dll.config.js

webpack-dev-server --config dev.config.js

因为涉及到两条命令,所以我选择了使用shell对两个命令合并


// npm run start命令行执行dev.sh脚本
sh bin/dev.sh
复制代码#!/bin/bash
### 思路
###1、在首次构建时,需要生成依赖的数量,并将数据重定向到文件中,用于二次构建时依赖数量的匹配
###2、二次构建时,会先判断记录了依赖数量的文件是否存在,存在则读取数量进行现有依赖数量的匹配,若依赖数量无变化,则认为dll文件不需要构建,直接运行项目的构建,若依赖数量变化,则重新构建dll文件

### 用于本地开发时自动维护dll文件
rootPath=`pwd`
packagePath=${rootPath}'/package.json'
dllValidatePath=${rootPath}'/build/vendor.dll.validate.txt'

### 读取package.json的dependencies与devDependencies对应的行数
dependenciesRow=`grep -n "dependencies" $packagePath | cut  -d  ":"  -f  1`
devDependenciesRow=`grep -n "devDependencies" $packagePath | cut  -d  ":"  -f  1`

### 依赖行数(以此判断依赖是否增减)
rows=$[$devDependenciesRow-$dependenciesRow]

### 判断vendor.dll.validate.txt文件是否存在
if [ -e $dllValidatePath ]; then

  ### 获取之前的依赖行数
  oldRows=`cat $dllValidatePath`

  if [ $oldRows == $rows ]; then
    ### 依赖数量相等则直接构建
    npm run dev
  else
    echo $rows > $dllValidatePath
    ### 不等,重新创建vendor.dll.js,并将新的行数写到vendor.dll.validate.txt
    npm run dll
    npm run dev
  fi

else
  rm -rf build
  mkdir build
  touch $dllValidatePath
  echo $rows > $dllValidatePath
  npm run dll
  npm run dev
fi

上面是通过依赖数量的变化来做其实是有点bug的,如果依赖增加了之后再减少到相同数量,dll文件并不会重新构建,这时需要自己手动构建一次,所以,严谨一些应该是要对依赖列表进行前后对比才可以确定dll是否需要变化shell相应的也会更复杂一些吧,以后有时间优化一下这里的逻辑。

注意:dll文件,最好不要压缩,因为压缩插件会将console打印的语句去除,会导致开发时框架或者库的错误提示或者警告丢失。

三、库的引用

不知道大家有没一种情况,就是某一些库,只是那么两三个入口需要使用,但是却被打包进common中。比如一些即时聊天服务,通常需要引入一些script或者css,而你的common配置中,超过两个引用次数就会将包打进common中,导致common过大,而每一个入口通常都需要引入common,并且这些外部引用的库会随着common的打包变化而重新下载,这就会导致用户无法持久缓存这部分这种库。

当然,我们可以通过增加common的模块引用次数下限去将这种库排除在外,的确可以,但是这样对common的控制就会受限,这不是我想的,我想common的配置,与这种业务性非常强的库抽离出来。

先看一下HtmlWebpackPlugin的配置


a8c35b5a60be77454a9e2ce11d8398fca8f2310c
931e78f7c6d692450854dc5302e6b177dbd73d4c

这里我们通过这个插件的自定义配置,在html中通过标记将script或者css文件以绝对路径的方式输出到结果中,这样我们就不需要通过webpack对这种稍微大一些又不想打包进common的包进行引用了,直接通过全局script标签的方式进行引入,以一定的规范放置文件,根据文件的版本做缓存的控制。

四、总结

以上是我对于webpack多入口配置的一些思考以及建议,如有错误,欢迎及时指正。下面是github项目地址webpack3-vue-cli



原文发布时间为:2018年06月22日
原文作者:bug给我滚
本文来源:  掘金  如需转载请联系原作者

相关文章
|
4月前
|
前端开发
构建工具对比:Webpack与Rollup的前端工程化实践
在现代前端开发中,前端工程化变得愈发重要。本文将对两个常用的构建工具——Webpack和Rollup进行比较,探讨它们在前端工程化实践中的特点、优势和适用场景。无论是大型应用的打包优化还是轻量级库的构建,选择适合的构建工具都能提高开发效率和项目性能。
29 1
|
8月前
|
前端开发 JavaScript 开发工具
webpack 01 - 初识前端工程化
webpack 01 - 初识前端工程化
|
4月前
|
前端开发 JavaScript 开发者
前端工程化实践:Webpack、Rollup等构建工具比较
在现代 Web 开发中,前端工程化已经成为了不可或缺的一部分。而构建工具作为前端工程化的重要组成部分,可以帮助开发者更高效地完成项目构建和管理。本文将比较两种主流的构建工具 Webpack 和 Rollup,并探讨它们的优缺点以及适用场景。
|
4月前
|
前端开发 UED
探索前端工程化之路:Webpack、Rollup等构建工具对比与实践
在现代前端开发中,工程化成为不可或缺的一环。本文将深入探讨常用的前端构建工具Webpack和Rollup,并比较它们在实践中的优劣势。通过对功能、性能、插件生态等方面的评估,帮助读者选择适合自己项目需求的构建工具。
34 1
|
4月前
|
前端开发 测试技术
前端工程化实践与构建工具比较:Webpack、Rollup等
在当今互联网时代,前端开发已经成为了最热门和最重要的职业之一。而随着前端技术的不断发展,前端工程化已经成为了必不可少的一部分。本篇文章将会介绍前端工程化的实践,并比较常用的构建工具Webpack和Rollup的优缺点,帮助读者更好地掌握前端工程化和构建工具的使用。
|
9月前
|
前端开发 JavaScript 搜索推荐
webpack----前端工程化与webpack的基本使用
webpack----前端工程化与webpack的基本使用
|
9月前
|
存储 JavaScript 前端开发
前端工程化与webpack(二)
前端工程化与webpack(二)
|
9月前
|
JavaScript 前端开发 搜索推荐
|
10月前
|
前端开发 JavaScript IDE
前端工程化===Webpack?No,我来告诉你什么是前端工程化!
前端工程化===Webpack?No,我来告诉你什么是前端工程化!
108 1
|
11月前
|
前端开发 JavaScript 开发者
前端工程化打包工具之Webpack
Webpack是一个非常流行的前端工程化打包工具,它可以帮助开发者快速构建具有可重用性和可维护性的前端项目,并且提供了完善的依赖管理和打包机制。
99 0