[TOC]
[整个章节的参考链接](https://kaiwu.lagou.com/course/courseInfo.htm?courseId=416#/detail/pc?id=4425)
>[success] # 编译阶段提速
~~~
1.编译模块阶段的效率提升,下面的行为操作都是在webpack编译阶段去做的
~~~
>[warning] ### IgnorePlugin -- 忽略第三方包指定目录
~~~
1.webpack 的内置插件,作用是忽略第三方包指定目录。
2.有的依赖包,除了项目所需的模块内容外,还会附带一些多余的模块,例如'moment' 会将所有
本地化内容和核心功能一起打包
3.下面案例通过配置的'webpack-bundle-analyzer'来看使用 'IgnorePlugin'后对'moment'的影响
~~~
* 配置代码
~~~
const webpack = require('webpack')
//webpack.config.js
module.exports = {
//...
plugins: [
//忽略 moment 下的 ./locale 目录
new webpack.IgnorePlugin({
resourceRegExp: /^\.\/locale$/,
contextRegExp: /moment$/,
}),
]
}
~~~
* 配置前
![](https://img.kancloud.cn/10/91/109140ff5c8b146d4984f3b38263fa4d_1373x675.png)
* 配置后
![](https://img.kancloud.cn/15/77/1577bde59f19de3e43a0686d14b4c4da_990x467.png)
>[danger] ##### 疑问这些包并不想全排除部分还是想引用要怎么做
~~~
1.可以配合'ContextReplacementPlugin' ,关于这部分可以参考=
'https://iamakulov.com/notes/webpack-contextreplacementplugin/'
~~~
>[warning] ### 按需引入
~~~
1.以'lodash' 为例通常项目中只使用很少的lodash方法,但是构建时却发现构建时引入了整个依赖包
所以需要按需引入这些内容
如果之前你的项目是这样使用loash:
import _ from 'lodash'
console.log(_.slice([]))
现在按需你需要这么写:
import slice from 'lodash/slice'
console.log(slice([]))
~~~
* 配置前
![](https://img.kancloud.cn/93/5b/935b90af1008f6a201ef918f1c63d969_1068x465.png)
* 配置后
![](https://img.kancloud.cn/1d/b6/1db6146f02f9af618e940eca32f44ebe_1369x673.png)
>[danger] ##### lodash 如果已经在项目初期没有做按需引入如何补救
~~~
1.使用'babel-plugin-lodash' 和'lodash-webpack-plugin' 插件参考文章'https://www.jianshu.com/p/3dd1948cf5a2'
2.使用'babel-plugin-import '参考'https://www.ctolib.com/mip/shenshanyoumu-babel-plugin-import-annotations.html'
'https://xiaozhuanlan.com/topic/2984105637'
上面两个来实现动态删除无效代码
~~~
>[warning] ### 预编译资源模块
~~~
1.提前对一些业务包,一类打包后然后使用
~~~
>[danger] ##### 创建一个webpack.dll.js
~~~
1.创建一个webpack.dll.js 用来专门处理这些需要预处理的文件
2.使用 DLLPlugin 进行分包,DllReferencePlugin对 manifest.json 引用
~~~
~~~
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: {
// 要处理的文件,这个library不是固定的可以自己个根据需要起适合自己的
library: [
'react',
'react-dom'
]
},
output: {
filename: '[name]_[chunkhash].dll.js', // library.dll.js中暴露出的全局变量名是entry里面key
path: path.join(__dirname, 'build/library'),// 打包后文件输出的位置
library: '[name]_[hash]' // 库暴露出来的名字 可以参考打包组件和基础库
},
plugins: [
new webpack.DllPlugin({
name: '[name]_[hash]',// 生成一个文件映射json名字
path: path.join(__dirname, 'build/library/[name].json') // 保存的位置
})
]
};
~~~
>[danger] ##### 在webpack 打包指令位置配置
~~~
1.上面是一个单独的指令,专门用来打包提取包的不是对项目打包,将提取包的内容通过
'DllReferencePlugin' 引入之后,在执行打包
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./build/library/')
})
],
~~~
>[danger] ##### 可以参考
[参考链接](https://www.cnblogs.com/lusongshu/p/8473318.html)
>[warning] ### 使用Externals
~~~
1.希望 webpack 不会对其进行打包,此时就可以配置 externals
~~~
>[danger] ##### 使用
~~~
1.这样jq在编译阶段就不会被,打入项目中可以通过cdn的形式引入
module.exports = {
//...
externals: {
//jquery通过script引入之后,全局中即有了 jQuery 变量
'jquery': 'jQuery'
}
}
// 通过手动cdn形式引入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="root">root</div>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</body>
</html>
~~~
>[danger] ##### Externals 和 DLLPlugin 区别
~~~
1.在 Webpack 的配置方面,externals 更简单,而 DllPlugin 需要独立的配置文件。
2.DllPlugin 包含了依赖包的独立构建流程,而 externals 配置中不包含依赖框架的生成方式,通常
使用已传入 CDN 的依赖包。
3.externals 配置的依赖包需要单独指定依赖模块的加载方式:全局对象、CommonJS、AMD 等。
4.在引用依赖包的子模块时,DllPlugin 无须更改,而 externals 则会将子模块打入项目包中。
~~~
>[danger] ##### 如何自动引入cdn
* 说明 页面提取资源使用vue 做的一个案例,[关于webpack中如何使用vue参考配置](https://vue-loader.vuejs.org/)
~~~
1.当做项目的时候对一些基础第三方包我们可以采用cdn的形式,将类第三方包抽离
2.配置cnd的'plugins' 用到的是'html-webpack-externals-plugin' -- 'npm install --save-dev html-webpack-externals-plugin'
3.使用的时候需要配合'HtmlWebpackPlugin' 一起使用
~~~
[html-webpack-externals-plugin 具体使用地址](https://www.npmjs.com/package/html-webpack-externals-plugin)
>[danger] ##### 以vue 举个例子
~~~
1.注意事项,下面案例'entry' 是直接可以跟cdn地址的,为什么vue这个却没有想react那种简写呢?因为
仔细看我用的vue的cdn地址结尾是没有类型,如果是没有具体类型的cdn地址,注意一定要加type字段
2.注意"global: 'Vue'" 这个vue 是大写的,为什么是大写因为我在后续文件引入写法是
" import Vue from 'vue' ",我用的参数是大写,这里也是一个坑,具体可以看文档对global解释
~~~
~~~
const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin')
moudles.export = {
plugins: [
new HtmlWebpackExternalsPlugin({
externals: [{
module: 'vue',
entry: {
path: 'https://cdn.jsdelivr.net/npm/vue@2.6.11',
type: 'js'
},
global: 'Vue'
}],
files:['template.html'] // 也可以指定页面加入对应cdn 看文档都有
})
}
// entry 简写版本
// moudles.export = {
// plugins: [
// new HtmlWebpackExternalsPlugin({
// externals: [{
// module: 'react',
// entry: '//11.url.cn/now/lib/16.2.0/react.min.js',
// global: 'React'
// },
// {
// module: 'react-dom',
// entry: '//11.url.cn/now/lib/16.2.0/react-dom.min.js',
// global: 'ReactDom'
// }
// ]
// })
// ]
// }
~~~
>[warning] ### include/exclude
~~~
1.webpack 中所有的loader 都可以拥有include和exclude属性。
exclude:排除不满足条件的文件夹(这样可以排除webpack查找不必要的文件)
include:需要被loader 处理的文件或文件夹
2.exclude 的优先级高于 include
3.作用不需要再用loader处理而已,打包还是会打包的,比如jQuery,不需要再被babel处理,因为jQuery已经是es5,
浏览器直接可以识别。这个时候,你不设置exclude,jQuery就会被处理,这样就增加了打包时间。所以,设置好
exclude和include可以优化打包时间
{
test: /\.js$/,
exclude: /node_modules/, // include: [path.resolve(__dirname, 'src')]
use: ['babel-loader?cacheDirectory=true']
}
~~~
>[warning] ### noParse
[链接](https://blog.csdn.net/qq_17175013/article/details/86842321)
>[warning] ### Source Map
~~~
1.参考'Source Map' 章节
~~~
>[warning] ### TypeScript 编译优化
~~~
1.Webpack 中编译 TS 有两种方式:使用 ts-loader 或使用 babel-loader
1.1.在使用 ts-loader 时,由于 ts-loader 默认在编译前进行类型检查,因此编译时间往往比较慢,
通过加上配置项 transpileOnly: true可以在编译时忽略类型检查,提高编译速度,但往往关闭后需要
在配合'ForkTsCheckerWebpackPlugin'
1.2. babel-loader 则需要单独安装 @babel/preset-typescript 来支持编译 TS(Babel 7 之前的版本则还是需要
使用 ts-loader)
我这简单试过几次如果'ts-loader' +'ForkTsCheckerWebpackPlugin' 感觉比'@babel/preset-typescript ' 慢,
~~~
>[danger] ##### 使用
~~~
1.注释部分是'ts-loader' +'ForkTsCheckerWebpackPlugin' 用法,没注释的地方是'babel-loader ' 用法,当然还需要
配置预设'@babel/preset-typescript ' 这里不做详细说明了
~~~
~~~
var TSCheckerPlugin = require('fork-ts-checker-webpack-plugin')
module: {
rules: [
{
test: /\.ts$/,
// use: {
// loader: 'ts-loader',
// options: {
// transpileOnly: true,
// },
// },
use: ['babel-loader'], // 使用babel-loader 情况下
},
],
},
plugins: [
// new TSCheckerPlugin({
// typescript: {
// diagnosticOptions: {
// semantic: true,
// syntactic: true,
// },
// },
// }),
],
}
~~~
>[danger] ##### 文章说明
[对比说明](https://segmentfault.com/q/1010000019545436)
>[warning] ### resolve
~~~
1.这个后续再看优化 resolve.modules 配置(减少模块搜索层级)
~~~
>[warning] ### 多进程打包处理 loader资源并行解析
~~~
1.webpack需要处理的文件是非常多的,构建过程是一个涉及大量文件读写的过程。项目复杂起来了,
文件数量变多之后,webpack构建就会特别满,而且运行在nodeJS上的webpack是单线程模型的,
也就是说Webpack一个时刻只能处理一个任务,不能同时处理多个任务。
文件读写和计算操作是无法避免的,那能不能让Webpack在同一时刻处理多个任务发挥多核CPU电脑的功能,
以提升
2.webpack 4.x 使用'thread-loader',小于4.0 可以使用'HappyPack'可以将原有的 webpack 对 loader 的执行过程,
从单一进程的形式扩展为多进程的模式,从而加速代码构建
3.这里要注意如果你是小项目,这里多进程打包反而速度会慢
~~~
[https://segmentfault.com/a/1190000022414110](https://segmentfault.com/a/1190000022414110)
[thread-loader使用](https://www.webpackjs.com/loaders/thread-loader/)
~~~
const threadLoader = require('thread-loader');
const jsWorkerPool = {
// options
// 产生的 worker 的数量,默认是 (cpu 核心数 - 1)
// 当 require('os').cpus() 是 undefined 时,则为 1
workers: 2,
// 闲置时定时删除 worker 进程
// 默认为 500ms
// 可以设置为无穷大, 这样在监视模式(--watch)下可以保持 worker 持续存在
poolTimeout: 2000
};
const cssWorkerPool = {
// 一个 worker 进程中并行执行工作的数量
// 默认为 20
workerParallelJobs: 2,
poolTimeout: 2000
};
threadLoader.warmup(jsWorkerPool, ['babel-loader']);
threadLoader.warmup(cssWorkerPool, ['css-loader', 'postcss-loader']);
module.exports = {
// ...
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'thread-loader',
options: jsWorkerPool
},
'babel-loader'
]
},
{
test: /\.s?css$/,
exclude: /node_modules/,
use: [
'style-loader',
{
loader: 'thread-loader',
options: cssWorkerPool
},
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[name]__[local]--[hash:base64:5]',
importLoaders: 1
}
},
'postcss-loader'
]
}
// ...
]
// ...
}
// ...
}
~~~
* 或者
~~~
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'thread-loader',
options: {
// 产生的 worker 的数量,默认是 cpu 的核心数
workers: 3,
// 一个 worker 进程中并行执行工作的数量
// 默认为 20
workerParallelJobs: 50,
// 额外的 node.js 参数
// workerNodeArgs: ['--max-old-space-size', '1024'],
// 闲置时定时删除 worker 进程
// 默认为 500ms
// 可以设置为无穷大, 这样在监视模式(--watch)下可以保持 worker 持续存在
poolTimeout: 500,
// 池(pool)分配给 worker 的工作数量
// 默认为 200
// 降低这个数值会降低总体的效率,但是会提升工作分布更均一
poolParallelJobs: 200,
// 池(pool)的名称
// 可以修改名称来创建其余选项都一样的池(pool)
// name: "my-pool"
}
},
'babel-loader'
]
}
}
~~~
- 工程化 -- Node
- vscode -- 插件
- vscode -- 代码片段
- 前端学会调试
- 谷歌浏览器调试技巧
- 权限验证
- 包管理工具 -- npm
- 常见的 npm ci 指令
- npm -- npm install安装包
- npm -- package.json
- npm -- 查看包版本信息
- npm - package-lock.json
- npm -- node_modules 层级
- npm -- 依赖包规则
- npm -- install 安装流程
- npx
- npm -- 发布自己的包
- 包管理工具 -- pnpm
- 模拟数据 -- Mock
- 页面渲染
- 渲染分析
- core.js && babel
- core.js -- 到底是什么
- 编译器那些术语
- 词法解析 -- tokenize
- 语法解析 -- ast
- 遍历节点 -- traverser
- 转换阶段、生成阶段略
- babel
- babel -- 初步上手之了解
- babel -- 初步上手之各种配置(preset-env)
- babel -- 初步上手之各种配置@babel/helpers
- babel -- 初步上手之各种配置@babel/runtime
- babel -- 初步上手之各种配置@babel/plugin-transform-runtime
- babel -- 初步上手之各种配置(babel-polyfills )(未来)
- babel -- 初步上手之各种配置 polyfill-service
- babel -- 初步上手之各种配置(@babel/polyfill )(过去式)
- babel -- 总结
- 各种工具
- 前端 -- 工程化
- 了解 -- Yeoman
- 使用 -- Yeoman
- 了解 -- Plop
- node cli -- 开发自己的脚手架工具
- 自动化构建工具
- Gulp
- 模块化打包工具为什么出现
- 模块化打包工具(新) -- webpack
- 简单使用 -- webpack
- 了解配置 -- webpack.config.js
- webpack -- loader 浅解
- loader -- 配置css模块解析
- loader -- 图片和字体(4.x)
- loader -- 图片和字体(5.x)
- loader -- 图片优化loader
- loader -- 配置解析js/ts
- webpack -- plugins 浅解
- eslit
- plugins -- CleanWebpackPlugin(4.x)
- plugins -- CleanWebpackPlugin(5.x)
- plugin -- HtmlWebpackPlugin
- plugin -- DefinePlugin 注入全局成员
- webapck -- 模块解析配置
- webpack -- 文件指纹了解
- webpack -- 开发环境运行构建
- webpack -- 项目环境划分
- 模块化打包工具 -- webpack
- webpack -- 打包文件是个啥
- webpack -- 基础配置项用法
- webpack4.x系列学习
- webpack -- 常见loader加载器
- webpack -- 移动端px转rem处理
- 开发一个自己loader
- webpack -- plugin插件
- webpack -- 文件指纹
- webpack -- 压缩css和html构建
- webpack -- 清里构建包
- webpack -- 复制静态文件
- webpack -- 自定义插件
- wepack -- 关于静态资源内联
- webpack -- source map 对照包
- webpack -- 环境划分构建
- webpack -- 项目构建控制台输出
- webpack -- 项目分析
- webpack -- 编译提速优护体积
- 提速 -- 编译阶段
- webpack -- 项目优化
- webpack -- DefinePlugin 注入全局成员
- webpack -- 代码分割
- webpack -- 页面资源提取
- webpack -- import按需引入
- webpack -- 摇树
- webpack -- 多页面打包
- webpack -- eslint
- webpack -- srr打包后续看
- webpack -- 构建一个自己的配置后续看
- webpack -- 打包组件和基础库
- webpack -- 源码
- webpack -- 启动都做了什么
- webpack -- cli做了什么
- webpack - 5
- 模块化打包工具 -- Rollup
- 工程化搭建代码规范
- 规范化标准--Eslint
- eslint -- 扩展配置
- eslint -- 指令
- eslint -- vscode
- eslint -- 原理
- Prettier -- 格式化代码工具
- EditorConfig -- 编辑器编码风格
- 检查提交代码是否符合检查配置
- 整体流程总结
- 微前端
- single-spa
- 简单上手 -- single-spa
- 快速理解systemjs
- single-sap 不使用systemjs
- monorepo -- 工程
- Vue -- 响应式了解
- Vue2.x -- 源码分析
- 发布订阅和观察者模式
- 简单 -- 了解响应式模型(一)
- 简单 -- 了解响应式模型(二)
- 简单 --了解虚拟DOM(一)
- 简单 --了解虚拟DOM(二)
- 简单 --了解diff算法
- 简单 --了解nextick
- Snabbdom -- 理解虚拟dom和diff算法
- Snabbdom -- h函数
- Snabbdom - Vnode 函数
- Snabbdom -- init 函数
- Snabbdom -- patch 函数
- 手写 -- 虚拟dom渲染
- Vue -- minVue
- vue3.x -- 源码分析
- 分析 -- reactivity
- 好文
- grpc -- 浏览器使用gRPC
- grcp-web -- 案例
- 待续