webpack 基础

174 阅读2分钟

为什么需要构建工具?

  • 转换ES6/ES7、TypeScript语法
  • css前缀补全/预处理器
  • 压缩混淆
  • 图片压缩

为什么选择webpack?

  • 社区生态丰富
  • 配置灵活和插件化扩展
  • 官方更新迭代速度快

认识webpack

基本配置包括entry output mode module plugins

mode

mode用来指定当前的构建环境是production还是development,对应node.js中的process.env.NODE_ENV,默认为production。

Loader

Loader直译为"加载器"。Webpack将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到loader。 所以Loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力。

常见的Loader

列举部分

babel-loader 转换ES6/ES7等js新特性语法

css-loader 支持css文件的加载和解析

less-loader 将less文件转换成css

ts-loader 将ts转换成js

file-loader 进行图片、文字等文件的打包压缩

tread-loader 多进程打包js和css

Loader的用法

module: {
    rules: [ 
        // test 指定匹配规则,use 指定使用的 loader 名称    
        { test: /.css$/, use: 'css-loader' },  
    ];
}

rules内loader是倒序执行!!!

举例:rules中loader排放位置是:css-loader,less-loader。倒序执行意为先把less转换为css,再通过css-loader解析。

plugins

Plugin直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 Plugins用于 bundle 文件的优化,资源管理和环境变量注入,作用域整个构建过程。

常见的plugins

列举部分

CommonsChunkPlugin 将chunks相同的模块代码提取成公共js

CleanWebpackPlugin 清理构建目录

CopyWebpackPlugin 将文件或者文件夹拷贝到构建的输出目录

HtmlWebpackPlugin 创建html文件去承接输出的bundle

UglifyjsWebpackPlugin 压缩js

ZipWebpackPlugin 将打包出的资源生成一个zip包

BundleAnalyzerPlugin 可视化查看各个文件的大小

TerserPlugin 压缩JS,自动清除console.log,debug等

plugins的用法

在配置文件中的 plugins 数组里将定义好的插件放入即可。

文件指纹策略

文件指纹的生成方式

Hash 和整个项目的构建相关,只要项目文件有修改,整个项目构建的hash值就会更改

Chunkhash 和webpack打包的chunk有关,不同的entry会生成不同的chunkhash值

Contenthash 根据文件内容来定义hash,文件内容不变,则contenthash不变

文件指纹webpack配置

css文件一般用contenthash来实现;js使用chunkhash;图片资源用hash。

代码压缩

js文件压缩

内置插件uglifyjs-webpack-plugin

注:webpack3需要手动引用配置该插件,webpack4默认使用。

在 webpack4 中,通过配置 optimization.minimize 与 optimization.minimizer 来自定义压缩相关的操作,uglifyjs不支持es6语法,可配置TerserPlugin替代。

css文件压缩

使用optimize-css-assets-webpack-plugin,同时使用cssnano预处理器处理css

plugins: [
    new OptimizeCSSAssetsPlugin({
        assetNameRegExp: /.css$/g,
        cssProcessor: require('cssnano'),  
    })
];

html文件压缩

修改html-webpack-plugin,设置压缩参数

plugins: [
    new HtmlWebpackPlugin({
        filename: 'index.html',
        template: 'build/index.html',
        inject: true,
        minify: { 
            collapseWhitespace: true,           
            removeComments: true, 
            removeAttributeQuotes: true
        }
    })
];

体积优化策略

Tree-shaking

公共资源分离

图片压缩

动态polyfill

Tree-shaking

Tree-shaking是webpack内置的一个优化,主要功能就是去除没有用到代码。

这部分代码也被称为Dead Code, Dead Code 一般具有以下几个特征

  • 代码不会被执行,不可到达

  • 代码执行的结果不会被用到

  • 代码只会影响死变量(只写不读)

Tree-shaking主要依赖于ES6的模块化import和export,我们都知道ES6的module只能是顶层出现,和运行时无关,不能运行时加载。如果是require,需要执行后才知道有没有引用,就无法进行Tree-shaking。

ES6 module 特点:

  • 只能作为模块顶层的语句出现
  • import 的模块名只能是字符串常量
  • import binding 是 immutable的

在webpack5中已经自带tree-shaking功能,在打包模式为production时,默认开启 tree-shaking功能。

HappyPack

webpack中最耗时的就是loader的转换过程,转换的流程很长。happypack的原理就是把这部分的任务拆解成多个子进程去并行处理,减少构建时间。

通过new HappyPack()实例化,然后把任务交由实例统一调度分配。核心调度器会将一个个任务分配给空闲的子进程。处理完毕后发送给核心调度器。