这是我参与「第五届青训营 」伴学笔记创作活动的第 12 天
什么是Webpack
问题
文件管理依赖手动管理:
- 多个JS文件,操作复杂
- 文件代码产生依赖时要严格按照顺序书写
- 开发与生产环境不一致
- 资源管理模型不一致
- 难以接入Less等工具…
工程化工具 => “前端工程”
Webpack
- 本质上是一种前端资源编译、打包工具
- 功能化中枢、工作流中的一个步骤
- 实现模块化和一致性
使用Webpack
步骤
- 安装
npm i -D webpack webpack-cli - 编辑配置文件
webpack.config.js - 执行编译命令
npx webpack
核心流程
entryGet Start入口处理,启动编译流程requireimportDependencies Lookup 依赖解析,找到资源moduleTransform根据module配置进行资源解析,调用资源转移器,将非标准JS资源转译为JS- 依赖和资源解析递归调用,直到所有资源处理完毕
outputCombine Assets 资源合并打包,成为可以直接在浏览器上运行的JS文件
配置
Webpack 的使用方法,基本围绕"配置"展开
- 流程类:作用于流程中的某些环节,直接影响打包效果的配置项
- 工具类:主流程之外,提供更多工程化能力的配置项
例子
Loader处理css文件
npm add -D css-loader style-loader
const path = require('path')
module.exports = {
entry: './src/index.js', // 入口文件(必须)
mode: 'development', // 生产模式
output: { // 输出(必须)
filename: '[name].js',
path: path.join(__dirname, 'dist')
},
module: {
rules: [{ // 用两个loader处理css文件
test: /.css$/,
use: ['style-loader', 'css-loader']
}]
}
}
思考:
- Loader的作用是什么?为什么需要用到css-loader,style-loader
- 这种方式与在HTML中维护css相比,有什么优劣之处?
- 如何在Webpack中接入Less, Sess, Stylus这类css预编译框架?
答:理解Loader
接入Babel
- 将高版本的代码(如ES6)转为低版本代码(ES5)
npm i -D @babel/core @babel/perset-env babel-loader
const path = require('path')
module.exports = {
entry: './src/index.js',
mode: 'development',
output: {
filename: '[name].js',
path: path.join(__dirname, 'dist')
},
module: {
rules: [{
test: /.js$/,
use: [{
loader: 'babel-loader',
options: [
['@babel/preset-env']
]
}]
}]
}
}
生产HTML
npm i -D html-webpack-plugin
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/index.js',
mode: 'development',
output: {
filename: '[name].js',
path: path.join(__dirname, 'dist')
},
plugins: [new HtmlWebpackPlugin] // 插件
}
HMR
- 模块替换Hot Module Replacemant
- 配置项
devServer:{hot:true} - 启动Webpack:
npx webpack serve
Tree-Shaking
- Dead Code
- 没有被用到的代码
- 代码执行结果不会被用到……
- 本质是删除Dead Code
- 对工具类库如Lodash,其能删除很多不必要的工具
module.exports = {
entry: './src/index.js',
mode: 'production', // mode
devtool:false,
output: {
filename: '[name].js',
path: path.join(__dirname, 'dist')
},
optimization: {
usedExports: true
},
}
理解Loader
只做一件事情:内容转换,设计来处理非标准JS资源,用于将这些资源翻译为标准JS
Loader链式调用
- less-loader:实现less=> 转换为css
- css-loader:将css包装为符合JS语法的模块
- style-loader:将css模块包装到require语句内
常见Loader
理解插件
插件是什么?为什么这样设计?
没有插件, 整个项目过于复杂
- 新人需要了解整个流程甚至细节,上手成本高
- 功能迭代成本高,牵一发动全身,可维护性低
- 功能僵化,作为开源项目则缺乏成长性,生命力弱
插件架构的精髓:
- 只实现最核心的功能,只做好主流程
- 思想:对扩展开发,对修改封闭