devServer配置
在 Vue 2 项目中,特别是当你使用 Vue CLI 创建的项目时,可以通过配置 vue.config.js
文件来设置代理,以解决开发环境中的跨域问题。Vue CLI 使用了 webpack 的 devServer
配置项来支持这一功能。
1. 创建或编辑 vue.config.js
首先,在你的项目根目录下找到或创建一个名为 vue.config.js
的文件(如果不存在的话)。这是一个可选的配置文件,Vue CLI 会自动识别它。
2. 配置代理
在 vue.config.js
中,你可以通过 devServer.proxy
来配置代理。这里是一个简单的例子,展示了如何将 /api
开头的请求代理到另一个服务器地址:
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000', // 目标服务器 host
changeOrigin: true, // 是否改变请求的源头
pathRewrite: {
'^/api': '' // 重写路径,去掉路径前缀 /api
}
}
}
}
}
在这个例子中:
- 所有以
/api
开头的请求都会被代理到http://localhost:3000
。 changeOrigin
设置为true
,这样可以修改请求头中的 host 为target
,有助于解决一些跨域问题。pathRewrite
选项允许你重写 URL 路径,例如,将/api/some/path
转换为/some/path
发送到目标服务器。
3. 多个代理规则
如果你需要针对不同的路径前缀设置不同的代理规则,可以直接添加更多的键值对到 proxy
对象中:
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
pathRewrite: { '^/api': '' }
},
'/static': {
target: 'http://localhost:4000',
changeOrigin: true,
pathRewrite: { '^/static': '/public/static' }
}
}
}
}
4. 启动开发服务器
完成上述配置后,只需正常启动你的 Vue 项目(通常通过运行 npm run serve
或 yarn serve
),这些代理规则就会生效。
需要注意的是,这种代理配置仅适用于开发环境。对于生产环境,你需要根据实际情况考虑是否以及如何实现类似的反向代理功能,这可能涉及到 Nginx、Apache 等服务器的配置。
这样做不仅解决了开发过程中的跨域问题,也使得前后端分离的开发模式更加顺畅。
使用 CDN 加载外部资源
基本概念
CDN(内容分发网络) 是一种分布式服务器系统,旨在将网页的内容(如 JavaScript 文件、CSS 样式表、图片等)分发到全球各地的多个位置,以便用户可以从最近的服务器获取所需资源,从而提高加载速度。
在 Vue 项目中,我们通常会考虑将一些常用的第三方库(例如 vue
, vue-router
, axios
等)通过 CDN 引入,而不是将其包含在最终构建的包里。
1. 在 HTML 中引入 CDN 资源
首先,在你的 public/index.html
文件中添加需要通过 CDN 加载的库。例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue App</title>
<!-- 引入 Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<!-- 引入 Vue Router -->
<script src="https://cdn.jsdelivr.net/npm/vue-router@3"></script>
<!-- 其他你需要的库 -->
</head>
<body>
<div id="app"></div>
</body>
</html>
2. 配置 vue.config.js
排除这些库
为了让 Webpack 不把这些依赖打包进最终的 bundle 文件中,我们需要配置 externals
。创建或编辑 vue.config.js
文件如下:
module.exports = {
configureWebpack: {
externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
// 添加其他你希望通过 CDN 加载的库
}
}
}
这里的 'vue': 'Vue'
表示在代码中引用 vue
模块时,实际上会指向全局变量 Vue
。同样地,对于 vue-router
,它对应的是 VueRouter
。
详细解析:externals
是如何“找到” Vue
的?
我们来一步步拆解这个过程:
1. 你写了这样的代码(源码)
// main.js 或任何组件中
import Vue from 'vue'
import VueRouter from 'vue-router'
new Vue({
router: new VueRouter({ ... }),
render: h => h(App)
}).$mount('#app')
2. Webpack 编译时看到 import Vue from 'vue'
Webpack 开始解析依赖,发现你要引入一个叫 'vue'
的模块。
3. Webpack 查看 externals
配置
它检查 vue.config.js
中的 externals
:
externals: {
'vue': 'Vue'
}
这行配置的意思是:
“如果你遇到
import ... from 'vue'
,别打包vue
这个包,直接使用运行时环境中全局变量Vue
。”
4. Webpack 生成的代码(简化版)
最终生成的 bundle 中,不会包含 Vue 的源码,而是生成类似这样的代码:
// webpack 模拟生成的代码
var Vue = window.Vue; // ← 注意这里!它直接从 window 上取 Vue
var VueRouter = window.VueRouter;
new Vue({
router: new VueRouter({ ... })
}).$mount('#app');
所以,Vue
是从哪里来的?
👉 来自你在 index.html
中通过 <script>
标签加载的 CDN 文件!
<!-- public/index.html -->
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
这个 CDN 脚本执行后,会做一件事:
// Vue.js 内部大致会这样暴露自己
window.Vue = Vue; // 把 Vue 构造函数挂载到全局 window 对象上
这样,当 Webpack 生成的代码执行 window.Vue
时,就能正确拿到 Vue 实例了。
验证:你可以在浏览器控制台中看到
打开浏览器开发者工具,输入:
console.log(Vue) // 应该输出 Vue 构造函数
console.log(window.Vue) // 和上面一样
如果输出了 Vue 的构造函数,说明 CDN 加载成功,externals
也能正确找到它。
总结:externals
找 Vue
的完整链路
import Vue from 'vue'
↓
Webpack 查看 externals 配置
↓
externals: { 'vue': 'Vue' } → “去全局找 Vue”
↓
浏览器执行 <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
↓
Vue.js 内部执行:window.Vue = Vue
↓
运行时:window.Vue 存在
↓
Webpack 生成的代码:var Vue = window.Vue ✅ 成功获取
⚠️ 注意事项
CDN 必须在 bundle 之前加载
<script>
标签必须放在<div id="app">
之前,否则你的 bundle 执行时window.Vue
还不存在,会报错。版本要一致
本地package.json
中的 Vue 版本最好和 CDN 的版本一致,避免 API 差异。生产环境专用
通常只在生产环境使用 CDN,开发环境可以正常打包,避免网络问题影响开发。
结论:externals
不是“主动去找”,而是 “告诉 Webpack 别打包,运行时去 window
上拿”,而 window.Vue
是由 CDN 脚本赋值的。两者配合,缺一不可。