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 是根据依赖图动态加载所有的依赖项,所以,每个模块都可以明确表述自身的依赖,可以避免打包未使用的模块。
BabelBabel 是一个工具链,主要用于将 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 和样式表,将它们转换为适合浏览器的可用格式。例如,JavaScript 可以压缩、拆分 chunk 和懒加载,
实现一个 loaderloader 就是一个js文件,它导出了一个返回了一个 buffer 或者 string 的函数;
譬如:
// log-loader.js module.exports = function (source) { console.log('test...', source) return source }在 use 时,如果 log-loader 并没有在 node_modules 中,那么可以使用路径导入。
实现一个 pluginplugin: 是一个含有 apply 方法的 类。
譬如:
class DemoWebpackPlugin { constructor () { console.log('初始化 插件') } apply (compiler) { } } module.exports = DemoWebpackPlugin