什么是 webpack

模块打包器 == 构建工具

  1. 将程序员写完的 源代码 ,加工成浏览器可以:高效、稳定运行的,兼容性较好的代码
  2. webpack 中会将前端的所有资源文件(js/json/css/img/less/…)都作为模块处理
  3. webpack 根据模块的依赖关系进行分析,生成对应的资源

webpack 原理

五个核心概念

  1. 【入口(enter)】
    • 指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始
  2. 【输出(output)】
    • 在哪里输出文件,以及如何命名这些文件
  3. 【Loader】
    • 处理那些非 JavaScript 文件(webpack 自身只能解析 JavaScript和json)
  4. 【插件(plugins)】
    • 执行范围更广的任务,从打包到优化都可以实现
  5. 【模式(mode)】
    • 有生产模式 production 和 开发模式 development

loader 的理解

  1. webpack 本身只能处理 JS、JSON 模块,如果要加载其他类型文件(模块),需要使用对应的 loader
  2. 它本身是一个函数,接受源文件作为参数,返回转换的结果
  3. loader 一般以 xxx-loader 的方式命名, xxx 代表了这个 loader 要做的转换功能,比如 css-loader

plugins 的理解

  • 插件可以完成一些 loader 不能完成的功能

配置文件

  • webpack.config.js:用于存储 webpack 配置信息

配置方式

  1. 初始化项目
    • 使用 npm init 或 yarn init 生成 package.json 文件
  2. 安装 webpack
    • npm i webpack@4 webpack-cli@3 -g //全局安装作为指令使用
    • npm i webpack@4 webpack-cli@3 -D //本地安装作为本地依赖使用

注意事项

  1. webpack 版本和 webpack-cli 版本永远相差一个 webpack@4 版本对应 webpack-cli@3 版本,以此类推
  2. 全局安装之后,最好也局部安装一下,有些错误是因为没有局部安装 webpack 引起的

基础实现

基本配置结构

1
2
3
4
5
6
7
8
module.export = {
mode:"...", //工作模式
enter:"...", //入口文件
output:{...}, //出口文件(输出目录 和 出口文件)
rules:[...], //配置 loader
plugins:[...], //配置插件
devServer:{...} //配置开发服务器
}

通过命令实现

webpack 入口文件路径 -o 输出文件路径 --mode=development

  • –mode
    1. development(开发模式)
    2. production(生产模式)

通过配置实现

  1. 根目录创建 webpack.config.js 文件
    • 该文件是 webpack 的配置文件,所有 webpack 的任务、用到的 loader 、plugins 都要配置在这
    • 该文件要符合 CJS 模块化规范
  2. 文件中引入 Node 中一个内置 path 模块,专门用于解决路径问题
  3. 使用 CJS 模块暴露一个对象,这个对象就是 webpack 的详细配置对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var path = require("path") //引入node中的处理路径的 path 模块

module.exports = {
mode:"development", //工作模式
enter:"./src/js/app.js", //入口文件
/* 完整写法
enter:{
main:"./src/js/app.js"
}
*/
output:{ // 输出文件
path:path.resolve(__dirname,"build"), // 定义所有输出文件的目录:__dirname 当前目录(webpack.config.js 所在目录)下的 “build” 目录
filename:"js/app.js" //定义 出口文件 的路径和名字
publicPath:"/build/" //定义代码中引用资源的路径
}
}

webpack.config.js 配置文件

  1. 这个文件名是可以随意定义的,只不过定义为 webpack.config.js 调用 webpack命令 时,不需要指定配置文件
  2. 指定配置文件调用配置项
    • 如果放在 config 目录下
    • webpack --config ./config/webpack.config.js
  3. 可以为生产环境单独配置一个配置文件,配置 package.json 文件的 scripts 属性定义打包命令
    • scripts:{build:"webpack --config ./config/webpack.pron.js"}
    • 调用:npm run build

loader 配置

  1. npm 安装相关 loader
  2. 配置 webpack.config.js
  • module.exports={...} :暴露 webpack 配置对象
    • module:{...} :模块配置
      • rules:[...] :规则组
        • {...} :规则(多个)
          • test:"/\.css$/" :文件匹配规则
          • exclude:"\.(html|css)" :排除这些其他的文件,与 test 对立
          • use: ["xxx","yyy","zzz"] :loader (loader 调用顺序从后往前)
          • loader:"..." :使用单个 loader,与 use 对立
          • options:{...} :配置 loader 参数

module.rules 中配置一个一个的 规则,每个规则配置需要调用的多个 loader

1
2
3
4
5
6
7
8
9
10
module.exports = {
module:{
rules:[
{
test:"...",
use:["xxx","yyy"]
}
]
}
}

css


css 解析为 js

  1. 入口文件引入 css 文件
    • import "../css/demo.css"
  2. 安装 loader
    1. npm i css-loader -D
    2. npm i style-loader -D
  3. wabpack.config.js 文件配置
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    rules:[
    {
    test:"/\.css$/", //该规则要处理的文件格式
    use:[
    "style-loader", // 创建 style 标签,将引入的样式字符串添加到此 style 标签,将标签插入html页面
    "css-loader" //将css文件变成 commonjs 模块加载到js中,里面内容是字符串

    /*完整写法

    {loader: "style-loader"},
    {loader: "css-loader"}

    */
    ]
    }
    ]

less 解析为 js

  1. 入口文件引入 less 文件
    • import "../css/demo.less"
  2. 安装 loader
    1. npm i css-loader -D
    2. npm i style-loader -D
    3. npm i less-loader -D
    4. npm i less -D // 不是 loader 是代码中使用 less 必要的库
  3. wabpack.config.js 文件配置
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    rules:[
    {
    test:"/\.less$/", //该规则要处理的文件格式
    use:[
    "style-loader", // 创建 style 标签,将引入的样式字符串添加到此 style 标签,将标签插入html页面
    "css-loader", //将css文件变成 commonjs 模块加载到js中,里面内容是字符串
    "less-loader"
    /*完整写法

    {loader: "style-loader"},
    {loader: "css-loader"}
    {loader: "less-loader"}

    */
    ]
    }
    ]

处理 css 兼容

  1. 安装 postcss-loaderpostcss
    • npm i postcss-loader postcss -D
  2. 配置 webpack.config.js
  3. 配置 package.json 添加配置项
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
rules:[
{
test:/\.css$/i,
use:[
"style-loader",
"css-loader",
{
loader:"postcss-loader",
options:{
postcssOptions:{
plugins:[
"postcss-preset-env"
]
}
}
}
]
}
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
"browserslist":[
//开发环境
"development":[
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version",
],
//生产环境:默认是生产环境
"production":[
">0.2%", // 兼容失眠上99.8%
"not dead", // “死去”的浏览器不兼容 如:ie8
"not op_mini all" //不做opera浏览器mini版的兼容
"ie 10" //兼容ie10
]
]

js


js语法检查

  1. 安装 eslint-loadereslint
    • npm i eslint-loader eslint -D
  2. 安装检查库(配置好的规则):eslint-config-airbnb-baseeslint-plugin-import
    • npm i eslint-config-airbnb-base eslint-plugin-import -D
  3. 配置 webpack.config.js
  4. 配置 package.json 添加配置项
1
2
3
4
5
6
7
8
9
10
11
rules:[
{
test:/\.js$/,
exclude:/node_modules/, //排除目录
enforce:"pre", //优先执行
loader:"eslint-loader",
options:{
fix:true //若有问题自动修复
}
}
]
1
2
3
4
5
6
"eslintConfig":{
"extends":"airbinb-base", //直接使用 airbnb-base提供规则
"env":{
"browser":true
}
}

ES6 语法转换

  1. 安装 babel-loader 、***@babel/core@babel/preset-env***
    • npm i babel-loader @babel/core @babel/preset-env -D
  2. 配置 webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
rules:[
{
test:/\.js$/,
exclude:/node_modules/, //排除目录
use:{
loader:"babel-loader",
options:{
presets:["@babel/preset-env"]
}
}
}
]

js 兼容性

  1. 安装 @babel/polyfill
    • npm i @babel/polyfill -D
  2. app.js 中模块引入
    • import "@babel/polyfill"

图片


解析css样式中图片

功能

  1. 指定大小的图片转为base64
  2. 输出图片到指定路径
  3. 指定加工后图片名字

用法

  1. 安装 url-loader
    • npm i url-loader -D
  2. webpack.config.js 配置
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    module:{
    rules:[
    {
    test:"\.(jpg|png|gif)",
    loader:"url-loader",
    options:{
    limit: 8 * 1024, // 小于 8k 的图片会转为 base64
    name:"[hash:10].[ext]", // 加工后的图片名字 hash 值的前10位
    outputPath:"imgs" // 输出路径下的 imgs 中
    }
    }
    ]
    }

解析html中的图片

将文件复制到指定目录

  1. 安装 html-loader
    • npm i html-loader -D
  2. webpack.config.js 配置
    1
    2
    3
    4
    5
    6
    rules:[
    {
    test:"\.html$",
    loader:"html-lader"
    }
    ]

其他资源

将文件复制到指定目录

  1. 安装 file-loader
    • npm i file-loader -D
  2. webpack.config.js 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
rules:[
{
exclude:"\.(html|less|css|png|jpg|bmp|gif|json)", // 除了这些以外的文件
use:[
{
loader:"file-loader", // 配置 loader
potions:{
outputPath:"media", // 输出文件的目录,webpack 基本配置的出口目录中的 media 目录
name:"[hash:5].[ext]" // 文件名 hash 前5个
}
}
]
}
]

plugins 配置

  1. npm 安装相关 plugin 插件
  2. webpack.config.js 文件中 CJS 模块语法引入 plugin 插件模块
    • var xxxPlugin = require(xxx-yyy-plugin)
  3. 配置 webpack.config.js
    • module.exports={...} :暴露 webpack 配置对象
      • plugins:[...] :插件组
        • new xxxPlugin() :实例化插件
          • {…} :实例化时传递配置项

plugins 中配置多个 插件对象

1
2
3
module.exports = {
plugins:[new xxxPlugin({...})]
}

html


生成html文件

  1. 安装 html-webpack-plugin 插件
    • npm i html-webpack-plugin -D
  2. webpack.config.js 引入插件
    • require("html-webpack-plugin")
  3. 插件组配置插件实例
1
2
3
4
5
6
7
8
9
const httpWebpackPlugin = require("html-webpack-plugin")

output:{ // 输出文件
path:path.resolve(__dirname,"build"), // html输出位置由 output 配置项决定
filename:"js/app.js" //定义出口文件的路径和名字
}
plugins:[new httpWebpackPlugin({
template:"./src/html.html" // 依据自定义的html生成新的html文件
})]

css


提取 css 为单文件

  1. 安装 mini-css-extract-plugin
    • npm i mini-css-extract-plugin -D
  2. webpack.config.js 引入插件
    • const MiniCssExtractPlugin = require("mini-css-extract-plugin")
  3. 配置 webpack.config.js
    1. 添加插件实例
    2. 添加插件实例的loader
1
2
3
4
5
6
7
8
const MiniCssExtractPlugin = require("mini-css-extract-plugin")

rules:[MiniCssExtractPlugin.loader], //添加loader
plugins:[
new MiniCssExtractPlugin({ //添加插件实例
filename:"/css/index.css" //配置新建css文件路径和名字
})
]

问题

  1. 如果定义新建css路径,使用 loader 解析的图片可能引用不到
    • 解决:
      • output 配置项中,添加 publicPath 属性
      • 当部署到服务器,项目地址资源目录地址 可能不同,所以部署到服务器时,publicPath 需要配置为 服务器地址

压缩 css 文件

  1. 安装 optimize-css-assets-webpack-plugin
    • npm i optimize-css-assets-webpack-plugin -D
  2. webpack.config.js 引入插件
    • const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin")
  3. webpack.config.js 配置插件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
plugins:[
new OptimizeCssAssetsPlugin({
cssProcessorPluginOptions:{
preset:[
"default",
{
discardComments:{
removeAll:true
}
}
]
}
})
]

webpack-dev-server

作用

  1. webpack 可以配置开发服务器
  2. 更新代码后,会自动刷新渲染页面,不需要执行命令编译
  3. 可以开启热模块更新功能
    • 更新代码之后,只重新渲染修改部分,其他部分保持不变,不会刷新整个页面

特点

运行命令之后,没有进行打包生成本地文件,而是在 内存 创建类似文件,关闭服务器之后将清除内存中创建的文件

用法

  1. 下载 webpack-dev-server
    • 局部安装有时不起作用,也需要进行全局安装
  2. 配置 webpack.config.js 文件
  3. 执行命令
    • webpack-dev-server
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
33
module.export = {
//工作模式
mode:"development",

//入口文件
enter:"./src/js/app.js",
/* 完整写法
enter:{
main:"./src/js/app.js"
}
*/

// 输出文件
output:{
path:path.resolve(__dirname,"build"), // 定义输出文件的目录:__dirname 当前目录(webpack.config.js 所在目录)下的 “build” 目录
filename:"js/app.js" //定义 出口文件 的路径和名字
publicPath:"/build/" //定义代码中引用资源的路径
},

// loader 配置项
rules:[{},{}],

// 插件配置项
plugins:[{},{}]

// webpack 开发服务器
devServer:{
port:5000, //服务器端口
open:true, //自动打开浏览器
hot:true // 热模块更新(热模块替换)
}

}

常用功能

loader

plugins