深入浅出 webpack
2021-05-08 18:56:04 0 举报
AI智能生成
Webpack 凭借强大的功能与良好的使用体验,已经成为目前最流行,社区最活跃的打包工具,是现代 Web 开发必须掌握的技能之一。作者结合自身的实战经验,介绍了 Webpack 的使用与常见优化方法、并深入讲解了 Webpack 原理与架构,相信各阶段的 Webpack 用户都能通过本书得到启发。
作者其他创作
大纲/内容
优化
缩小文件搜索范围
优化 loader 的配置
正则
include,exclude
babel-loader 支持缓存编译出来的结果,可以通过 cacheDirectory 选项开启
resolve.modules
resolve.mainFields
resolve.alias
resolve.extensions
module.noParse
使用 DLLPlugin
.dll 文件
动态链接库:在一个动态链接库中,可以包含被其它模块调用的函数和数据
原理
将模块抽离,打包到动态链接库,一个动态链接库可以包含多个模块
当需要导入的模块存在于动态链接库中,不需要编译,直接从动态链接库中获取
接入 webpack
DLLPlugin 插件:用于打包出一个个不相互以来的动态链接库
DllReferencePlugin 插件:用于将一个个动态链接库引入我们的 webpack配置
.manifest.json
描述了与其相对应的 .dll.js 包含哪些模块和以及每个模块的路径和 Id
使用 HappyPack
原理
将任务分解给多个子进程去并发执行,子进程处理后再将结果发送给主进程
由于 JavaScript 是单线程模型,所以要想发挥多核 CPU 的功能,就只能通过多进程实现
使用
loader 配置 querystring?id=myid
plugin 添加 HappyPack 实例,id 对应 loader 配置中的 id
其它参数
threadPool 共享进程池
使用 ParallelUglifyPlugin 多进程压缩
原理
将多个文件的压缩工作分配给多个子进程去完成,每个子进程还是通过 UglifyJS 去压缩代码,但是变成了并行执行
使用:参考官网
使用自动刷新
文件监听
原理
当前获取的时间和最后一次保存的最后编辑时间不一致则认为该文件发生了变化,watchOptions.poll 设置了定时检查的周期,具体就是每秒检查多少次
等待时间,监听到修改并不会立即刷新,会等待一定的时间,是防止频繁修改导致卡死,可以通过 watchOptions.aggregateTimeout 设置
优化
ignored
浏览器自动刷新
原理
DevServer默认原理:通过在开发的网页中注入客户端的代码,通过代理客户端去刷新整个页面
iframe 原理:将开发的网页装进一个 iframe 中,通过刷新 iframe 达到自动刷新的效果
模块热更新
优化
NamedModulesPlugin
区分环境
process 模块
模拟node.js 中的 process
压缩代码
压缩文本作用:减小代码体积,提高网页加载速度,混淆代码
压缩 JavaScript
UglifyJSPlugin
ParallelUglifyJSPlugin
压缩 ES6
UglifyES
压缩 CSS
cssnano
CDN 加速
概念:内容分发网络
接入 CDN
要为网站接入 CDN,就需要将网页的静态资源上传到 CDN 服务上,在访问这些静态资源的时候,需要使用 CDN 提供的 URL 地址去访问
缓存问题
针对 HTML 文件,不放到 CDN,放在自己的服务器,不开启缓存
JavaScript、CSS、图片等文件,上传到服务器,采取 hash 值方法
请求数量限制问题
同一个时刻同一个域名下资源的并行数量有限
放置不同的域(rel="prefetch")预解析域名
用 webpack 实现 CDN 接入
hash 值解决缓存
publicPath:静态资源的导入 URL 变成指向 CDN 服务的绝对路径的URL,该配置设置存放静态资源 CDN 目录 URL
使用 TreeShaking
剔除无用代码
无效原因
采用了 CommonJS 语法
解决:mainFields
提取公共代码
好处
服务器:减小网络传输流量,减小成本
客户端:提升访问速度
如何提取
base
缓存
common
CommonsChunkPlugin
chunks
name
minChunks
分割代码以按需加载
webpack 内置支持 import (*)
import 返回一个 promise,可以通过 .then 访问加载成功的内容
vue-router
路由懒加载
使用 Prepack
优化运行时候的效率
开启 Scope Hoisting
作用域提升
原理:分析各个模块的依赖关系,尽可能将被打散的模块合并到一个函数中,但前提不能造成代码冗余,因此只有那些被引用一次的代码才有可能被合并
输出分析
原理
工作原理概述
基本概念
entry
module
chunk
代码块,一个 chunk 由一个或者多个模块组合而成
Loader
Plugin
在 webpack 构建流程中特定时机会广播对应的事件,插件可以监听这些事件的发送,并在特定时机做相对应的事情
流程概括
流程细节
注意各个阶段暴露出来的事件,在 自定义 plugin 中有大作用
输出文件分析
一个自执行函数
(function(modules) {
// 模拟 require 语句
function __webpack_require__() {
}
// 执行存放所有模块数组中的第0个模块
__webpack_require__(0);
})([/*存放所有模块的数组*/])
__webpack_require__ 函数可以再浏览器中运行,模拟了 node 的 require 语句
做了缓存优化,已经加载过的模块不会加载第二次
分割代码时的输出
webpackJsonp 用于从异步加载的文件中安装模块
__webpack_require__.e 用于加载被分割出去的,需要异步加载的 chunk 对应的文件
编写 Loader
原则:职责单一性,只管输入输出
获取 Loader 中的 options
返回其他结果
this.callback
同步和异步
处理二进制数据
module.exports.raw = true;
缓存加速
加载本地 Loader
npm link
ResolveLoader
编写 Plugin
插件执行顺序
初始化获得实例
初始化 compiler 对象
调用插件 apply 方法,传入 compiler 对象
compiler.plugin(事件名称, 回调函数) 监听 webpack 暴露出来的事件
compiler 对象
包含当前 webpack 所有的配置信息,包括 loader、plugin等等,在webpack 启动的时候初始化,它是全局唯一的,可以认为它是当前 webpack 的一个实例
整个webpack从启动到关闭的生命周期
compilation 对象
当前的模块资源、编译生成资源、变化的文件等
代表一次新的编译
事件流
常用的 API
读取输出资源、代码块、模块及其依赖
监听文件变化
修改输出资源
判断 Webpack 使用了哪些插件
webpack 调试
入门
前端的发展
常见的构建工具以及比较
何为构建?
构建就是做这件事情,把源代码转换成发布到线上的可执行 JavaScrip、CSS、HTML 代码
工程化、自动化思想在前端开发中的体现
npm script
内置,简单
提供 pre post
参考阮一峰:http://www.ruanyifeng.com/blog/2016/10/npm_scripts.html
grunt
缺点:集成度不够,要写很多配置才可以用,无法做到开箱即用
gulp
缺点
概念:基于流的自动化构建工具
特点:引入了流的概念,同时提供了一系列的插件去处理流,流在插件之间传递
Fis3
webpack
概念:打包模块化 JavaScript 工具
优点:集成度高,有各种各样的plugin和loader,开箱即用
一切皆为模块,唯一的缺点就是只能用于模块化开发的项目
rollup
为什么要用 webpack
时代产物
“模块化+新语言+新框架”
良好的生态
安装和使用
-D 是 --save-dev 的缩写 ,安装的时候会安装到devDependency下面
使用 Loader
传参方式
每一个 Loader 可以通过 URL queryString 的方式传入参数
还可以通过Object的方式传入如:options:{ minimize:true,}
使用 plugin
通过 plugins 属性配置,传入的是插件列表,每一项都是插件实例
使用 DevServer
开发环境
HTTP server
webpack-dev-server
DevServer 会把webpack构建的产物放置到内存中,想要访问,必须通过 HTTP 访问
原理:启动 HTTP 服务器用于服务页面请求,同时会启动webpack,并监听 webpack 发出的文件变化的信号,通过 websocket 协议自动刷新网页做到实时预览
监听模式
webpack --watch 开启监听模式
index.html 没有实现实时更新
模块热替换
--hot
sourceMap
--devtool source-map
配置
entry
context
启动 weback 时所在的当前工作目录
入口类型
string
'./app/entry' './app/entry'
array
['./app/entry1', './app/entry2']
配合 output.library 使用,只有最后一个文件入口的模块会被导出
object
{ a: './app/entry-a', b: ['./app/entry-b1', './app/entry-b2']}
多入口文件
chunk 名称
main
object
多个chunk
对应 object 中的 key 值
动态 Entry
output
chunk
id
name
hash
chunkhash
filename
静态
动态
chunkFilename
配置非入口的 chunk 文件的名称
path
输出文件的本地存放目录
必须是 String 类型
publicPath
配置发布到线上资源的 URL 前缀
默认为空
一般以 / 结尾
crossOriginLoading
webpack 需要输出部分代码需要异步加载
原理:JSONP的方式实现
通过 crossOriginLoading 可以配置异步插入标签的 crossOrigin 值
anonymous
use-credentials
应用:获取详细的错误信息
libraryTarget和library
var(默认)
commonjs
commonjs2
this
window
global
module
概念:配置如何处理模块
rules
配置模块的读取和解析规则
test/include/exclude
use 配置项来应用Loader
Loader 的执行顺序默认是从后往前执行
使用 enforce 选项,从签到后
pre
post(默认)
noParse
让 webpack 忽略对部分没采用模块化的文件的递归解析和处理
原因:一些库 如 JQuery 庞大又没有采用模块化的标准
收益:提高构建速度
parser
Resolve
概念:webpack 本身内置 JavaScript 模块化语法解析功能,默认是采用模块化标准里的约定去寻找,但是也可以通过自身需求修改默认规则,resolve 应运而生
alias
mainFields
根据不同的配置决定优先采用哪份代码
extensions
导入语句没带文件后缀时,webpack 会自动带上后缀去尝试访问文件是否存在
默认值:extensions: ['.js', '.json']
modules
配置 webpack 去哪些目录下寻找第三方模块
默认:node_modules
modules:['./src/components','node_modules']
descriptionFiles
配置描述第三方模块的文件名称
默认是 package.json
enforceExtension
为 true 必须带上文件后缀
plugin
用于拓展 webpack 功能
devServer
hot
inline
默认是会自动注入
关闭:DevServer 将无法直接控制要开发的网页
iframe 的方式
http://localhost:8080/webpack-dev-server/
historyApiFallback
HTML5 History API:单页应用要求服务器在针对任何命中的路由时都返回一个对应的 HTML 文件,例如在访问 http://localhost/user 和 http://localhost/home 时都返回 index.html 文件
contentBase
配置 DevServer HTTP 服务器的文件根目录,默认情况下为当前执行目录
headers
在HTTP 响应中注入一些 HTTP 响应头
host
配置 DevServer 服务监听的地址
port
配置 DevServer 服务监听的端口
open
clientLogLevel
配置在客户端的日志登记
其他配置项
target
设置 JavaScript 的应用场景
web
node
...
devtool
配置生成 source Map
devtool: 'source-map'
默认为 false
watch 和 watchOptions
Externals
概念:用来告诉 webpack 要构建的代码中使用了哪些不用被打包的模块
ResolveLoader
告诉 webpack 如何去寻找 Loader
常用来加载本地的 Loader
实战
0 条评论
下一页