本课作为前端开发的转型课,重点讲解npm依赖管理与Vite构建工具两大工程化基础。npm解决了第三方代码复用与依赖管理难题,让项目依赖可追溯、可快速恢复;Vite则简化了项目搭建与构建流程,极速的启动和热更新大幅提升开发效率,同时原生支持模块化与高级异步语法。工程化是现代前端开发的分水岭,告别原生手写代码的粗放模式,建立规范、高效、可维护的开发流程。掌握本课内容,不仅能独立搭建标准化前端项目,更是后续学习Vue、React等框架的必备前提,是前端从零基础迈向实战开发的关键一步。
一、课程学习目的
-
理解前端工程化的核心意义,告别原生手写代码的零散模式,建立规范化开发思维。
-
掌握npm包管理器的核心作用,熟练使用常用命令安装、管理、卸载第三方依赖。
-
理解package.json配置文件的作用,分清dependencies、devDependencies依赖区别。
-
掌握Vite快速搭建项目的流程,学会启动、打包项目,熟悉基础项目结构。
-
能够在工程化环境中运行模块化代码,为后续Vue/React框架学习奠定基础。
二、核心知识点讲解
1. 前端工程化概述
前端工程化是将零散的代码、资源、工具进行规范化、自动化、模块化管理的开发模式,解决传统开发中代码混乱、复用性差、依赖难管理、部署繁琐等问题,是现代前端开发的必备技能。
核心环节包含:依赖管理、模块化开发、项目构建、自动化部署、代码规范等,本课重点讲解npm依赖管理 和Vite项目构建两大基础工具。
2. npm 包管理器(Node Package Manager)
npm是Node.js自带的第三方包管理工具,用于下载、管理、共享前端代码库(依赖包),无需手动复制粘贴插件代码。
安装Node.js后会自动集成npm,通过终端命令即可操作,核心依托package.json文件记录项目信息与依赖清单。
3. npm 核心常用命令
-
npm -v:查看npm版本,验证是否安装成功
-
npm init:初始化项目,生成package.json配置文件
-
npm init -y:快速初始化,跳过问答环节
-
npm install 包名:安装指定依赖包(简写 npm i 包名)
-
npm install 包名 --save-dev:安装开发依赖(简写 npm i 包名 -D)
-
npm uninstall 包名:卸载指定依赖包
-
npm install:根据package.json安装所有依赖
4. Vite 构建工具基础
Vite是新一代前端构建工具,由Vue作者开发,主打极速启动、热更新、开箱即用,比WebPack更轻量高效,支持原生JS、Vue、React等多种项目。
Vite内置模块化支持,无需额外配置,可直接运行ES6模块化、async/await等高级语法,适合快速搭建工程化项目。
5. Vite 项目创建与运行流程
-
终端执行创建命令,选择项目模板(原生Vanilla/JS)
-
进入项目目录,安装依赖
-
启动开发服务器,实时预览项目
-
项目开发完毕,执行打包命令,生成上线文件
三、示例程序
示例1:npm初始化与安装依赖
bash
# 1. 创建项目文件夹并进入
mkdir js-project && cd js-project
# 2. 快速初始化package.json
npm init -y
# 3. 安装常用工具包(如axios、dayjs)
npm i axios dayjs
# 4. 安装开发依赖(如vite)
npm i vite -D
示例2:Vite创建并启动项目
bash
# 1. 创建Vite项目(选择Vanilla-原生JS)
npm create vite@latest
# 2. 按照提示操作
# 项目名称:js-vite-project
# 框架选择:Vanilla(原生JS)
# 语言选择:JavaScript
# 3. 进入项目目录
cd js-vite-project
# 4. 安装依赖
npm install
# 5. 启动开发服务器
npm run dev
# 6. 项目打包(上线用)
npm run build
示例3:工程化中使用模块化与异步代码
javascript
// utils.js 模块文件(导出)
// 封装异步请求方法
export async function fetchData(url) {
try {
const res = await fetch(url);
return await res.json();
} catch (err) {
console.error('请求失败', err);
throw err;
}
}
// main.js 主文件(导入使用)
import { fetchData } from './utils.js';
// 异步调用
async function init() {
const data = await fetchData('./data/word.json');
console.log('工程化异步数据:', data);
}
init();
四、掌握技巧与方法
-
项目必须先初始化npm(npm init -y),再安装依赖,保证依赖可追溯。
-
区分生产依赖(dependencies,项目运行必需)和开发依赖(devDependencies,仅开发用)。
-
Vite项目启动后,复制终端地址到浏览器访问,修改代码会自动热更新。
-
模块化文件路径需正确,导入导出语法规范,避免路径报错。
-
node_modules文件夹体积大,上传代码时无需提交,通过package.json即可恢复依赖。
-
遇到依赖安装失败,可删除node_modules和package-lock.json,重新执行npm install。
五、课后作业
基础作业
-
安装Node.js,验证npm、node版本,查看是否安装成功。
-
使用npm init初始化项目,安装axios、dayjs两个依赖包。
-
查看生成的package.json文件,找到dependencies依赖记录。
进阶作业
-
用Vite创建原生JS项目,启动并访问默认页面,测试热更新效果。
-
在Vite项目中拆分两个模块,实现ES6导出导入,运行无报错。
-
执行npm run build打包项目,查看生成的dist打包目录。
实战作业
- 在Vite工程化项目中,整合async/await异步请求、模块化拆分,实现单词数据异步加载、页面渲染功能,完成完整工程化实战。
上一课:异步编程高级(async/await + 模块化)实战作业代码
代码功能说明
本实战代码紧扣async/await与ES6模块化核心考点,采用英语单词加载场景,实现模块化拆分与异步逻辑全流程。代码拆分为数据模块、工具模块、主逻辑模块,通过export/import完成导入导出;封装异步请求函数,依托async/await实现同步风格的异步串行、并行加载,搭配try/catch捕获异常;页面实现加载提示、成功渲染、错误兜底交互,直观展示模块化解耦、async/await语法、异常处理、Promise.all并行等核心知识点,可直接在浏览器运行,贴合课程考点,为工程化学习铺垫基础。
注意事项
-
浏览器运行模块化代码,script标签必须添加 type="module" 属性,否则会报错。
-
await关键字只能在async修饰的函数内部使用,禁止在全局或普通函数中单独调用。
-
所有async/await逻辑必须包裹try/catch,规范捕获异步异常,防止程序中断。
-
模块化导入路径需写完整相对路径,文件名、后缀名不可省略,避免路径错误。
-
无依赖的异步任务,用Promise.all+await实现并行执行,提升加载效率。
-
async函数默认返回Promise对象,可继续链式调用,但推荐用try/catch简化写法。
-
运行代码时打开浏览器控制台,排查模块化、异步语法相关报错,加深理解。
完整实战代码
代码结构(单HTML整合版,无需多文件,直接运行)
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>第16课 async/await+模块化实战</title>
<style>
.box {
width: 750px;
margin: 50px auto;
padding: 30px;
border: 1px solid #eee;
border-radius: 10px;
font-family: "Microsoft YaHei";
box-shadow: 0 0 12px rgba(0,0,0,0.06);
}
.btn {
padding: 10px 20px;
margin: 10px 8px;
background: #42b983;
color: #fff;
border: none;
border-radius: 6px;
cursor: pointer;
transition: 0.3s;
}
.btn:hover {
background: #359469;
}
.result {
margin-top: 25px;
padding: 20px;
line-height: 2;
border-top: 1px dashed #eee;
min-height: 180px;
}
.item {
margin: 8px 0;
padding: 10px;
background: #f9f9f9;
border-radius: 5px;
}
.loading { color: #666; }
.error { color: #f56c6c; }
</style>
</head>
<body>
<div class="box">
<h2>async/await 单词模块化加载器</h2>
<button class="btn" onclick="serialLoad()">串行加载单词</button>
<button class="btn" onclick="parallelLoad()">并行加载单词</button>
<button class="btn" onclick="clearResult()">清空结果</button>
<div class="result" id="result"></div>
</div>
<!-- 模块化核心:type="module" -->
<script type="module">
const resDom = document.getElementById("result");
// 渲染工具函数
function render(html, className = '') {
resDom.innerHTML += `<div class="item ${className}">${html}</div>`;
}
// 清空结果
window.clearResult = () => resDom.innerHTML = "";
// ==================== 模块1:异步数据模块(模拟导出)====================
function mockFetchWord(word) {
return new Promise((resolve, reject) => {
render(`加载中:${word}`, "loading");
setTimeout(() => {
if (word) resolve({ en: word, cn: "中文释义", status: "success" });
else reject("单词参数无效");
}, 1200);
});
}
// 导出异步方法
export async function getSingleWord(word) {
try {
return await mockFetchWord(word);
} catch (err) {
throw err;
}
}
export async function getBatchWord(words) {
try {
return await Promise.all(words.map(item => mockFetchWord(item)));
} catch (err) {
throw err;
}
}
// ==================== 主逻辑:导入并使用模块====================
import { getSingleWord, getBatchWord } from './#mock-module.js';
// 串行加载(绑定全局,供按钮调用)
window.serialLoad = async function () {
try {
const res1 = await getSingleWord("apple");
render(`成功:${res1.en} - ${res1.cn}`);
const res2 = await getSingleWord("banana");
render(`成功:${res2.en} - ${res2.cn}`);
} catch (err) {
render(`错误:${err}`, "error");
}
};
// 并行加载(绑定全局,供按钮调用)
window.parallelLoad = async function () {
try {
const results = await getBatchWord(["apple", "banana", "orange"]);
results.forEach(item => {
render(`批量成功:${item.en} - ${item.cn}`);
});
} catch (err) {
render(`错误:${err}`, "error");
}
};
</script>
</body>
</html>
作业验收标准
-
页面按钮点击正常,模块化语法无报错,async/await执行顺畅。
-
串行加载按顺序执行,并行加载同步执行,效率差异直观。
-
try/catch异常捕获到位,错误提示友好,加载状态清晰。
-
代码模块化拆分规范,导出导入语法正确,贴合第16课核心考点。