在上一篇《工程化起点:Node.js、npm 与 Vite 如何让 Vue 项目跑起来》中,我们已经解决了“现代前端项目为什么不能只靠一个 index.html 文件”这个问题,也知道了 Node.js、npm、Vite、package.json 这些基础工具到底在做什么。
但如果你真的把一个 Vue 项目跑起来,很快就会遇到下一批更贴近真实开发的问题:
- 团队里为什么很多项目不用
npm,而是用pnpm - 为什么同一个项目会有
.env.development和.env.production - 本地调接口为什么经常要配置代理
- 为什么很多项目里会用
@/api/user这种路径别名 - 为什么编辑器刚写完代码,就提示格式和规范问题
这些问题不属于“Vue 语法”本身,但它们几乎构成了现代前端项目的日常工作环境。
如果说上一篇讲的是工程化的“起点”,那么这一篇讲的就是:
一个 Vue 项目真正进入日常开发状态后,最常见的工程化补全能力。
1. 为什么还要补这一层工程化知识
很多初学者会觉得:
我都已经会
npm install、npm run dev了,项目不是已经能跑起来了吗?
能跑起来,确实说明你已经跨过了工程化的第一道门槛。
但“能运行”和“适合长期开发”是两回事。
真实项目通常还要解决这些问题:
- 不同环境下接口地址不一样
- 本地开发时需要绕过跨域
- 团队需要统一代码风格
- 依赖安装速度和磁盘占用需要优化
- 导入路径不能总写很长的相对路径
所以这一篇可以理解为:
从“会启动项目”到“会在项目里舒服地开发”的过渡层。
2. 为什么很多团队开始使用 pnpm
2.1 pnpm 是什么
pnpm 也是 JavaScript 项目的包管理工具,和 npm、yarn 属于同一类工具。
它主要解决两个现实问题:
- 安装依赖时更快
- 更节省磁盘空间
2.2 它和 npm 有什么不同
你可以先建立一个简单认知:
npm:默认方案,入门最常见pnpm:现代前端团队里越来越常见,尤其是中大型项目
pnpm 的一个核心特点是:
它会尽量复用全局依赖存储,而不是每个项目都拷贝一整份依赖。
这意味着:
- 安装速度通常更快
- 多个项目不会反复占用大量空间
- 依赖结构也更严格,能更早暴露一些不规范引用
2.3 常见命令对照
如果你已经熟悉 npm,那迁移到 pnpm 并不难:
npm install
pnpm install
npm run dev
pnpm dev
npm install axios
pnpm add axios
npm install -D eslint
pnpm add -D eslint
2.4 学习阶段怎么选
建议是:
- 入门先理解
npm - 进入 Vue / Vite 工程项目后,开始认识
pnpm
你不用急着“二选一站队”,但最好能看懂两套命令,不然以后打开别人的项目时很容易懵。
3. 环境变量:为什么同一个项目会有多个 .env
在真实项目中,不同运行环境下的配置通常不同。
例如:
- 本地开发环境:请求测试接口
- 测试环境:请求联调服务器
- 生产环境:请求正式服务器
这时就不能把接口地址写死在代码里。
3.1 最直观的错误写法
const baseURL = "https://api.example.com";
如果你把地址直接写死,后面切换环境就会很痛苦。
3.2 Vite 中常见的环境文件
在 Vite 项目里,经常会看到这些文件:
.env
.env.development
.env.production
你可以先这样理解:
.env:所有环境都可用的公共配置.env.development:开发环境专用.env.production:生产环境专用
3.3 一个常见示例
VITE_APP_TITLE=Web Note
VITE_API_BASE_URL=/api
⚠️ 关键规则: 在 Vite 中,想让前端代码读取到环境变量,变量名通常必须以
VITE_开头。
3.4 在代码中如何读取
// 读取环境变量里的接口前缀
const baseURL = import.meta.env.VITE_API_BASE_URL;
console.log(baseURL);
这样做的好处是:
- 不同环境切换更自然
- 不必全项目手动替换地址
- 更适合后续部署
4. 开发代理:为什么本地调接口时总会配 proxy
很多初学者在本地开发时,会遇到一个经典报错:
浏览器提示跨域,接口请求被拦截了。
这往往是因为:
- 前端页面运行在
http://localhost:5173 - 后端接口运行在
http://localhost:8080
它们不是同一个源,所以浏览器会触发同源策略限制。
4.1 为什么开发阶段常用代理
开发代理不是后端接口本身,而是前端开发服务器帮你“转发请求”。
你可以这样理解:
- 浏览器请求前端开发服务器
- 开发服务器再帮你转发到真正的后端接口
- 浏览器以为自己还在和同源地址通信
这就是为什么本地联调时,很多项目都会配置 proxy。
4.2 Vite 中的典型配置
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
export default defineConfig({
plugins: [vue()],
server: {
proxy: {
// 把 /api 开头的请求转发到本地后端
"/api": {
target: "http://localhost:8080",
changeOrigin: true
}
}
}
});
4.3 这样配置后意味着什么
如果你代码里写:
axios.get("/api/user/list");
开发时它会被代理到:
http://localhost:8080/api/user/list
这也是为什么很多项目里的接口地址并不是直接写完整域名,而是优先写 /api 这样的前缀。
5. 路径别名:为什么大家都喜欢写 @/
当项目越来越大时,如果你一直这样导入文件:
import request from "../../../utils/request";
代码会很痛苦:
- 路径太长
- 容易数错层级
- 文件一旦移动,引用就容易乱
所以很多项目都会配置路径别名。
5.1 最常见的别名就是 @
例如:
// 通过别名直接定位到 src 下的工具模块
import request from "@/utils/request";
import { login } from "@/api/user";
这样一看就知道:
@代表src目录- 路径更短
- 结构更清晰
5.2 Vite 里的常见配置
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
// 把 @ 映射到 src 目录
"@": path.resolve(__dirname, "./src")
}
}
});
6. 为什么项目一上来就有 ESLint 和 Prettier
很多人第一次打开工程项目时,会发现保存代码后格式自动变化,或者编辑器里突然出现很多“看起来很烦”的提示。
这通常和下面两个工具有关:
ESLintPrettier
6.1 ESLint 是做什么的
它主要负责:
- 检查潜在错误
- 检查不规范写法
- 统一一部分代码风格
例如:
- 变量定义了但没使用
- 使用了不推荐的语法
- 某些写法可能有隐藏风险
6.2 Prettier 是做什么的
它主要负责:
- 自动格式化代码
- 统一缩进、引号、分号、换行风格
你可以把它理解为:
ESLint更偏“规则检查”Prettier更偏“代码排版”
6.3 为什么团队几乎都会配它们
因为如果不统一风格,团队协作时会出现很多没意义的争论:
- 用单引号还是双引号
- 结尾加不加分号
- 一行最多写多长
- JSX / Vue 模板怎么换行
这类问题最好交给工具统一处理,而不是靠人争论。
7. 一个最基础的规范链路长什么样
7.1 安装依赖
pnpm add -D eslint prettier eslint-config-prettier
如果你还在使用 npm,对应命令也很简单:
npm install -D eslint prettier eslint-config-prettier
7.2 常见配置思路
你不一定要一上来就手写很复杂的规则,但至少要先建立这个认知:
ESLint负责语法和规范检查Prettier负责自动格式化eslint-config-prettier常用于避免两者规则冲突
在学习阶段,重点不是背所有配置项,而是知道:
现代前端项目里的“代码规范”不是靠自觉,而是靠工具链落地。
7.3 编辑器为什么也要配合
很多项目会建议在 VS Code 中安装相关插件,并开启“保存时自动格式化”。
这样你一保存:
- 格式自动整理
- 明显错误更早暴露
- 团队代码风格更统一
8. 环境变量、代理、Axios 三者怎么串起来
很多初学者会把这三件事分开学,但真实项目里,它们往往是连在一起的。
一个典型思路如下:
8.1 环境变量里放接口基础前缀
VITE_API_BASE_URL=/api
8.2 Axios 实例中读取这个值
import axios from "axios";
const service = axios.create({
// 从环境变量中读取接口基础地址
baseURL: import.meta.env.VITE_API_BASE_URL,
timeout: 5000
});
export default service;
8.3 开发环境通过代理转发
server: {
proxy: {
"/api": {
target: "http://localhost:8080",
changeOrigin: true
}
}
}
这样做以后:
- 开发环境里,本地请求会走代理
- 生产环境里,可以按部署方式切换成真实地址
- 你的请求代码不用反复改
这就是工程化带来的价值:
不是只让项目跑起来,而是让“环境切换”和“接口联调”变得更顺滑。
9. 一个更贴近实际项目的目录结构
当你把这些工程化能力接进 Vue 项目后,一个更常见的目录结构可能长这样:
src/
api/
assets/
components/
router/
stores/
styles/
utils/
views/
App.vue
main.js
.env
.env.development
.env.production
vite.config.js
package.json
你可以这样理解它们的职责:
api/:接口函数views/:页面级组件components/:复用组件utils/:工具函数styles/:全局样式和变量vite.config.js:代理、别名等工程配置
10. 新手最常见的工程化误区
10.1 把接口地址写死在组件里
这样后面切换环境会非常痛苦。
10.2 不理解代理,只会复制配置
如果不知道代理到底在解决什么问题,一旦接口联调失败就很难排查。
10.3 环境变量名没加 VITE_ 前缀
结果就是代码里根本读不到。
10.4 只装了 ESLint / Prettier,但没真正接入编辑器和项目
工具装了不等于真的生效。
10.5 仍然大量使用相对路径导入
项目小的时候还能忍,项目一大就会明显拖慢开发体验。
11. 这一篇和上一篇、下一篇分别是什么关系
你可以这样看待这三篇内容:
工程化起点:解释 Node.js、npm、Vite 为什么存在,项目为什么能跑起来工程化补全:解释pnpm、环境变量、代理、路径别名、代码规范为什么是日常开发标配Vue 基础:在工程化环境已经就绪的前提下,正式进入 Vue 3 的组件和响应式开发
也就是说,这一篇的作用不是替代 Vue 语法,而是帮你把“开发环境”补齐。
12. 小结
如果把现代前端项目比作一个工作现场,那么:
Node.js / npm / Vite负责把工地搭起来pnpm负责更高效地管理材料.env负责切换不同环境配置proxy负责打通本地联调- 路径别名负责让项目结构更清晰
ESLint / Prettier负责让团队代码更统一
这些知识点看上去不像 Vue 语法那样“直接产出页面”,但它们决定了你写项目时是否顺手、是否稳定、是否接近真实团队开发方式。
13. 下篇可以学什么
最适合接在这篇之后的内容,就是:
13.1 Vue 3 基础入门
继续学习:
- 模板语法
- 指令系统
- 响应式数据
- 生命周期
- 组件通信
13.2 Vue + Axios 请求页面
继续学习:
- 在组件中请求接口
- 列表页和表单页怎么组织
- 加载中、错误、空状态怎么处理
建议你先进入 Vue 基础,再接 Vue + Axios,这样学习节奏会更稳。