Webpack笔记
参加字节跳动的青训营时写的笔记。这部分是范文杰老师讲的课。
插一嘴:范文杰老师的公众号Tecvan有很多干活,可以关注一下。(下面的部分有好多都有很有用的扩展链接,偷懒,就直接把老师的公众号贴出来)
1. 简介
Webpack本质上是一种前端资源编译、打包工具。
功能:
- 多份资源文件打包成一个Bundle
- 支持Less、Babel、Eslint、TypeScript
- 支持模块化处理css、图片等资源文件
- 支持HMR(热更新)
- 支持Tree-shaking
- 支持SourceMap
- ,
2. 使用Webpack
2.1 使用步骤
-
安装,
npm install webpack webpack-cli -D
-
编辑配置文件(webpack.config.js)
const path = require('path'); module.exports = { entry: path.join(__dirname, 'src', 'index.js'), mode: 'development', output: { filename: 'bundle.js', path: path.join(__dirname, 'dist') }, }
-
执行编译命令,
npx webpack
2.2 核心流程
- 入口处理:从入口文件开始启动编译流程
-
依赖解析:根据
require
或import
等语句找到依赖资源 -
资源解析:根据
module
配置,调用资源加载器,把css、less、png等非标准JS资源转译成JS内容(Webpack只认识JS) - 资源合并打包:将转译后的资源合并打包为可以直接在浏览器运行的JS文件,包括代码混淆、代码压缩等操作。
递归调用2、3,直到所有资源处理完毕。因为依赖资源可能也会依赖其他资源。
2.3 分类
Webpack的使用基本都围绕配置展开,而配置大致可分为两类:
- 流程类:作用于流程中,直接影响打包效果的配置项
- 工具类:主流程之外,提供更多工程化能力的配置项
2.4 练习
2.4.1 简单使用
模块在上一层。(为了不影响观感)
- 编写代码
-
编辑webpack配置文件
const path = require('path'); module.exports = { entry: path.join(__dirname, 'src', 'index.js'), mode: 'development', output: { filename: 'bundle.js', path: path.join(__dirname, 'dist') }, }
-
执行
npx webpack
2.4.2 处理CSS
按2.4.1的步骤直接执行,会发现出错
原因:Webpack只认识JS,所以需要使用Loader将对应非JS资源转译成JS
-
安装Loader
npm install css-loader style-loader -D
-
添加
module
,使用Loader处理CSS文件const path = require('path'); module.exports = { entry: path.join(__dirname, 'src', 'index.js'), mode: 'development', output: { filename: 'bundle.js', path: path.join(__dirname, 'dist') }, module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] } ] } }
-
执行
npx webpack
,成功2.4.3 使用Babel
Babel用于将使用ES6语法编写的JS代码转换为向后兼容的JavaScript语法,以便能够运行在当前和旧版本的浏览器或其他环境中。
-
安装依赖。
npm install @babel/core @babel/preset-env babel-loader
-
配置。
const path = require('path'); module.exports = { entry: path.join(__dirname, 'src', 'index.js'), mode: 'development', output: { filename: 'bundle.js', path: path.join(__dirname, 'dist') }, module: { rules: [ { test: /\.js$/, use: [{ loader: 'babel-loader', options: { presets: [ [ '@babel/preset-env' ] ] } }] } ] } }
-
npx webpack
源代码:
let add = (a, b) => a + b;
转换后的:
2.4.4 生成HTML
-
安装依赖
npm install html-webpack-plugin -D
-
配置。因为这个不是loader,而是plugin(插件),所以配置需要引入插件,然后在
plugins
中实例化插件const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: path.join(__dirname, 'src', 'index.js'), mode: 'development', output: { filename: 'bundle.js', path: path.join(__dirname, 'dist') }, plugins: [new HtmlWebpackPlugin()] }
-
npx webpack
2.4.5 HMR(热更新)
热更新简单来说就是可以在应用运行的时候,不需要刷新页面,就可以实时查看到修改的效果
-
安装依赖
npm install webpack-dev-server -D
-
开启HMR
- 启动Webpack
npx webpack serve
2.4.6 Tree-Shaking
Tree-shaking:树摇,用于删除Dead Code
Dead Code:
- 代码没有被用到
- 代码只读不写
Dead Code例子:
没有使用Tree-Shaking时:
修改配置文件,开启Tree-Shaking:
结果:
2.5 更多功能
- 缓存
- Sourcemap
- 性能监控
- 日志
- 代码压缩
- 分包
3. Loader
作用:将资源转译成标准JS。(因为Webpack只认识JS)
3.1 Loader使用示例
使用Loader(处理less):
-
安装Loader
npm install style-loader css-loader less-loader -D
-
添加
module
处理const path = require('path'); module.exports = { entry: path.join(__dirname, 'src', 'index.js'), mode: 'development', output: { filename: 'bundle.js', path: path.join(__dirname, 'dist') }, module: { rules: [ { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] } ] }, }
分析:
- less-loader:实现less -> css的转换
- css-loader:将css转换成module.eports = "${css}"的形式,符合JS的语法(直截了当来说的话,就是把css用js表示)
- style-loader:将css模块包进require语句,并在运行时调用injectStyle等函数将内容注入到页面的style标签
3.2 Loader其他特性
- 链式执行(过程的输出刚好是下一个过程的输入)
- 支持异步执行
- 分normal、pitch两种模式(这部分没有什么概念)
3.3 编写简单Loader
3.3.1 Loader形式
module.exports = function(source, sourceMap?, data?) { // ?代表参数可有可无
// source是loader的输入。可能是文件内容或上一个loader处理的结果
// ......
return source; // 此时的source是指经loader处理后的source(不处理则是原来的source,如eslint-loader)
}
3.3.2 开始动手
目录结构
index.js
let t1 = "Hello";
自编简单loader
module.exports = function (source) {
console.log(source);
source += ` let t2 = ' World';
console.log(t1 + t2);`
return source;
}
配置文件
const path = require('path');
module.exports = {
entry: path.join(__dirname, 'src', 'index.js'),
mode: 'production',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.js$/,
use: path.join(__dirname, 'loader', 'myloader.js')
}
]
},
}
3.4 常见Loader
4. Plugin(插件)
使用如2.4.4所示
写插件,暂时无能为力,先把课件上的干货放出来(方便以后查看)
5. 更多
在老师的公众号可能没有的(老师分享的)