webpack是什么
webpack是一个项目构建工具、它可以把你一些组织互相依赖的代码、按类别去帮你打包成一个整体唯一的文件、在打包中通过loader去处理webpack不认识的文件、在打包构建流程中抛出不同时期的生命周期钩子通知plugin、也可以在打包中往代码里面注入不同的环境变量、对代码的压缩配合其他插件(babel) 对源代码进行编译、编译成通用浏览器的语法、也可以在plugin里面对输出文件内容的做增删除、最重要的是这一系列的流程你并不需要写太多代码、你只需通过一个配置文件去定义你的打包规则、相对来说比较简单就能配置出一个基础环境!
webpack特点
- 自身功能齐全、插件系统完善支持自定义loader和plugin、定制化强、扩展性强、面对复杂场景也是游刃有余、社区生态完整、业界应用工程化首选!
搭建一个简单的webpakc环境
安装webpack依赖
// 初始化package.json
yarn init
// 安装webpack
yarn add webpack webpack-cli -D
// 在package.json里面配置打包命令
"scripts": {
"build":"webpack --config webpack.config.js"
}
创建webpack.config.js(打包配置文件)
```javascript // 根节点创建webpack.config.js const path = require(‘path’);
module.exports = { // 入口文件 entry: { ‘main’:’./src/main.js’, }, // 此选项控制是否生成,以及如何生成 source map。 devtool: ‘inline-source-map’, // 模式-环境 mode: ‘development’, module:{ // 模块配置相关(配置 loader、解析器等选项) rules:[
]
},
// 插件使用
plugins: [],
// 输出规则
output: {
// 输出的文件名、[name] 来自打包的名称
filename: '[name].bundle.js',
// 输出的位置
path: path.resolve(__dirname, 'dist'),
// 在生成文件之前清空 output 目录
clean: true
}
};
> 创建一个src->main.js、然后在src下在创建一个test1.js 和test2.js、然后开始随便写点内容、下方的图就是依赖关系

<a name="wXcSD"></a>
#### 执行yarn build 开始打包
> 打包后我们在根节点创建一个public文件夹、并且里面创建一个index.html引入dist里面的js文件,然后在浏览器打开、我们发现里面输出了我们打包文件的内容信息、这样我们就完成了一个简单的打包!下面我们开始配置一些常用的loader和插件
<a name="vh3r3"></a>
#### 常用loader和plugin
<a name="IqXhZ"></a>
##### loader
- **style-loader、css-loader **
```javascript
// 安装
yarn add style-loader css-loader -D
// webpack.config.js使用
module: {
// 模块配置相关(配置 loader、解析器等选项)
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
]
}
// 使用
import "./style/common.css"
- file-loader、raw-loader、url-loader ```javascript // 安装 yarn add file-laoder
// webpack.config.js使用 module.exports = { module: { // 模块配置相关(配置 loader、解析器等选项) rules: [ { test: /.(png|jpe?g|gif)$/i, use: [ { loader: ‘file-loader’ } ] } ] } }
// 使用 import icon from “./assets/icon02.png”
- **babel-loader** ( 将高级语法转义成低版本浏览器也能认识的插件)
```javascript
// 安装
babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime -D
// webpack.config.js使用
module.exports = {
module: {
// 模块配置相关(配置 loader、解析器等选项)
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: ['@babel/plugin-transform-runtime']
}
}
}
]
}
}
// 使用
// test1.js
export const fn = async () =>{
const res = await asyncTest()
console.log('function',res)
}
function asyncTest(){
return new Promise( resolve =>{
setTimeout( () =>{
resolve(1111)
},2000)
})
}
// main.js
import { fn } from "./test1.js"
const mains = "main.js"
console.log(test1)
fn()
plugin
- UglifyJsPlugin 压缩和混淆代码 ```javascript // 安装 yarn add uglifyjs-webpack-plugin -D
// webpack.config.js使用 const UglifyJsPlugin = require(‘uglifyjs-webpack-plugin’); module.exports = { optimization: { minimizer: [ new UglifyJsPlugin({ cache: true, parallel: true }) ] } }
- **html-webpack-plugin **自动生成html、并引用打包后的js
```javascript
// 安装
yarn add html-webpack-plugin -D
// webpack.config.js使用
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
plugins: [
new HtmlWebpackPlugin()
]
}
- webpack-bundle-analyzer 打包分析插件、可以分析你的打包内容所消耗的时间、根据各种维度去分析进行优化打包速度 ```javascript // 安装 yarn add webpack-bundle-analyzer -D
// webpack.config.js使用 const BundleAnalyzerPlugin = require(‘webpack-bundle-analyzer’).BundleAnalyzerPlugin; module.exports = { plugins: [ new BundleAnalyzerPlugin() ] }
// 执行build后会自动打开分析的html文件

- **optimize-css-assets-webpack-plugin** 不同组件中重复的css可以快速去重
- **happypack** 通过多进程模型,来加速代码构建
<a name="dkGrk"></a>
### 贴上整体基础配置文件
```javascript
const path = require('path');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
// 入口文件
entry: {
'main': './src/main.js',
},
// 此选项控制是否生成,以及如何生成 source map。
devtool: 'inline-source-map',
// 模式-环境
mode: 'development',
module: {
// 模块配置相关(配置 loader、解析器等选项)
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
}
]
},
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: ['@babel/plugin-transform-runtime']
}
}
}
]
},
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true
})
],
splitChunks: {
// 抽离入口文件公共模块为commmons模块
cacheGroups: {
commons: {
name: "commons",
chunks: "initial",
minChunks: 2
}
}
}
},
// 插件使用
plugins: [
new HtmlWebpackPlugin(),
new BundleAnalyzerPlugin()
],
// 输出规则
output: {
// 输出的文件名、[name] 来自打包的名称
filename: '[name].bundle.js',
// 输出的位置
path: path.resolve(__dirname, 'dist'),
// 在生成文件之前清空 output 目录
clean: true
}
};
webpack构建流程
我们在学习了webpack基础打包配置后、现在我们还需要学习下webpack构建的整个流程是什么样的、了解其基本的构建过程有助于我们更熟悉webpack、今后使用webpack更能知道那个环节可以优化和排查问题! 下面贴一张网上找的图片、个人觉得写的很清晰!可以先看图了解下整个过程!
一、合并参数
启动打包后、webpack会把默认配置和用户自定义的配置( webpack.config.js ) 进行参数配置合并、得到最终的options对象给到下一个流程!!
二、实例化Compiler和订阅生命周期
合并完配置对象后、准备初始化compiler对象、该对象是继承至Tapabel、给所有的插件注册生命周期的订阅、然后执行run方法开始执行编译!
三、parser分析项目依赖
找到入口文件、开始分析文件构建AST树、找出依赖递归下去处理、依赖递归根据文件类型去命中相对应的loader配置、调用配置中的所有loader对文件进行transformation
四、输出文件
递归完所有的依赖后、就能拿到每个文件结果、根据entry的配置或者分包配置生成对应的chunk文件
本篇package.json版本
{
"name": "webpack-cli-test",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"build": "webpack --config webpack.config.js"
},
"devDependencies": {
"@babel/core": "^7.17.8",
"@babel/plugin-transform-runtime": "^7.17.0",
"@babel/preset-env": "^7.16.11",
"babel-loader": "^8.2.4",
"css-loader": "^6.7.1",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.0",
"style-loader": "^3.3.1",
"uglifyjs-webpack-plugin": "^2.2.0",
"webpack": "^5.71.0",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.9.2"
}
}