webpack构建流程

4,114 阅读5分钟

1.Webpack的构建流程主要有哪些环节?如果可以请尽可能详尽的描述 Webpack 打包的整个过程。

回答以上问题首先要了解webpack什么?

webpack是javascript应用程序的静态模块打包工具,会递归创建一个依赖关系图,其中包含应该程序的需要的模块,然后将这些模块打包成一个或多个bundle。

了解webpack最基础的概念之后,我们再来跟进一步了解webpack作为一个工具是如何实现功能的。下面从工具的属性来分析一下webpack的使用。

从单纯使用作为开发工具的角度,为了降低操作的复杂度webpack提供了webpack.config.js配置文件。当然还有更简单的webpackv4.0.0开始,可以不用引入配置文件,就可以实现打包。官方在持续的降低复杂度,但是从多掌握点知识的角度即如何做到由术入道,还是需要多关注的如何在大项目(复杂度高)的项目中怎么灵活使用配置文件。

初始webpack.config.js
  • 入口(entry)
  • 输出
  • loader
  • 插件(plugins)
通过代码来更直观的认识webpack.config.js
module.exports = {
  //入口文件
  entry: './src/index.js',
  //导出目录
  output: {
    filename: 'bundle.js',
    path: path.join(__dirname, 'dist')
  },
  //loader
  module: {
    rules: [
      {
        test: /.css$/,
        use: ['style-loader', 'css-loader'],
      }
    ]
  },
  //plugin
  plugins: [
    new CleanWebpackPlugin(),
  ]
}
通过以上简单点了解可以指导webpack的4个核心概念:
  • entry:源码的入口文件,webpack打包的第一步
  • output:输入目录,即源码经过webpack处理之后,最终生成的文件
  • loader:处理非javascript文件(webpack自身只理解javascipt)
  • plugin:在webpack的构建过程中处理其他任务,优化输出结果

知道以上知识可以帮助开阔思路如:常用的loader、plugin有哪些,如何打包多入口的等,然后运行yarn webpack,整个编译构建过程结束,相对于webpack的构建过程以上知识存在于术的层面,下面从入道的层面分析一下webpack的构建流程、打包流程。

在分析构建、打包流程之前可以先猜测一下webpack是如何工作的:
  • 首先会校验配置文件(webpack.config.js),然后读取配置文件参数
  • 至少会有一个Compiler(编译)、读取源码的过程,对源码进行输入、输出的操作,毕竟最后编译的文件是bundle.js
  • 需要编译入口文件(entry),如果有依赖还需要处理递归调用的问题
  • 如果想加载plugins(插件),那么至少会提供(hooks)钩子函数
  • 最后大概率会调用一个run方法
基于以上分析的信息,来整理webpack构建打包流程如下:
  1. 初始化参数。获取用户在webpack.config.js文件配置的参数
  2. 开始编译。初始化compiler对象,注册所有的插件plugins,插件开始监听webpack构建过程的生命周期事件,不同环节会有相应的处理,然后开始执行编译。
  3. 确定入口。根据webpack.config.js文件的entry入口,开始解析文件构建ast语法树,找抽依赖,递归下去。
  4. 编译模块。递归过程中,根据文件类型和loader配置,调用相应的loader对不同的文件做转换处理,在找出该模块依赖的模块,递归本操作,直到项目中依赖的所有模块都经过了本操作的编译处理。
  5. 完成编译并输出。递归结束,得到每个文件结果,包含转换后的模块以及他们之前的依赖关系,根据entry以及output等配置生成代码块chunk
  6. 打包完成。根据output输出所有的chunk到相应的文件目录

2.Loader 和 Plugin 有哪些不同?请描述一下开发 Loader 和 Plugin 的思路。

关于这个问题,首先要会到webpack定义loader、plugin的定义:

loader:loader让webpack去处理那些非JavaScript文件(webpack自身只理解javascript)。loader可以将所有类型的文件转换成webpack能处理的有效模块。然后利用webpack的打包能力,对它们进行处理。

plugin:插件可以用于执行其他范围更广的任务,插件的范围包括,打包优化,代码压缩,甚至可以重新定义环境中的变量。插件的目的是用于解决loader无法实现的其他事。

开发一个loader:

首先要了解loader是将非javascript文件转换为webpack能处理的有效模块,那么loader是一个输入资源转换输出的过程。

  • loader.js需要到导出一个函数,这个函数对加载的资源进行处理
  • 函数输入为加载到的资源,输出为加工的资源
  • 输入的结果有两种形式:第一就是输出为标准的JS代码,让打包结果可以正常执行,第二就是输出的结果交给下一个loader继续执行
  • 开发好的loader.js配置到webpack.config.js下面的module.rules
开发一个plugin:

首先要了解plugin是通过webpack的钩子机制(hooks)实现的,开发的插件可以通过这些不同的任务节点上挂载不同的任务。

  • 创建一个javascript命名函数
  • 在插件函数的prototype上定义一个apply方法
  • 指定一个绑定到webpack自身的事件钩子
  • 处理webpack内部实例的特点数据
  • 功能完成以后调用webpack提供的回调

3.使用 Webpack 实现 Vue 项目打包任务

项目示例地址:gitee.com/yhaixin/web…

关于webpack打包文件概述:

  • webpack.common.js
  • webpack.dev.js
  • webpack.prod.js

以上文件大概可以看出我们的思路,对于开发(dev)、生成(prod)环境做了打包编译配置区分。

主要介绍一下webpack.prod.js文件的配置:

在看webpack.prod.js文件时会发现,在该文件内主要做的文件压缩、代码分包等用到loader、plugins有:

  • mini-css-extract-plugin
  • terser-webpack-plugin
  • optimize-css-assets-webpack-plugin