[前端进阶课] 构建自己的 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 和样式表,将它们转换为适合浏览器的可用格式。例如,JavaScript 可以压缩、拆分 chunk 和懒加载,

实现一个 loader

loader 就是一个js文件,它导出了一个返回了一个 buffer 或者 string 的函数;

譬如:

// log-loader.js module.exports = function (source) { console.log('test...', source) return source }

在 use 时,如果 log-loader 并没有在 node_modules 中,那么可以使用路径导入。

实现一个 plugin

plugin: 是一个含有 apply 方法的 类。

譬如:

class DemoWebpackPlugin { constructor () { console.log('初始化 插件') } apply (compiler) { } } module.exports = DemoWebpackPlugin

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygsyy.html