郁郁青青 长过千寻

Webpack 和 Babel


    1. webpack
    2. babel
    3. ほしのかけら
    4. 一种常规执行步骤の记录
    5. 小册实践路径记录
    6. 主题博文

webpack

修改服务器的根目录展示路径:修改 publickPath,例如这里我要访问www.demo.com/resume/xxx,项目在路径resume文件夹里,就这样配置,

1
2
3
4
5
output: {
filename: '[name].[contentHash:8].js',
path: distPath,
publicPath: '/resume'
},

練習問題:构建和打包的原因;module, chunk, bundle 的含义;loader 和 plugin 的区别;webpack 实现懒加载的方法;常见性能优化;babel-runtime, babel-polyfill 的区别。

webpack-merge:组合多个 webpack 配置文件,例如组合公共配置文件 webpack.common.js,https://www.npmjs.com/package/webpack-merge。

DefinePlugin:https://www.webpackjs.com/plugins/define-plugin/。

webpack-dev-server:开发环境中配置,常用属性有 port 服务端口、progress 打包进度条开关、contentBase 根目录、open 自动打开浏览器开关、compress 启动 gzip 压缩开关、proxy 设置代理(跨域请求)。

CleanWebpackPlugin:清空 output.path 文件夹,生产环境配置中使用。

抽离压缩 CSS:mini-css-extract-plugin,使用该插件提供的 MiniCssExtractPlugin.loader 替换 style-loader,避免生产环境直接将样式用脚本动态插入标签,然后在 plugins 中执行抽离new MiniCssExtractPlugin({ filename: 'css/main.[contentHash:8].css' });terser-webpack-plugin 和 optimize-css-assets-webpack 压缩 CSS,在optimization:{ minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})], }

抽离公共代码:避免同样的代码编码在多个文件中,而抽离公共代码引入,例如引入体积较大的库的时候,如果不抽离,即使修改很少的业务代码也将导致哈希值变更会引起整个文件的重新加载。

懒加载:setTimeout(() => {import('xxx').then(res => { xxxxxx })}, 5700);结合 React-router 异步加载路由。

定义 chunk 的地方:entry, optimization.splitChunks.cacheGroups, 懒加载。


构建速度进行优化的关键点:babel-loader, happyPack, IgnorePlugin, ParallelUglifyPlugin, noParse, 自动刷新, 热更新, DllPlugin。

babel-loader:性能消耗较多的地方,使用缓存确定范围来提升速度;module: {rules: [{ test: /\.js$/, use: ['babel-loader?cacheDirectory'], include: path.resolve(__dirname, 'src'), exclude: path.resolve(__dirname, 'node_modules') }], }

IgnorePlugin:默认引入将引入模块中所有 js 代码,当只需要其中一部分时就使用 IgnorePlugin 忽略模块动态引入我们需要的一部分;忽略new webpack.IgnorePlugin(xx, xxx),动态引入import 'xxxx'

noParse:对于已经模块化处理过的模块,形如xxx.min.js这样的模块则忽略;module: { noParse: [/xxx\.min\.js$/], }

happyPack:开启多进程打包。

ParallelUglifyPlugin:多进程压缩 js。

热更新 HMR:热更新后网页不刷新、状态不丢失,和自动刷新不同;HotModuleReplacementPlugin;热更新需要注册监听范围。

DLLPlugin:。


优化产出代码的关键点:小图片 base64;bundle 加哈希;懒加载;提取公共代码;IgnorePlugin;CDN 加速;使用 production;Scope Hosting。

使用 production:自动开启代码压缩;React 等会自动删掉调试代码;启动 Tree-Shaking(ES6 Module 生效 tree-shaking,commonjs 不行);

ES6 Module 和 Commonjs 的区别:静态引入、编译时引入和动态引入、执行时引入的区别。

Scope Hosting:代码体积更小;创建函数作用域更少;代码更可读;

1
2
3
4
5
6
7
8
9
const ModuleConcatenationPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin')
module.export = {
resolve: {
mainFields: ['jsnext:main', 'browser', 'main']
},
plugin: [
new ModuleConcatenationPlugin(),
]
} // 。

打包构建的好处:体积更小(Tree-Shaking、压缩、合并),加载更快;编译高级语言或语法(TS、ES6、模块化、scss);兼容性和错误检查(Polyfill、postcss、eslint);同一、高效的开发环境,统一的构建流程和产出标准,集成公司构建规范(体测、上线等)。

Proxy 无法被模拟。

webpack 优化构建速度(prod):优化 babel-loader;IgnorePlugin;noParse;happyPack;ParallelUglifyPlugin。

webpack 优化构建速度(dev):自动刷新;热更新;DllPlugin。

webpack 优化产出代码:小图片 base64;提取公共代码;bundle 加 hash;使用 CDN 加速;懒加载;IgnorePlugin;使用 production;Scope Hosting。

babel

解析 ES6 或更高级的语法满足浏览器兼容性。babel 只处理语法,webpack 处理模块化。

babel-polyfill:是 core-js 和 regenerator 的集合,前者没有 generator 语法支持,后者补充;v7.4 已被弃用,推荐直接使用 babel-polyfill。

babel-polyfill 按需引入:在只用了一部分功能时按需引入;按需引入的时候无需在文件顶部加 import ‘@babel/polyfill’;下面是 .babelrc 文件按需引入的配置

1
2
3
4
5
6
7
8
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": 3
}]], "plugins": []}

babel-runtime:安装 @babel/plugin-transform-runtime(- D) 和 @babel/runtime;进行 .babelrc 配置,下面是配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"presets": [...],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"absoluteRuntime": false,
"corejs": 3,
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]
}

;避免了污染全局环境,利于开发第三方库。

为什么配置文件的结尾是 rc:https://www.cnblogs.com/MYSQLZOUQI/p/5186952.html。

ほしのかけら

Webpack 4 配置最佳实践:https://zhuanlan.zhihu.com/p/38456425。

试题,用 Webpack 实现 predictable long term cache:https://github.com/LeetCode-OpenSource/hire/blob/master/webpack_zh.md。

loader 的执行顺序:后 → 前。

关键词:css 浏览器兼容加前缀,postcss-loader,autoprefixer。

赋值源码路径和输出路径:const { srcPath, distPath } = require('./paths')

一种常规执行步骤の记录

1
2
3
4
5
6
. 新建文件夹 webpack-demo
. node -v
. npm init -y
// 初始化 npm 环境,webpack-demo 文件里出现 package.json 文件(当前目录描述文件)
. npm install webpack webpack-cli -D
. 新建 src 文件夹,src 下新建 index.js,根目录下新建 webpack.config.js 文件
1
2
3
4
5
6
7
8
9
10
// webpack.config.js
const path = require('path') // 引用 nodejs 的 path 模块
module.exports = {
mode: 'development', // production
entry: path.join(__dirname, 'src', 'index.js'), // path 模块,寻找当前文件目录的模块,这里的 index.js 是整个文件的入口
output: { //
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
}
}
1
2
3
4
5
6
7
8
9
10
11
. 修改 package.json 文件,给属性 scripts 对象添加属性 build 属性
// "build": "webpack --config webpack.config.js"
. npm run build
// 根目录自动生成 dist 文件夹,并包含 bundle.js 文件
. 新建 index.html 文件
. npm install html-webpack-plugin -D
// 解析 html 的插件
. npm install webpack-dev-server -D
// 启动服务的插件
// package.json 文件里的 属性 devDependencies 对象生成属性 html-webpack-plugin 和 webpack-dev-server
. 修改 webpack.config.js 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// webpack.config.js
const path = require('path') // 引用 nodejs 的 path 模块
const HtmlWebpackplugin = require('html-webpack-plugin')
module.exports = {
mode: 'development', // production
entry: path.join(__dirname, 'src', 'index.js'), // path 模块,寻找当前文件目录的模块,这里的 index.js 是整个文件的入口
output: { //
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
},
plugins: [
new HtmlWebpackplugin({
template: path.join(__dirname, 'src', 'index.html'), // 模板
filename: 'index.html' // 产出的文件名,在 dist 文件夹内
})
],
devServer: {
port: 3000,
contentBase: path.join(__dirname, 'dist') // 当前目录
}
}
1
2
3
. 修改 package.json,给属性 scripts 对象添加属性 dev 属性
// "dev": "webpack-dev-server --config webpack.config.js"
. npm run dev
1
2
3
4
. npm install @babel/core @babel/preset-env babel-loader -D
// evn 是 babel 的配置集合,@ 是一个组,/ 是一个模块,babel-loader 是给 webpack 的插件
// package.json 文件里的 属性 devDependencies 对象生成属性 @babel/core, @babel/preset-env, babel-loader
. 根目录下新建 .babelrc 文件,并修改
1
2
3
4
// .babelrc
{
"presets": ["@babel/preset-env"] // babel 的配置
}
1
. 修改 webpack.config.js,做 module 配置,针对不同模块做不同解析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// webpack.config.js
const path = require('path') // 引用 nodejs 的 path 模块
const HtmlWebpackplugin = require('html-webpack-plugin')
module.exports = {
mode: 'development', // production
entry: path.join(__dirname, 'src', 'index.js'), // path 模块,寻找当前文件目录的模块,这里的 index.js 是整个文件的入口
output: { //
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
},
module: { // 针对不同模块做不同解析
rules: [
{
test: /\.js$/, // .js 结尾的
loader: ['babel-loader'], // 走 loader
include: path.join(__dirname, 'src'), // 包含哪些目录需要走 loader
exclude: /node_modules/ // 第三方插件没必要转译

}
]
},
plugins: [
new HtmlWebpackplugin({
template: path.join(__dirname, 'src', 'index.html'), // 模板
filename: 'index.html' // 产出的文件名,在 dist 文件夹内
})
],
devServer: {
port: 3000,
contentBase: path.join(__dirname, 'dist') // 当前目录
}
}
1
2
3
4
5
6
7
// 配置生产环境
. 新建文件 webpack.prod.js
. 修改文件 webpack.prod.js
// 拷贝文件 webpack.config.js 内容给 webpack.prod.js,属性 mode 值改为 production,删除属性 devServer,output.filename 值改为 bundle.[contenthash].js
. 修改文件 package.json
// 属性 scripts.build 值改为 webpack --config webpack.prod.js
. npm run build

小册实践路径记录

1
2
3
4
5
6
7
8
9
10
11
mkdir my-project && cd my-project
npm init
npm install webpack webpack-cli -D
# webpack-cli 不再作为 4.x 版本之后的 webpack 的依赖,因此单独安装
# npx webpack 运行项目内安装的 webpack
# npx webpack --help 查看 webpack-cli 提供的可用命令
# npx webpack --version 查看 webpack 的安装版本
npm install webpack-dev-server -D
npm install html-webpack-plugin -D
npm install --save-dev style-loader css-loader
# npm install file-loader --save-dev

主题博文

入门Webpack,看这篇就够了 https://www.jianshu.com/p/42e11515c10f

页阅读量:  ・  站访问量:  ・  站访客数: