Html5和Webpack1: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. Webpack5的概念和安装
在实际前端开发时,除了LESS样式表之外,也经常会使用SASS,TypeScript等Web扩展技术。这些技术的出现有效的提高了Web开发的效率和便利性,但是也带来了一些问题,也就是这些技术开发的代码不能直接再浏览器中运行,需要通过各种不同编译器将代码编译成原生Web技术所使用的代码。这就导致了应用发布流程的复杂性大大增加。同时大型项目包含了大量的CSS和JavaScript文件,Html网页在加载这些文件时需要编写大量的<link>或<script>
于是专注于前端代码编译打包的工具就应允而生,例如Webpack,Rollup等等。这些编译打包工具会完成非标准扩展文件的预编译,同时会将大量的CSS和JavaScript文件合并成一个或者几个文件便于Html加载。其中Webpack是打包工具中使用最广泛的,也是我们本次实验为大家介绍的重点。
- webpack的安装
webpack 做一个一款前端开发工具,本身也可以通过npm包管理器进行安装。为了安装webpack,我们在终端选项卡中执行如下命令。在安装命令中有两点要注意,第一是webpack的安装要同时安装webpack和webpack-cli两个工具,第二是在安装时使用--save-dev参数,将工具安装到web应用所在目录之下。
npm install webpack webpack-cli --save-dev
- webpack的调用
在通过npm安装webpack工具之后,我们需要执行这个工具,但是由于webpack工具并不是全局方式进行安装,因此并没有放到node目录中,而是被安装到了应用所在的目录下,而应用所在的目录并没有在path中,因此无法直接执行webpack。这时我们可以使用node中的另一个命令行工具npx来执行webpack。在终端选项卡中执行如下命令。
npx webpack -v
npx在执行之后会搜索应用所在目录中通过npm安装的工具。如果存在则调用应用所在目录中的工具。通过npx webpack -v我们可以查看刚安装的工具的版本信息为5.75。因此我们称呼大版本号为5的webpack为webpack5。
- package.json文件和插件目录
在前面的实验中我们也讲解过,通过npm init初始化过的项目会包含一个package.json文件。这个文件存储了项目的相关配置信息,也包括了项目型插件的信息。我们通过vscode打开packge.json文件。会发现webpack安装后配置文件中出现了"devDependencies" 字段。这个字段中记录了项目型插件的安装信息
同时在项目根目录下多出了一个目录node_modules,这个目录就是项目型插件的安装目录。
4. Webpack5的配置方式
- 创建目录结构
webpack5项目主要用于管理大型复杂的项目,为了方便大型项目的文件管理,webpack5具有建议的项目文件结构,一般来说建议在项目根目录中包含如下内容:
a.src目录用于存放原始JavaScript文件,
b.dist目录用于存放编译后的文件。我们创建这两个目录,在终端选项卡中执行如下命令。
mkdir src mkdir dist ls
- 创建配置文件
除了默认目录之外,webpack5还需要一个配置文件用来描述预编译过程。配置文件默认的名字为webpack.config.js位于项目的根目录中。我们通过vscode新建并保存webpack.config.js配置文件。
在webpack.config.js配置文件中有两个比较重要的配置属性。分别是entry属性和output中的filename属性。其中entry属性为需要编译的JavaScript文件,output中的filename属性为编译出文件的文件名。配置文件的内容如下
const path = require('path'); module.exports = { mode:'development', entry: './src/index.js', output: { filename: 'main.js', path: path.resolve(__dirname, 'dist'), }, };
- 项目的编译
接下来我们创建需要编译的文件./src/index.js,文件内容如下
function showMsg(str){ document.getElementById('resp').outerHTML += '<div>' + str + '<div/>' }
./src/index.js编写完成后。我们就可以进行编译,在终端中执行如下命令,可以看到./src/index.js文件编译成为./dist/main.js。
npx webpack cat ./dist/main.js
最后我们修改index.html文件来引用main.js,文件内容如下
<!DOCTYPE html> <html lang="zh-CN"> <title>Web dev</title> <body> <div> <button class="" onclick="showMsg('click button')">button</button> <button class="light" onclick="showMsg('click light button')">light button</button> <button class="cancel" onclick="showMsg('click cancel button')">cancel button</button> </div> </body> </html>
编辑完成之后,用内嵌Edge打开index.html,点击button看到index.js中的字符串输出函数被调用。
5. JS中的跨文件变量冲突
- 构建实验环境
ES6的一个非常重要的功能就是新增了模块化语法。在没有模块化语法之前,JavaScript往往会遇到变量名冲突的问题。也就是不同的JavaScript文件定义了相同名字的变量。会导致互相干扰。我们先来看一个例子,我们在./src目录下新建function.js文件并将showMsg函数移动到function.js中。我们修改function.js的内容如下
function showMsg(str){ document.getElementById('resp').outerHTML += '<div>' + str + '<div/>' }
接下来我们在./src目录中新增一个JavaScript文件conflict.js,文件内容如下。
var showMsg = "Hello World";
- 构造名字冲突的另一个文件
我们采用传统的<script>元素加载function.js和conflict.js
<!DOCTYPE html> <html lang="zh-CN"> <script src="./src/function.js"></script> <script src="./src/conflict.js"></script> <title>Web dev</title> <body> <div> <button class="" onclick="showMsg('click button')">button</button> <button class="light" onclick="showMsg('click light button')">light button</button> <button class="cancel" onclick="showMsg('click cancel button')">cancel button</button> </div> <div id="resp"> </div> </body> </html>
- 验证Html中的脚本冲突
修改后按F5启动内嵌Edge。点击button按钮,会发现function.js中定义的showMsg被conflict.js中的showMsg取代。这种不区分变量生效范围的方法非常不利于大型项目的开发。
6. ES6中的模块化语法
为了解决多文件的变量冲突问题,开发者们设计出了很多的变通方法进行处理,最终JavaScript的官方版本ECMAScript 6(简称ES6)中提出了标准的模块化语法。在ES6的模块化语法中,每一个文件做为一个模块。模块和模块之间有独立的命名空间,不同模块中的变量在不同的命名空间中,这样即使出现的重名,也不会发生冲突。一个模块如果需要调用另一个模块的资源,需要使用import和export进行导入和导出。接下来我们来看如何通过webpack进行多个模块的导入和导出。
- 模块的导出语法
我们修改function.js为如下内容,通过export default 导出属性语法来声明showMsg函数和README字符串会被其他模块调用。
function showMsg(str){ document.getElementById('resp').outerHTML += '<div>' + str + '<div/>' } const README = "模块function.js中函数showMsg的功能: 将str参数的内容添加到id为resp的元素"; export default {showMsg, README}
接下来修改conflict.js在如下内容,在这里我们可以使用导出语法的另一个形式 module.export = 导出属性,来导出conflict.js模块中的showMsg变量和README字符串。
var showMsg = "Hello World"; const README = "模块conflict.js中变量showMsg的内容: 'Hello World'"; module.exports = {showMsg, README}
- 模块的导入语法
为两个文件添加了export之后,我们在index.js中通过import语法来引用这两个文件。import语法格式为 import 模块名 form 模块路径,在import之后即可使用模块名来指定模块的命名空间。继续修改index.js为如下内容
import func from './function.js' import conflict from './conflict.js' console.log(func.README); console.log(func.showMsg); console.log(conflict.README); console.log(conflict.showMsg);
- 通过node命令运行打包文件
修改完成后,我们在终端中执行如下命令进行编译和运行。会发现两个模块打包到了一个文件main.js中,同时两个模块的同名变量已经不会发生冲突
npx webpack node ./dist/main.js
实验链接:https://developer.aliyun.com/adc/scenario/1cf44643943541b69c90597845365fad