webpack
webpack 最出色的功能之一就是,除了
JavaScript
,还可以通过loader
引入任何其他类型的文件。
Webpack 核心概念:
Entry
(入口):Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。Output
(出口):指示 webpack 如何去输出、以及在哪里输出Module
(模块):在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。Chunk
(代码块):一个 Chunk 由多个模块组合而成,用于代码合并与分割。Loader
(模块转换器):用于把模块原内容按照需求转换成新内容。Plugin
(扩展插件):在 Webpack 构建流程中的特定时机会广播出对应的事件,插件可以监听这些事件,并改变输出结果
配置项
- 入口 Entry
entry: {
a: "./app/entry-a",
b: ["./app/entry-b1", "./app/entry-b2"]
},
多入口可以通过 HtmlWebpackPlugin
分开注入
plugins: [
new HtmlWebpackPlugin({
chunks: ['a'],
filename: 'test.html',
template: 'src/assets/test.html'
})
]
- 出口 Output
修改路径相关
publicPath
:并不会对生成文件的目录造成影响,主要是对你的页面里面引入的资源的路径做对应的补全filename
:能修改文件名,也能更改文件目录
导出库相关
library
: 导出库的名称libraryTarget
: 通用模板定义方式
- 模块 Module
webpack 一切皆模块,配置项 Module,定义模块的各种操作,
Module 主要配置:
loader
: 各种模块转换器extensions
:使用的扩展名alias
:别名、例如:vue-cli 常用的@
出自此处
- 其他
plugins
: 插件列表devServer
:开发环境相关配置,譬如proxy
externals
:打包排除模块target
:包应该运行的环境,默认web
Webpack 执行流程
webpack从启动到结束会依次执行以下流程:
- 初始化:解析webpack配置参数,生产
Compiler
实例 - 注册插件:调用插件的
apply
方法,给插件传入compiler
实例的引用,插件通过compiler调用Webpack提供的API,让插件可以监听后续的所有事件节点。 - 入口:读取入口文件
- 解析文件:使用
loader
将文件解析成抽象语法树AST
- 生成依赖图谱:找出每个文件的依赖项(遍历)
- 输出:根据转换好的代码,生成
chunk
- 生成最后打包的文件
ps:由于 webpack 是根据依赖图动态加载所有的依赖项,所以,每个模块都可以明确表述自身的依赖,可以避免打包未使用的模块。
Babel
Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript
语法,以便能够运行在当前和旧版本的浏览器或其他环境中:
Babel 内部所使用的语法解析器是 Babylon
主要功能
- 语法转换
- 通过
Polyfill
方式在目标环境中添加缺失的特性 (通过@babel/polyfill
模块) - 源码转换 (
codemods
)
主要模块
@babel/parser
:负责将代码解析为抽象语法树@babel/traverse
:遍历抽象语法树的工具,我们可以在语法树中解析特定的节点,然后做一些操作@babel/core
:代码转换,如ES6的代码转为ES5的模式
Webpack 打包结果
在使用 webpack 构建的典型应用程序或站点中,有三种主要的代码类型:
- 源码:你或你的团队编写的源码。
- 依赖:你的源码会依赖的任何第三方的
library
或 “vendor
” 代码。 - 管理文件:
webpack
的runtime
使用manifest
管理所有模块的交互。
runtime
:在模块交互时,连接模块所需的加载和解析逻辑。包括浏览器中的已加载模块的连接,以及懒加载模块的执行逻辑。
manifest
:当编译器(compiler)开始执行、解析和映射应用程序时,它会保留所有模块的详细要点。这个数据集合称为 “Manifest”,
当完成打包并发送到浏览器时,会在运行时通过 Manifest 来解析和加载模块。无论你选择哪种模块语法,那些 import 或 require 语句现在都已经转换为 webpack_require 方法,此方法指向模块标识符(module identifier)。通过使用 manifest 中的数据,runtime 将能够查询模块标识符,检索出背后对应的模块。
其中:
import
或require
语句会转换为__webpack_require__
- 异步导入会转换为
require.ensure
(在Webpack 4 中会使用 Promise 封装)
比较
gulp
是任务执行器(task runner):就是用来自动化处理常见的开发任务,例如项目的检查(lint)、构建(build)、测试(test)webpack
是打包器(bundler):帮助你取得准备用于部署的 JavaScript 和样式表