下面是以 隔行变色 为例,讲解使用 webpack 做开发前端 和 webpack 的各种插件的配置。
通过示例,让大家 了解 webpack 各种配置的含义和使用步骤,不需要大家掌握。 在 实际开发中,只需一键即可生成 webpack 这些配置。
学习前提:
1)新建 change-rows-color 目录,并目录中运行 npm init -y 命令,初始化管理配置文件 package.json
2)新建 src 源代码目录
3)新建 src -> index.html 首页 和 src -> index.js 脚本
4)初始化首面基本的结构
(1)快速 生成 html 页面结构
!
没错,使用一个! 即可快速生成 html 页面结构。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>titletitle>
head>
<body>
body>
html>
(2)编写代码
ul>li{这是第$ 个li}*9
使用快捷键 快速 生成如下代码:
<ul>
<li>这是第1 个lili>
<li>这是第2 个lili>
<li>这是第3 个lili>
<li>这是第4 个lili>
<li>这是第5 个lili>
<li>这是第6 个lili>
<li>这是第7 个lili>
<li>这是第8 个lili>
<li>这是第9 个lili>
ul>
5)运行 npm install jquery -S 命令,安装jQuery
i 是 install 的简写
-S 是 --save 的简写
-D 是 --save-dev 的简写
npm install jquery -S
等价于
npm i jquery -S
等价于
npm install jquery --save
6)通过 ES6 模块化的方式导出jQuery,实现列表隔行变色效果。
在 index.js 中编写如下代码。
// 1. 使用ES6导入语法,导入jquery
import $ from 'jquery'
// 2. 定义;jQuery的入口函数
$(function(){
//3.实现奇偶行变色
$("li:odd").css("background-color", 'red')
$("li:even").css("background-color", 'pink')
})
7) index.html 引入 index.js 脚本,并查看效果
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>indextitle>
<script src="./index.js">script>
head>
<body>
<ul>
<li>这是第1 个lili>
<li>这是第2 个lili>
<li>这是第3 个lili>
<li>这是第4 个lili>
<li>这是第5 个lili>
<li>这是第6 个lili>
<li>这是第7 个lili>
<li>这是第8 个lili>
<li>这是第9 个lili>
ul>
body>
html>
在浏览器中报异常,出现不兼容问题。
使用 webpack 进行打包,解决不兼容问题。
安装webpack 相关的两个包:webpack、 webpack-cli
npm install webpack@5.42.1 webpack-cli@4.7.2 -D
说明:-D 是 --save-dev 的简写 。


说明:
dependencies: 开发、上线部署都会用的插件
devDependencies: 只在开发阶段用到的插件,上线部署不使用。
1)在change-rows-color 项目根目录 创建 webpack.config.js,内容如下。
// 使用node.js 中的导出语法,向外导出一个webpack的配置对象
module.exports={
// mode用来指定构建模式,可选值有 development 和 production
mode:'development'
}
2)在 package.json 的 scripts 中添加 webpack 配置

"scripts": {
"dev":"webpack"
},
说明:
dev 不是固定的,可以是任意字符串。只要确保 npm 脚本名称一致即可。
当是 dev, 则脚本是 npm run dev,当是 abc ,则脚本是 npm run abc,当是 xxx ,则脚本是 npm run xxx。
无论是 dev,还是 abc、xxx ,都只是一个代号,最终执行的是对应的值,即 webpack 。
webpack 是固定值,不可以变动。
运行 npm run dev ,启动 webpack 进行项目的打包构建

说明:使用 npm run dev , 也可以使用 npm run abc 、 npm run xxx 等,与上一步骤参数有关。
脚本执行后,生成 dist 目录和 main.js 文件。如下所示。

1) 修改引用的脚本
将 index.html 中的脚本由 index.js 改为 main.js
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>indextitle>
<script src="../dist/main.js">script>
head>
<body>
<ul>
<li>这是第1 个lili>
<li>这是第2 个lili>
<li>这是第3 个lili>
<li>这是第4 个lili>
<li>这是第5 个lili>
<li>这是第6 个lili>
<li>这是第7 个lili>
<li>这是第8 个lili>
<li>这是第9 个lili>
ul>
body>
html>
2)浏览

在 webpack.config.js 中, mode:'development' 时,执行 npm run dev , 生成的 main.js是 324kb,耗时564ms。

webpack.config.js 中 mode:'production' 时,执行 npm run dev , 生成的 main.js是 88.3kb,耗时2799ms。

开发时,一定要使用 development 模式,节省时间。
上线,部署时,使用 production , main.js 要进行压缩,耗时更长。

webpack.config.js 配置如下:
// 使用node.js 中的导出语法,向外导出一个webpack的配置对象
const path = require('path')
module.exports={
// mode用来指定构建模式,可选值有 development 和 production
mode:'development' ,
// 更改打包入口
entry: path.join(__dirname,'./src/index1.js'),
// 更改打包输入目录和文件名
output:{
path: path.join(__dirname,'dist2'),
filename: 'bundle.js'
}
}
npm install webpack-dev-server@3.11.2 -D
"scripts": {
"dev": "webpack serve"
},
再次运行 npm run dev, 重新进行项目的打包
在浏览器中访问 http://localhost:8080, 查看自动打包效果。
webpack-dev-server 会启动一个 实时打包的http 服务器

npm run dev 出现异常> change-rows-color@1.0.0 dev
> webpack serve
[webpack-cli] Unable to load '@webpack-cli/serve' command
[webpack-cli] TypeError: options.forEach is not a function
at WebpackCLI.makeCommand (H:\space\change-rows-color\node_modules\webpack-cli\lib\webpack-cli.js:173:21)
at ServeCommand.apply (H:\space\change-rows-color\node_modules\@webpack-cli\serve\lib\index.js:41:19)
at loadCommandByName (H:\space\change-rows-color\node_modules\webpack-cli\lib\webpack-cli.js:907:35)
at async Command. (H:\space\change-rows-color\node_modules\webpack-cli\lib\webpack-cli.js:1462:17)
at async Promise.all (index 0)
at async WebpackCLI.run (H:\space\change-rows-color\node_modules\webpack-cli\lib\webpack-cli.js:1500:9)
at async runCLI (H:\space\change-rows-color\node_modules\webpack-cli\lib\bootstrap.js:11:9)

解决方法
无法加载“@webpack cli/service”命令,未下载@webpack cli/service,则下载webpack cli 。
执行下面的 webpack cli 安装命令:
npm i webpack-cli -D
说明:
i 是install 的简写。-D 是 --save-dev 的简写,安装包写入 devDependencies(开发环境)。运行 npm run dev 后,每当代码修复后,会自动进行项目的打包。打包日志如下。

这里发现个问题:修复 index.js后,虽然进行的打包,但是页面未变化。
原因是 打包生成的 main.js 在根目录的内存中,并没有保存到 dist/main.js 。
webpack-dev-server 生成的 main.js 在项目的根目录,并且在内存中,磁盘中无法使用,所以看不到。
可以通过 http://127.0.0.1/main.js 能访问到。
inde.html 中对 main.js 的引用
<script src="/main.js">script>
devServer 节点对 webpack-dev-server 插件进行更多的配置。
webpack.config.js 配置:
....(无关的内容省略)
module.exports={
mode:'development',
plugins:[htmlPlugin] ,
devServer:{
open: true, // 初次打包后,自动打开浏览器
host:'127.0.0.1', // 实时打包使用的主机地址
port:80, // 实时打包所使用的端口号
}
}
注意:凡是修改 webpack.config.js 配置,或修改了 package.json 配置文件,必须重启实时打包服务,配置才能生效。
安装命令:
npm i html-webpack-plugin@5.3.2 -D
webpack.config.js 配置:
const path = require('path')
// 1、导入html插件
const HtmlPlugin = require('html-webpack-plugin')
// 2、创建html插件的实例对象
const htmlPlugin = new HtmlPlugin({
template:'./src/index.html', // 指定原文件的存放路径
filename:'./index.html', // 指定生成的文件的存放路径
})
module.exports={
mode:'development',
plugins:[htmlPlugin] , // 3、通过plugins 节点,使htmlPlugin插件生效
}
html-webpack-plugin 有两个功能:
复制页面
注入脚本
style-loader 用于 打包处理 css 文件。
npm i style-loader@3.0.0 css-loader@5.2.6 -D
在 webpack.config.js 的 module -> rules 数组中
module :{
rules:[
{ test:/\.css$/ ,use:['style-loader','css-loader'] }
]
}
说明,test 表示匹配的文件类型, use 表示对应要调用的 loader
use 数组 中指定的 loader 顺序是固定的。
多个 loader 的调用顺序是:从后往前 调用。
创建文件 src\css\index.css ,内容如下:
li{
list-style:decimal-leading-zero;
}
index.js 内容:
import './css/index.css'
重新执行命令:
npm run dev

less 、less-loader 用于 打包处理 less 文件。
npm i less-loader@10.0.1 less@4.1.1 -D
在 webpack.config.js 的 module -> rules 数组中
module :{
rules:[
{ test:/\.less/ ,use:['style-loader','css-loader','less-loader'] }
]
}
创建文件 src\css\index.less,内容如下:
html,
body,
ul{
margin: 0;
padding: 1;
li{
line-height: 30px;
padding-left: 20px;
font-size: 12px;
}
}
index.js 内容:
import './css/index.less'
重新执行命令:
npm run dev

url 路径相关 的文件url-loader、file-loader 用于 打包处理样式表中与 url 路径相关 的文件
npm i url-loader@4.1.1 file-loader@6.2.0 -D
在 webpack.config.js 的 module -> rules 数组中
module :{
rules:[
{ test:/\.jpg|png|gif$/ ,use:['url-loader?limit=22229'] }
]
}
其中 ? 之后的是 loader 的参数项 :
limit 用来指定图片的大小,单位是字节(byte) 。limit 的值是自定义的,22229是随边写的。
当图片的大小 ≤ limit 的值时,会被转为 base64 格式的图片。
创建 src下的 images目录,里面有 baidu.png 图片。
index.html 内容:
index.js 内容:
// 1. 导入图片
import baidu from './images/baidu.png'
// 2. 给img标签的src动态赋值
$('.box').attr('src',baidu)

webpack 只能打包处理一部分高级的 JavaScript 语法。对于那些 webpack 无法处理的高级 js 语法,需要借助于 babel-loader 进行打包处理。
babel 官网上相关配置说明: https://babeljs.io/docs/en/babel-plugin-proposal-decorators
例如 webpack 无法处理下面的 JavaScript 代码
// 1. 定义名为info的装饰器
function info(target){
// 2. 为目标添加静态属性info
target.info='Person info'
}
// 3. 为Person类应用info装饰器
@info
class Person{}
// 4. 打印Person的静态属性info
console.log(Person.info)
安装
npm i babel-loader@8.2.2 @babel/core@7.14.6 @babel/plugin-proposal-decorators@7.14.5 -D
1)在 webpack.config.js 的 module -> rules 数组中
module :{
rules:[
{ test:/\.js$/ ,use:'babel-loader', exclude:/node_modules/ }
]
}
2)在项目根目录下,创建名为 babel.config.js 的配置文件,定义 Babel 的配置项如下:
module.exports={
plugins:[['@babel/plugin-proposal-decorators',{legacy:true}]],
}
项目开发完成之后,需要使用 webpack 对项目进行打包发布,主要原因有以下两点:
① 开发环境下,打包生成的文件存放于内存中,无法获取到最终打包生成的文件
② 开发环境下,打包生成的文件不会进行代码压缩和性能优化
为了让项目能够在生产环境中高性能的运行,因此需要对项目进行打包发布
在 package.json 文件的 scripts 节点下,新增 build 命令如下
"scripts": {
"dev": "webpack serve",
"build":"webpack --mode production"
}
--model 是一个参数项,用来指定 webpack 的运行模式。production 代表生产环境,会对打包生成的文件进行代码压缩和性能优化。
注意: 通过 --model 指定的参数项,会覆盖 webpack.config.js 中的 model 选项。
在 webpack.config.js 配置文件的 output 节点中,进行如下的配置:
output:{
path:path.join(__dirname,'dist'),
filename:'js/bundle.js',
},
修改 webpack.config.js 中的 url-loader 配置项,新增 outputPath 选项即可指定图片文件的输出路径。
在 module.exports -> module ->rules ,
// 1. 将原来的 url-loader 配置中增加 outputPath 参数
{ test:/\.jpg|png|gif$/ ,use:['url-loader?limit=29&outputPath=images'] },
或者,如下配置:
{
test:/\.jpg|png|gif$/,
use: {
loader: 'url-loader',
options:{
limit: 28,
outputPath:'images'
}
}
},
为了在每次打包发布时自动清理掉 dist 目录中的 旧文件,可以安装并配置 clean-webpack-plugin 插件
clean-webpack-plugin 插件npm install clean-webpack-plugin@3.0.0 -D
在 webpack.config.js ,配置如下:
// 得到插件,创建插件实例对象
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const cleanPlugin = new CleanWebpackPlugin()
// 把创建的插件对象cleanPlugin,挂载到 plugins 节点下
module.exports={
plugins:[cleanPlugin],
}
npm run build

前端项目在投入生产环境之前,都需要对 JavaScript 源代码进行压缩混淆,从而减小文件的体积,提高文件的加载效率。此时就不可避免的产生了另一个问题:
对压缩混淆之后的代码除错(debug)是一件极其困难的事情。
Source Map 就是一个信息文件,里面储存着位置信息。也就是说,Source Map 文件中存储着压缩混淆后的
代码,所对应的转换前的位置。
有了它,出错的时候,除错工具将直接显示原始代码,而不是转换后的代码,能够极大的方便后期的调试。
推荐在 webpack.config.js 中添加如下的配置,即可保证 运行时报错的行数与源代码的行数 保持一致。
保持一致。
module.exports={
// ... 省略其它配置项
devtool:'eval-source-map',
// ... 省略其它配置项
}
在生产环境下,建议关闭 Source Map 或将 devtool 的值设置为 nosources-source-map ,好处是 防止源码泄露,提高网站的安全性。
module.exports={
// ... 省略其它配置项
devtool:'nosources-source-map',
// ... 省略其它配置项
}
答案:不需要!
resolve:{
alias:{
// 告诉webapck,@符号表示src这一层目录
'@':path.join(__dirname,'./src/')
}
}
安装、webpack.config.js、修改打包入口
webpack-dev-server、html-webpack-plugin
loader 的作用、loader 的调用过程
精准定位到错误行并显示对应的源码
方便开发者调试源码中的错误