# 01-Webpack的介绍与安装
# 介绍
Webpack 是一个前端资源打包工具,能将各种js文件、图片、css等打包到一起,这样可以减少浏览器请求次数

举例:
# 安装
先安装node.js(因为Webpack是基于Node.js环境的工具)
用npm对项目进行初始化
先创建一个空文件夹,取个名字(注意:不能用中文,因为webpack在打包时会报错)。用vscode打开该文件夹
打开终端

在命令行内输入下面代码
npm init -y //执行完这行代码后会生成一个package.json文件
安装webpack和webpack-cli(webpack-cli是什么?client 客户、终端。安装了webpack-cli之后,我们就可以在命令行内使用webpack了)
npm i webpack@4 webpack-cli@3 -D // @xxx 表示安装的版本号 // -D (请大家补充到这里)检查是否安装成功
npx webpack -v
# 02-利用webpack进行打包
# 第一步:准备代码
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>webpack</title>
</head>
<body>
<div id="app">
<h1 class="title"></h1>
</div>
</body>
<script>
const $ = function (selector) {
return document.querySelector(selector)
}
$('#app h1').innerText = "Hello, Webpack";
</script>
</html>
分散为多个文件并使用ES6语法

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>webpack</title>
</head>
<body>
<div id="app">
<h1 class="title"></h1>
</div>
</body>
<script src="./index.js"></script>
</html>
// tool.js
const $ = function (selector) {
return document.querySelector(selector)
}
module.exports = {
$: $
}
// index.js
import {
$
} from './js/tool.js';
$('#app h1').innerText = "Hello, Webpack";
再次打开页面后发现报错,原因是浏览器不支持ES6语法。
# 第二步:执行命令进行打包
npx webpack
打包后发现多了一个文件夹dist,里面有一个main.js文件
# 第三步:修改index.html
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>webpack</title>
</head>
<body>
<div id="app">
<h1 class="title"></h1>
</div>
</body>
- <script src="./index.js"></script>
<!--因为打包完后会生成main.js,所以在这里我们要引入打包后的文件:main.js-->
+ <script src="../dist/main.js"></script>
</html>
# 03-打包配置
# 零配置打包
之所以刚才我们只执行一行代码就可以完成打包,原因是webpack从v4.0.0开始,可以不用设置任何配置便可以进行打包
当我们执行npx webpack这个命令时,webpack会先到根目录下找 webpack.config.js 配置文件,如果有就执行该配置文件并进行打包。没有则执行webpack的默认配置,默认配置代码如下:
const {resolve} = require('path')
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
path: resolve('dist'),
filename: 'main.js'
}
}
# 自定义打包
设置配置文件:在项目的根目录下创建一个webpack.pro.config.js文件,这个文件的作用就是对webpack打包进行配置
const {resolve} = require('path') //这是nodejs提供的路径功能模块 module.exports = { mode: 'production', //打包模式,值有:"production"(默认值) | "development" | "none"(一般不用) //production: 生产模式,他会自动启用webpack内部的一些优化措施,例如:代码压缩,混淆...(好处:打包好的文件体积小;坏处:需要消耗较长的时间) //development: 开发模式,不会对代码进行压缩,混淆...(坏处:文件体积相对大点;好处:打包很快) entry: './src/index.js', //入口,告诉webpack从哪个文件开始进行打包 output: { //出口,告诉webpack打包好的文件放到哪里以及文件名称 path: resolve('dist'), //路径,path必须是个绝对路径 filename: 'main.js' //打包好的文件名称 } }打包:在命令行输入下面代码回车
npx webpack --config webpack.pro.config.js
# 04-基础使用总结
- ==webpack-cli是干嘛的?==
- ==npm i webpack@4 中@4是什么意思?== 版本 会安装第4个大版本下最新的版本
- ==npm i webpack@4 -D 中-D是什么意思?==(作业)
- 如何检查是否安装成功? npx webpack -v
- ==自定义打包中我们学了哪几个参数?分别代表什么意思?==(不需要记,只需要看到代码后知道它是什么意思就行)
- ==自定义打包的命令怎么写?==(不需要记,只需要看到代码后知道它是什么意思就行)
# 注意事项:
- 每次改了源代码都需要重新打包一次!!!
- ==路径不能出现中文!!!==
# 05-增强功能-SourceMap
添加了SourceMap之后就会多生成一个叫 ".map" 的文件,它的作用是将打包后的代码和源代码做了一个映射,当代码出错了,它会帮我们定位到源代码出错的位置上。
const {resolve} = require('path')
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
path: resolve('dist'),
filename: 'main.js'
},
+ devtool: "source-map",
}
# 06-loader(css-loader)
# 引入:如何将css文件进行打包?
准备css文件并引入到index.js中:
require('./css/index.css');
打包时报错:
原因:webpack只能处理js和json文件,不能出来别的文件
解决办法:需要loader来帮忙
# loader是什么?
loader是webpack的加载器,是一个总名称。它可以把图片、css、less、sass、字体等转换成js文件,然后webpack就可以处理了
# css-loader
作用:把css文件转成成js文件然后再加载到webpack中
使用步骤:
安装
npm i css-loader -D配置
const {resolve} = require('path') module.exports = { mode: 'production', entry:'./src/index.js', output:{ path: resolve('dist'), filename:'main.js' }, + module:{ // 处理非js模块 + rules:[ // 规则 + { + test: /\.css$/, // 正则测试 + use: [ + { + loader: 'css-loader' // loader + } + ] + } + ] + } }
注意:==只使用css-loader没有任何效果,原因是只处理的css文件,但处理好之后往哪里输出没有设置==
# 07-loader(style-loader、less-loader)
# style-loader
作用:将css代码写到html的style标签里
使用步骤:
安装
npm i style-loader -D配置
module.exports = { module:{ rules:[ { test: /\.css$/, use: [ + {loader: 'style-loader'}, {loader: 'css-loader'} ] } ] } }
# less-loader
作用:将less转换成css
使用步骤:
安装
npm i less less-loader -D补充:这里不光要安装less-loader,还需要安装less。原因:less-loader只是把less文件转换成js模块,只有转换成js模块后才能进行下一步处理。less这个工具才是真正将less转换成css。为什么他俩要分开?因为less-loader是webpack自己的处理器,而less是公共的插件。市面上不光只有webpack,还有别的打包工具也需要less。

配置
module.exports = { module: { rules: [ { - test: /\.css$/, + test: /\.less$/, use: [ {loader: 'style-loader'}, {loader: 'css-loader'}, + {loader: 'less-loader'} ] } ] } }链式配置:
module.exports = {
module: {
rules: [
{
test: /\.less$/,
+ use: ['style-loader','css-loader','less-loader']
}
]
}
}
注意:
- ==use数组中的loader顺序不能颠倒,执行顺序是 从下往上、从右到左==
修改index.js中的代码
- require('./css/index.css'); + require('./css/index.less');
# 08-loader(postcss-loader、autoprefixer插件)
# postcss-loader
作用:
- 把css代码解析成 js 可以操作的 抽象语法树结构(Abstract Syntax Tree,AST)
- 调用插件来处理 AST 并得到结果(eg:添加css3样式前缀、压缩代码等)
使用步骤:
安装
npm i postcss postcss-loader -D配置
module.exports = { module: { rules: [ { test: /\.less$/, use: [ {loader: 'style-loader'}, { loader: 'css-loader', options: { modules: true, } }, + {loader: 'postcss-loader'}, {loader: 'less-loader'} ] } ] } }
注意:postcss-loader只是把css代码解析成AST,所以没有任何效果
# autoprefixer(是插件,不是loader)
作用:添加css3样式前缀(eg:Chrome: -webkit-、IE: -ms-)
使用步骤:
安装
npm i autoprefixer -D配置
module.exports = { module: { rules: [ { test: /\.less$/, use: [ {loader: 'style-loader'}, { loader: 'css-loader', options: { modules: true, } }, { loader: 'postcss-loader', + options: { + postcssOptions: { + plugins: [ + require('autoprefixer')({ + // 市场份额大于1%的浏览器的,最后两个版本 + overrideBrowserslist: ['last 2 versions', '> 1%'] + }) + ], + }, + }, }, {loader: 'less-loader'} ] } ] } }
# 另一种方式:
单独创建postcss的配置文件 postcss.config.js(名字不能错,而且要放在项目的根目录下,否则webpack找不到它)
const autoprefixer = require('autoprefixer')
module.exports = {
plugins:[
autoprefixer({
// 市场份额大于1%的浏览器的,最后两个版本
overrideBrowserslist:['last 2 versions','> 1%']
})
]
}
webpack.pro.config.js配置文件变为:
module.exports = {
module: {
rules: [
{
test: /\.less$/,
use: [
{loader: 'style-loader'},
{
loader: 'css-loader',
options: {
modules: true,
}
},
+ {loader: 'postcss-loader'},
{loader: 'less-loader'}
]
}
]
}
}
# 09-loader(postcss-preset-env插件)
# postcss-preset-env(是插件,不是loader)
作用:将最新的CSS语法转换为目标环境的浏览器能够理解的CSS语法,而且它包含autoprefixer这个插件
使用步骤:
安装依赖
npm i postcss-preset-env -D配置规则
module.exports = { module: { rules: [ { test: /\.less$/, use: [ {loader: 'style-loader'}, { loader: 'css-loader', options: { modules: true, } }, { loader: 'postcss-loader', options: { postcssOptions: { plugins: [ + require('postcss-preset-env')({ + stage: 2, + browsers: ['last 2 versions','> 1%'], + }) ], }, }, }, {loader: 'less-loader'} ] } ] } }
stage共分为5个阶段,分别是:
- stage-0 非官方草案
- stage-1 编辑草案或早期工作草案
- stage-2 工作草案
- stage-3 候选版本
- stage-4 推荐标准
# 10-loader(file-loader、url-loader)
# file-loader
作用:处理字体(图标)等文件
使用步骤:
安装依赖
npm i file-loader -D配置规则
module.exports = { module: { rules: [ + { + test: /\.(woff2?|eot|ttf|svg)$/, + use:{ + loader:'file-loader', + options:{ + // [name] [ext]都是占位符,就是把原来的文件名原样输出 + name:'[name].[ext]', + // 输出的目录 + outputPath: './fonts' + } + } + } ] } }
其实本质就是把字体(图标)等文件复制到另一个文件夹里
# url-loader
作用:处理图片
使用步骤:
安装url-loader
npm i url-loader -D配置规则
module.exports = { module: { rules: [ + { + test: /\.(png|jpe?g|gif|svg)$/, + use: { + loader: 'url-loader', + options:{ + // 小于8k的图片转为base64格式 + limit: 8192, + // 大于8k的图片则输出到下面对应的目录里 + outputPath: './images' + } + } + } ] } }
# ==base64编码的优缺点:==
优点:减少请求次数
缺点:会增大文件的体积,比原来大0.3倍
所以推荐小图片转base64(一般为8K),大图片推荐使用拷贝
#11-loader(babel-loader)
# babel-loader
作用:将最新的JS语法(eg:ES6、ES7)转换为目标环境的浏览器能够理解的JS语法(eg:ES5)
使用步骤:
安装
npm i babel-loader @babel/core @babel/preset-env -D配置
{ test:/\.js$/, // 排除node_modules目录 exclude:/node_modules/, use:[ { loader:'babel-loader', options:{ presets:['@babel/preset-env'] } } ] }
# 12-plugins(html-webpack-plugin、mini-css-extract-plugin、clean-webpack-plugin)
插件的作用:用来扩展 webpack 的功能,增强webpack的魔法能力
# html-webpack-plugin
作用:把我们自己写的.html文件复制到打包目录下,并且自动引入相关资源
使用步骤:
安装
npm i html-webpack-plugin -D配置
+ const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { module: { rules: [] }, + plugins:[ + new HtmlWebpackPlugin({ + template: resolve('./src/index.html'), // 以当前src目录下的index.html为模版 + filename: 'index.html' // 生成的文件名称 + }) + ] }
# mini-css-extract-plugin
作用:把css代码提取到一个单独的css文件中,而不是直接插入到html的style标签中
使用步骤:
安装
npm i mini-css-extract-plugin -D配置
+ const MiniCssExtractPlugin = require('mini-css-extract-plugin') module.exports = { module: { rules: [ { test: /\.less$/, use: [ - {loader: 'style-loader'}, + {loader: MiniCssExtractPlugin.loader} { loader: 'css-loader', options: { modules: true, } }, {loader: 'postcss-loader'}, {loader: 'less-loader'} ] } ] }, plugins:[ + new MiniCssExtractPlugin() ] }
# clean-webpack-plugin
作用:在生成打包文件之前,清空dist目录
使用步骤:
安装
npm i clean-webpack-plugin -D配置
+ const { CleanWebpackPlugin } = require('clean-webpack-plugin') module.exports = { plugins:[ + new CleanWebpackPlugin() ] }
# 12-plugins(webpack-dev-server)
# webpack-dev-server
作用:实现实时打包预览效果
- 当我们修改了代码webpack会自动打包
- 打包完成后会自动刷新浏览器
原理:
==把dist目录打包到内存中(此时我们在磁盘上是看不到dist目录的),然后以dist目录为静态目录,启动本地服务器==
使用步骤:
- 安装
npm i webpack-dev-server -D
先创建一个新的文件webpack.dev.config.js,然后将webpack.pro.config.js代码复制一份给它
修改webpack.dev.config.js的代码
const {resolve} = require('path') module.exports = { - mode: 'production', + mode: 'development', entry: './src/index.js', output: { path: resolve('dist'), filename: 'main.js' }, devtool: "source-map", + devServer: { + host:'localhost', // 主机 + contentBase: './dist', + port: 9090, // 启动服务的端口 + open: true, // 自动打开浏览器 + } }==在package.json的scripts中配置打包快捷命令==
"scripts": { "build": "webpack --config webpack.pro.config.js", "dev": "webpack-dev-server --config webpack.dev.config.js" }==在命令行执行:==
npm run build // 打包上线 或者 npm run dev // 开发阶段
# 13-最后补充与总结
# 工程化开发的优势:

# 今天要掌握的东西
- 每一个loader和插件的作用(看到名字后知道这是干什么的就行)
- 看到最基本的一些配置知道是干什么用的(我画个图)
- 所有要注意的地方(高亮)
- 知道配置代码里的每一条语句是干什么用的(不强制要求)
# 安装所有npm包
npm i webpack@4 webpack-cli@3 style-loader css-loader less less-loader postcss postcss-loader autoprefixer postcss-preset-env file-loader url-loader babel-loader @babel/core @babel/preset-env mini-css-extract-plugin html-webpack-plugin clean-webpack-plugin webpack-dev-server -D
##webpack.dev.config.js
const {
resolve
} = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {
CleanWebpackPlugin
} = require('clean-webpack-plugin')
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: resolve('dist'),
filename: 'main.js'
},
devtool: "source-map",
devServer: {
host: 'localhost', // 主机
contentBase: './dist',
port: 9090, // 启动服务的端口
open: true, // 自动打开浏览器
},
module: {
rules: [{
test: /\.less$/,
use: [{
loader: MiniCssExtractPlugin.loader
},
{
loader: 'css-loader',
options: {
modules: true,
}
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
require('postcss-preset-env')({
stage: 2,
browsers: ['last 2 versions', '> 1%'],
})
],
},
},
},
{
loader: 'less-loader'
}
]
},
{
test: /\.(woff2?|eot|ttf|svg)$/,
use: {
loader: 'file-loader',
options: {
// [name] [ext]都是占位符,就是把原来的文件名原样输出
name: '[name].[ext]',
// 输出的目录
outputPath: './fonts'
}
}
},
{
test: /\.(png|jpe?g|gif|svg)$/,
use: {
loader: 'url-loader',
options: {
// 小于8k的图片转为base64格式
limit: 8192,
// 大于8k的图片则输出到下面对应的目录里
outputPath: './images'
}
}
},
{
test: /\.js$/,
// 排除node_modules目录
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}]
}
]
},
plugins: [
new MiniCssExtractPlugin(),
new HtmlWebpackPlugin({
template: resolve('./src/index.html'), // 以当前src目录下的index.html为模版
filename: 'index.html' // 生成的文件名称
}),
new CleanWebpackPlugin()
]
}
# webpack.pro.config.js
const {
resolve
} = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {
CleanWebpackPlugin
} = require('clean-webpack-plugin')
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
path: resolve('dist'),
filename: 'main.js'
},
devtool: "source-map",
module: {
rules: [{
test: /\.less$/,
use: [{
loader: MiniCssExtractPlugin.loader
},
{
loader: 'css-loader',
options: {
modules: true,
}
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
require('postcss-preset-env')({
stage: 2,
browsers: ['last 2 versions', '> 1%'],
})
],
},
},
},
{
loader: 'less-loader'
}
]
},
{
test: /\.(woff2?|eot|ttf|svg)$/,
use: {
loader: 'file-loader',
options: {
// [name] [ext]都是占位符,就是把原来的文件名原样输出
name: '[name].[ext]',
// 输出的目录
outputPath: './fonts'
}
}
},
{
test: /\.(png|jpe?g|gif|svg)$/,
use: {
loader: 'url-loader',
options: {
// 小于8k的图片转为base64格式
limit: 8192,
// 大于8k的图片则输出到下面对应的目录里
outputPath: './images'
}
}
},
{
test: /\.js$/,
// 排除node_modules目录
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}]
}
]
},
plugins: [
new MiniCssExtractPlugin(),
new HtmlWebpackPlugin({
template: resolve('./src/index.html'), // 以当前src目录下的index.html为模版
filename: 'index.html' // 生成的文件名称
}),
new CleanWebpackPlugin()
]
}