webpack 的基本使用
- 配置 npm 镜像源
- 创建列表隔行变色案例
- 新建空白项目目录,初始化 package.json 配置文件
- 通过 npm 安装 jquery
- 新建 src 源代码目录
- index.html
- index.js
- 检查网页效果
- webpack 的安装
- webpack 的安装
- dependencies 与 devDependencies
- 参数 -S 及 --save
- 参数 -D 及 --save-dev
- dependencies 与 devDependencies
- 使用 -S 还是 -D
- webpack 的配置
- webpack 配置文件
- package.json 的 script 节点
- webpack 的使用
- 开发模式与发布模式
- 指定 webpack 的 entry 及 output
- 举个栗子
- webpack 实现页面自动刷新
- 安装所需插件
- 配置 webpack-dev-server
- 细节
- html-webpack-plugin
- html-webpack-plugin 的另一个功能
- devServer 节点
配置 npm 镜像源
npm 默认使用的是国外的源对软件包进行安装,我们可以通过将网页链接修改为国内镜像源提升软件包的安装速度。
使用如下修改 npm 镜像源(淘宝镜像源):
npm config set registry https://registry.npm.taobao.org
使用如下命令观察 npm 程序目前所使用的镜像源:
npm config get registry
创建列表隔行变色案例
新建空白项目目录,初始化 package.json 配置文件
在创建空白项目目录后,在该目录下运行如下命令以初始话配置文件:
npm init -y
# 若你希望可以初始话配置文件中的某些信息,可以使用如下命令
npm init
在使用 npm init -y 命令后,你能够在项目文件中观察到新增文件 package.json。
里面的内容如下(可能与你的略有不同):
{
"name": "demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
通过 npm 安装 jquery
使用如下命令通过 npm 安装 jquery:
npm install -S jquery
# 或
npm install --save jquery
# 或
npm install jquery
新建 src 源代码目录
在项目根目录下创建 src 文件夹,并在其中放置你的网页文件。
index.html
为实现列表隔行变色效果,我们将创建包含如下内容的 index.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>列表隔行变色效果</title>
</head>
<body>
<ul>
<li>这是第 1 个 li</li>
<li>这是第 2 个 li</li>
<li>这是第 3 个 li</li>
<li>这是第 4 个 li</li>
<li>这是第 5 个 li</li>
<li>这是第 6 个 li</li>
<li>这是第 7 个 li</li>
<li>这是第 8 个 li</li>
<li>这是第 9 个 li</li>
</ul>
<!-- 导入 index.js 文件 -->
<script src="./index.js"></script>
</body>
</html>
对于上述代码中的九个列表,在 VScode 中可以通过输入如下命令并敲击回车键(Enter)快速生成:
ul>li{这是第 $ 个 li}*9
index.js
在此我们将使用 ES6 的模块化导入方式来导入 jquery,来验证 webpack 是否具有解决兼容性问题的能力。
import $ from 'jquery'
// 使用 $ 来接受导入的 jquery 模块
// li:add 选中排位位于奇数位次的 li 标签
// li:even 选中排位位于偶数次的 li 标签
$(function(){
$('li:odd').css('background-color', 'red')
$('li:even').css('background-color', 'pink')
})
检查网页效果
将 index.html 在浏览器中打开,可以看到希望产生的效果并没有实现。
让我们打开控制台(快捷键 F12),可以观察到报错信息:
Uncaught SyntaxError: Cannot use import statement outside a module (at index.js:1:1)
大意是我们无法在模块外部使用 import 语句,也就是不支持该语法。
webpack 的安装
webpack 的安装
在终端中输入如下命令以进行 webpack 的安装:
npm install webpack webpack-cli -D
- 如果各位对 webpack 的某个版本较为中意,可以通过使用 @ 符号来指定版本,这里以安装 webpack 5.42.1 来进行演示。
npm install webpack@5.42.1 -D
- webpack-cli 是 webpack 的命令行版本。
dependencies 与 devDependencies
在安装完成 webpack 及 webpack-cli 后,让我们把目光望向 package.json 文件。
{
"name": "demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"jquery": "^3.6.3"
},
"devDependencies": {
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1"
}
}
可以看到 jquety 被存放到 dependencies 下,而 webpack 及 webpack-cli 都被存放到 devDependencies 中。照成这种现象的原因与我们两次安装软件包使用的命令参数存在不同。
参数 -S 及 --save
在使用 npm 安装软件包时,默认使用的参数就是 -S 或 –save,使用该参数对包进行安装后,软件包的名称都将出现在 dependencies 中。
参数 -D 及 --save-dev
使用 -D 或 –save-dev 参数对包进行安装后,软件包的名称都将出现在 devDependencies 中。
dependencies 与 devDependencies
- dependencies
dependencies 所包含的包是在开发阶段及发布阶段都需要包含(在两个阶段中发挥作用的软件包)到的软件包。 - devDependencies
devDependencies 所包含的包是在开发阶段需要包含但在发布阶段不需要包含的软件包。
对软件包进行 dependencies 及 devDependencies 进行区分,可以减少在发布阶段所需要打包的内容,减少网站成品所占用的服务器资源。
使用 -S 还是 -D
在开发过程中,我们往往会需要用到很多的软件包,安装这些软件包究竟是使用命令参数 -S 好,还是使用命令参数 -D 好呢?
在安装一个包时如果存在上述疑惑,推荐各位可以使用 npm 官网,里面有许多软件包的具体信息。当然,查看该网站,你还可以收获上述问题的解决之道。
比如,对于 webpack,该网站中存在着如下建议:
webpack 的配置
webpack 配置文件
在对 webpack 进行配置之前,需要在项目根目录下新建 webpack 配置文件,该文件的名称为 webpack.config.js。
在创建该配置文件后,请向该配置文件中输入如下内容:
module.exports = {
mode: "development"
}
其中:
mode 用来指定模式,其取值有两种,development 用来指定当前项目的模式为 开发模式;production 用来指定当前项目的模式为 发布模式。
package.json 的 script 节点
在配置完成 webpack.config.js 配置文件后,我们需要在 package.json 文件中的 script 节点中添加内容:
"script": {
"dev": "webpack"
}
修改完成后, package.json 文件大概长这样:
{
"name": "demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"jquery": "^3.6.3"
},
"devDependencies": {
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1"
}
}
webpack 的使用
在终端中使用如下命令使用 webpack 对网页源代码文件进行打包:
npm run dev
在使用该命令后,可以观察到项目文件中多出了一个文件夹 dist,dist 文件夹中的 main.js 文件便是此次 webpack 对文件打包的结果。
由于 main.js 文件是文件打包的结果,所以我们需要对 index.html 进行修改,引入 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>列表隔行变色效果</title>
</head>
<body>
<ul>
<li>这是第 1 个 li</li>
<li>这是第 2 个 li</li>
<li>这是第 3 个 li</li>
<li>这是第 4 个 li</li>
<li>这是第 5 个 li</li>
<li>这是第 6 个 li</li>
<li>这是第 7 个 li</li>
<li>这是第 8 个 li</li>
<li>这是第 9 个 li</li>
</ul>
<!-- 导入 main.js 文件 -->
<script src="../dist/main.js"></script>
</body>
</html>
将 index.html 在浏览器中打开,可以发现该网页已经可以正常运行,webpack 成功的解决了依赖问题。
开发模式与发布模式
webpack 能够对被打包文件进行压缩混淆,但当我们打开文件 main.js 可以观察到该文件并没有被压缩混淆。但其中的确有部分代码被压缩了,但那是 jquery。我们的 webpack 并没有对打包文件进行压缩混淆。
原因是:
压缩混淆所需要的时间往往都比较长,在开发阶段每次打包都需要耗费较多的时间用于打包是得不偿失的。如果需要对被打包文件进行压缩混淆,就需要我们对 webpack.config.js 文件进行配置,将模式设置为 发布模式(production) 即可。
为使用 webpack 的压缩混淆功能,我们将 webpack.config.js 中的内容修改为如下结果:
module.exports = {
mode: "production"
}
修改完成后,我们再次运行如下命令:
npm run dev
由程序打印的消息,我们可以观察到,本次打包程序所耗费的时间是使用开发模式打包所耗费时间的近 七倍,所耗费的空间是使用开发模式进行打包所耗费空间的近 四倍。
指定 webpack 的 entry 及 output
在 webpack 4.x 及 5.x 的版本中,默认存在如下约定:
- 默认的入口文件为:
项目文件根目录下的 src 文件夹中的 index.js 文件。 - 默认的导出文件为:
项目文件根目录下的 dist 文件夹中的 main.js 文件。
我们可以通过修改 webpack.config.js 来对入口文件及导出文件进行修改。
举个栗子
将导出文件设置为 项目文件根目录下的 result 文件夹中的 bundle.js 文件;将输入文件显式设置为 webpack 的默认输入文件。
为达成上述目的,我们将 webpack.config.js 做出如下修改:
const path = require("path");
module.exports = {
mode: "development",
entry: path.join(__dirname, './src/index.js'),
output: {
path: path.join(__dirname, './result'),
filename: 'bundle.js'
}
}
其中:
- path.join( […paths] )
paths: 它是逗号分隔的一系列路径,这些路径将连接在一起以构成最终路径。构成的最终路径将作为返回值返回。
join() 是 Node.js 下的 path 模块中的函数,所以使用该函数前需要通过 require() 函数将其导入。 - __dirname
__dirname 指当前文件所在的文件夹,由于 webpack.config.js 位于项目文件的根目录下,所以此处的 __dirname 代指项目文件所在的路径。 - 在该配置文件中,我们使用 entry 来定义入口文件,使用 output 来定义导出文件。
在配置完成配置文件 webpack.config.js 后,我们使用命令 npm run dev,可以发现导出文件已在指定路径下成功显示,这表明我们对导入导出文件的设置是正确的。
webpack 实现页面自动刷新
在日常开发过程中,如果每次查看网页的效果都需要先执行命令 npm run dev 后再刷新页面,会大大影响各位码农的工作心情。
我们可以通过 webpack-dev-server 及 html-webapck-plugin 这两款插件来帮助我们解决这个问题。
安装所需插件
在终端中输入如下命令以安装所需的插件:
npm install webpack-dev-server html-webpack-plugin -D
配置 webpack-dev-server
对 package.json 文件中的 script 节点进行如下更改:
"script": {
"dev": "webpack serve" //将此项由 webpack 修改为 webpack serve
}
修改完成后的 package.json 文件大概长这样:
{
"name": "demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack serve",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"jquery": "^3.6.3"
},
"devDependencies": {
"html-webpack-plugin": "^5.5.0",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.11.1"
}
}
在配置 webpack-dev-server 后,我们再执行命令:
npm run dev
可以发现,在使用该命令完成打包后,程序并没有立即退出。并且此时,如果我们对 index.js 文件(即入口文件)进行保存,webpack 也会自动对其进行打包。
细节
在使用 webpack-dev-server 对入口文件进行自动打包的结果并不会直接存储到物理磁盘中,而是会直接存储到内存中。你可以在项目文件的根目录下访问到该文件虽然你看不到它。
还记得使用 webpack-dev-server 后使用命令 npm run dev 后打印的前几行消息吗?
这段打印信息告诉我们,我们可以通过访问链接 http://localhost:8080/ 或 http://192.168.0.105:8080/ 来对项目根目录进行访问。
虽然我的网页好像发生了错误,但还是可以访问那个看不到的导出文件 main.js。
访问链接 http://localhost:8080/main.js 来对 main.js 进行访问。
可以看到被打包后的 main.js 文件:
在 webpack 结束运行前,打包后的文件都将存储在内存中,可以在项目文件根目录中访问到该文件。
html-webpack-plugin
html-webpack-plugin 插件可以自动地将某个路径下的文件复制到其他路径下,该文件并不会存在于物理磁盘中,在 webpack 运行过程中,该文件都将暂存于内存中,在 webpack 停止运行时,将该文件写入物理磁盘(复制的文件中所发生的修改在 webpack 中止运行后将写入原文件中)中。
在 webpack.config.js 文件添加如下内容对该插件进行配置:
const HtmlPlugin = require('html-webpack-plugin);
const htmlPlugin = new HtmlPlugin({
template: './src/index.html',
filename: './index.html'
)}
module.exports = {
plugins: [htmlPlugin]
}
其中:
- template 指定需要复制的文件,filename 则指定该文件需要复制到的路径。
webpack 文件修改后大概长这样:
const path = require("path");
const HtmlPlugin = require('html-webpack-plugin');
const htmlPlugin = new HtmlPlugin({
template: './src/index.html',
filename: './index.html'
})
module.exports = {
mode: "development",
entry: path.join(__dirname, './src/index.js'),
output: {
path: path.join(__dirname, './dist'),
filename: 'main.js'
},
plugins: [htmlPlugin]
}
修改配置后,每当我们使用命令 npm run dev 后,index.html 都将移动到项目文件的根目录中。此时我们只需要访问 http://localhost:8080/ 即可直接访问 index.html 文件。并且我们对 index.js 的修改在对 index.js 文件保存后都将反映到页面中。
html-webpack-plugin 的另一个功能
其实,html-webpack-plugin 并不只有复制文件这一个功能。该插件还可以帮助我们在 index.js 导入入口文件。我们可以通过如下方式对其进行验证。
首先,将 index.html 中的导入 JavaScript 文件的代码删去,删除后的 index.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>列表隔行变色效果</title>
</head>
<body>
<ul>
<li>这是第 1 个 li</li>
<li>这是第 2 个 li</li>
<li>这是第 3 个 li</li>
<li>这是第 4 个 li</li>
<li>这是第 5 个 li</li>
<li>这是第 6 个 li</li>
<li>这是第 7 个 li</li>
<li>这是第 8 个 li</li>
<li>这是第 9 个 li</li>
</ul>
</body>
</html>
然后执行命令 npm run dev,打开链接 http://localhost:8080/ 对 index.html 进行访问,可以发现我们即使没有在 index.html 文件中导入 index.js 文件,该文件也依旧在发挥功能。
devServer 节点
在配置文件 webpack.config.js 文件中的 devServer 节点下,我们还可以对 webpack-dev-server 插件进行更多的配置。
devServer: {
open: true,
host: '127.0.0.1',
port: 80
}
其中:
- open 用来指定是否要自动打开浏览器
- host 及 port 用来指定打开浏览器(若浏览器已被打开将不会再打开新浏览器)后需要打开的网址及端口号。
在对配置文件进行如上添加后,在使用命令 npm run dev 后将会自动使用浏览器打开指定页面。