Html5和Webpack3:Webpack5的常见用法
1. 创建资源
开始实验之前,您需要先创建实验相关资源。
- 在实验室页面,单击创建资源。
- (可选)在实验室页面左侧导航栏中,单击云产品资源列表,可查看本次实验资源相关信息(例如IP地址、子用户信息等)。
说明:资源创建过程需要3~5分钟(视资源不同开通时间有所差异,ACK等资源开通时间较长)。完成实验资源的创建后,您可以在云产品资源列表查看已创建的资源信息,例如:子用户名称、子用户密码、AK ID、AK Secret、资源中的项目名称等。
实验环境一旦开始创建则进入计时阶段,建议学员先基本了解实验具体的步骤、目的,真正开始做实验时再进行创建。
资源创建成功,可在左侧的资源卡片中查看相关资源信息以及RAM子账号信息
2. 进入VNC实验环境
- 进入网页环境
1.1 资源创建成功后,我们在右侧选择切换到远程桌面。
1.2 在远程桌面页面中,点击Chromium网页浏览器。
- 登录RAM用户
2.1 浏览器启动后会默认打开阿里云的RAM用户登录页。在登录页面中我们点击下一步按钮。
2.2 接下来我们需要输入RAM用户的密码。密码显示在实验控制台左侧,我们点击子用户密码右侧的复制按钮。
复制完成后,我们在用户密码框中按Ctrl + V 复制密码,然后点击登录按钮
- 进入ECS的远程连接。
3.1 登录成功后,页面跳转到控制台,我们在控制台的搜索框中输入ECS,然后点击云服务器ECS进入云服务器控制台。
3.2 在ECS控制台中,我们找到实验创建的ECS,点击右侧的远程连接按钮。
3.3 在远程连接中选择通过VNC远程连接中的立即登录如果没有显示该选项,则可点击展开其他登录方式按钮。
- 登录VNC远程连接
4.1 初次登录VNC远程连接时需要先设置VNC密码。点击重置VNC密码按钮。
4.2 输入两次新的VNC密码,并点击确认。
4.3 VNC密码设置成功后,输入密码并点击确认。
4.4 VNC登录成功后会看到实验ECS的登录界面。
3. 实验环境准备
在前面的实验中我们介绍了webpack常见用法。通过webpack我们可以将前端的JavaScript代码和样式表统一打包压缩。在本节实验中,我们来学习如何Webpack5的一些常用用法
- 创建网页文件
首先我们来创建项目目录,在终端中执行如下命令
mkdir src mkdir css mkdri dist
在./src目录中创建function.js文件为如下内容
function showMsg(str){ document.getElementById('resp').outerHTML += '<div>' + str + '<div/>' } const README = "模块function.js中函数showMsg的功能: 将str参数的内容添加到id为resp的元素"; export default {showMsg, README}
在./src目录中创建conflict.js文件为如下内容
var showMsg = "Hello World"; const README = "模块conflict.js中变量showMsg的内容: 'Hello World'"; module.exports = {showMsg, README}
在./src目录中创建index.js文件为如下内容
import '../css/style.css' import func from './function.js' import conflict from './conflict.js' window.func = func window.conflict = conflict
在./css目录中创建style.css文件为如下内容
body { background-color: #f4f4f4; color: #141414; } body button { background-color: #3060C0; color: #f4f4f4; } body button.light { background-color: #799add; color: #141414; } body button.cancel { background-color: #a4a4a4; color: #141414; } button { border-radius: 8px; padding: 5px 15px; margin: 10px; font-size: 15px; border: 2px solid #777; }
最后在项目根目录创建index.html网页文件。
<!DOCTYPE html> <html lang="zh-CN"> <script src="./dist/main.js"></script> <title>Web dev</title> <body> <div> <button class="" onclick="func.showMsg('click button')">button</button> <button class="light" onclick="func.showMsg('click light button')">light button</button> <button class="cancel" onclick="func.showMsg('click cancel button')">cancel button</button> </div> </body> </html>
- 创建项目配置文件
接下来创建node.js项目和webpack项目的项目文件。在根目录中创建package.json文件为如下内容
{ "name": "web", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "build": "webpack", "release": "webpack --mode=production" }, "author": "", "license": "ISC", "devDependencies": { "css-loader": "^6.7.3", "style-loader": "^3.3.1", "webpack": "^5.75.0", "webpack-cli": "^5.0.1" } }
在根目录创建webpack.config.js文件为如下内容
const path = require('path'); module.exports = { mode: 'development', entry: './src/index.js', output: { filename: 'main.js', path: path.resolve(__dirname, 'dist'), }, module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] } ] } };
- 依赖资源的安装和测试
我们在终端中执行如下命令安装依赖,并测试使用npx webpack命令编译。
npm i npx webpack
依赖安装完毕后,按F5打开网页,发现css加载完成
4. Webpack5的资源模块
- 构建加载了图片的网页
在上一个实验中我们演示了JavaScript脚本和样式表的加载方式。实际上除了这两种最常见的资源之外,Html网页还会引用一些其他的资源,比如图标,图片,字体等。对于这些资源我们可以使用Webpack5的资源模块进行处理。
为了演示这些功能,我们首先来构建引用了图标资源的文件。首先使用以下命令下载图标文件
mkdir imgs wget https://labfileapp.oss-cn-hangzhou.aliyuncs.com/PracticalTrain/lena_tiny.png -P ./imgs wget https://labfileapp.oss-cn-hangzhou.aliyuncs.com/PracticalTrain/lena_small.png -P ./imgs
下载之后修改index.html文件,加载图片
<!DOCTYPE html> <html lang="zh-CN"> <script src="./dist/main.js"></script> <title>Web dev</title> <body> <div> <img id="lena_tiny" src="./imgs/lena_tiny.png" alt="lena tiny"> <img id="lena_small" src="./imgs/lena_small.png" alt="lena small"> </div> <div> <button class="" onclick="func.showMsg('click button')">button</button> <button class="light" onclick="func.showMsg('click light button')">light button</button> <button class="cancel" onclick="func.showMsg('click cancel button')">cancel button</button> </div> </body> </html>
图片加载后按F5调试网页
- 配置资源模块处理图片
通过上一个步骤的方法我们为<img>元素加载了两张图片,对于某些网页来讲,会存在很多细小的图标图片文件,这种情况下同样会出现网页发出大量网络连接加载小图片的情况。这种情况下就可以使用Webpack5的资源模块将小图片加载到main.js中。在页面中统一加载。我们修改webpack.config.js文件为如下内容。在rules数组中加入对png文件的处理。
const path = require('path'); module.exports = { mode: 'development', entry: './src/index.js', output: { filename: 'main.js', path: path.resolve(__dirname, 'dist'), }, module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.png$/, type: 'asset/inline', }, ] } };
配置文件修改完毕后,我们在./src/index.js中加载图片,除了使用import关键字加载资源之外,我还可以使用require()函数加载资源,require()函数的返回值即使资源的引用,我们修改./src/index.js为如下内容。
import '../css/style.css' import func from './function.js' import conflict from './conflict.js' window.func = func window.conflict = conflict window.img = { "lena_small": require('../imgs/lena_small.png'), "lena_tiny": require('../imgs/lena_tiny.png') }
- 修改Html引用加载图片
通过main.js打包图片后,图片的元素<img>的src属性就不再是一个网络URL而是一个图片的数据编码,因此我们需要通过JavaScript脚本来设置src属性。我们修改index.html为如下内容,在window.onload事件中设置<img>图片的的src属性
<!DOCTYPE html> <html lang="zh-CN"> <script src="./dist/main.js"></script> <title>Web dev</title> <body> <div> <img id="lena_tiny" alt="lena tiny"> <img id="lena_small" alt="lena small"> </div> <div> <button class="" onclick="func.showMsg('click button')">button</button> <button class="light" onclick="func.showMsg('click light button')">light button</button> <button class="cancel" onclick="func.showMsg('click cancel button')">cancel button</button> </div> <script> window.onload = function () { console.log(img) document.getElementById('lena_tiny').src = img.lena_tiny document.getElementById('lena_small').src = img.lena_small } </script> </body> </html>
网页修改完毕后,按F5运行网页可以看到图片的加载效果。
同时在控制台界面可以看到图片的src为base64编码的图片数据
5. Webpack5的常见用法
- 生产环境编译模式
在使用webpack编译时,可以在webpack命令后添加参数,webpack比较常用的参数是使用--mode选择编译模式。我们常用的编译模式有两种,分别时开发模式和生产模式,在开发模式中webpack生成的代码会尽可能符合开发人员的阅读习惯,而在生产模式下,生成的代码会尽量压缩,符合计算机执行的要求。在默认情况下webpack使用的时开发模式进行编译,接下来我们来看如何使用生产模式进行编译。我们在终端中执行如下命令进行编译
npx webpack --mode=production
编译之后通过vscode打开./dist/main.js按atl+z启动自动换行。会发现main.js文件经过了高度的压缩,同时参数函数的名称和属性名称也被扰码。
- 配置编译命令脚本
除了使用npx webpack 参数命令之外,还可以使用package.json中的scripts字段配置编译脚本。通过脚本配置的方式时可以添加webpack的参数,我们修改package.json为如下内容
{ "name": "web", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "build": "webpack", "release": "webpack --mode=production" }, "author": "", "license": "ISC", "devDependencies": { "css-loader": "^6.7.3", "style-loader": "^3.3.1", "webpack": "^5.75.0", "webpack-cli": "^5.0.1" } }
修改的之后,在终端中执行如下命令同样可以进行编译
# development开发模式进行编译 npm run build # production生产模式进行编译 npm run release
- Hash文件名编译
在实际生产环境中,为了对编译生成的JavaScript进行缓存和灰度升级,经常会为每次生成的JavaScript设置成不同的名称。这时就可以配置webpack.config.js的输出文件名字段为[hash:hash值长度],修改webpack.config.js为如下内容
const path = require('path'); module.exports = { mode: 'development', entry: './src/index.js', output: { filename: 'main-[hash:8].js', path: path.resolve(__dirname, 'dist'), }, module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] } ] } };
设置完成后通过如下命令进行编译,会发现生成JavaScript文件会添加一个8位的Hash值
npm run build ls ./dist
我们修改./src/index.js为如下内容,添加一条注释
require('../style.css') import func from './function.js' import conflict from './conflict.js' window.func = func window.conflict = conflict //a
修改后再次编译,会发现由于内容的概念,新编译的文件文件名和上次编译的不同。
npm run build ls ./dist
6. Webpack5的Plugin
在上一个小节中为大家讲解通每次编译成不同的名字的设置方式。这种方式有利于灰度升级,但是开发者需要每次编译之后手动修改index.html文件中的<script>引用。为了实现每次编译之后自动生成index.html中的<script>引用,我们可以使用plugin插件来实现。
- 安装和配置plugin插件
webpack中的plugin和loader都属于可以通过npm安装的插件。在webpack中负责自动加载的plugin是html-webpack-plugin,我们首先通过如下命令安装html-webpack-plugin
npm i html-webpack-plugin --save-dev
安装完毕之后,我们需要修改webpack.cionfig.js配置文件。在配置文件中加载插件,然后再plugins:字段中创建插件对象。插件对象创建后配置template字段,设置需要自动加载的Html文件名
我们修改webpack.cionfig.js配置文件为如下内容。
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { mode: 'development', entry: './src/index.js', output: { filename: 'main-[hash:8].js', path: path.resolve(__dirname, 'dist'), }, module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] } ] }, plugins: [ new HtmlWebpackPlugin({ template:'./index.html' }) ] };
- 通过Plugin实现脚本自动加载
修改配置文件之后,我们在修改index.html文件去掉原有的<script>脚本引用后再次编译。
npm run build
编译完成后我们会发现./dist目录中出现了index.html文件,我们用vscode打开./dist/index.html,会发现在<head>元素中,自动加载了编译好的JavaScript
- 自动清除plugin的安装
通过这种方式加载编译还存在一个小问题,也就是由于每次编译生成的JavaScript文件名不同,./dist目录中会残存很多早期编译的文件结果,这时我们可以使用clean-webpack-plugin插件来实现自动清理。我们首先通过npm命令来安装插件
npm i clean-webpack-plugin --save-dev
安装完成后,修改webpack.cionfig.js配置文件。在配置文件中加载插件,然后再plugins:字段中创建插件对象。
const path = require('path'); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { mode: 'development', entry: './src/index.js', output: { filename: 'main-[hash:8].js', path: path.resolve(__dirname, 'dist'), }, module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] } ] }, plugins: [ new HtmlWebpackPlugin({ template: './index.html' }), new CleanWebpackPlugin() ] };
修改完成后再次编译,会发现./dist目录中的旧文件都被删除了
npm run release ls ./dist
实验链接:https://developer.aliyun.com/adc/scenario/8b26427eaadd4f0e94b2691925c7229e