- 问题现象
-
本地做了两个项目,将项目推送到github中,想要同时部署在github pages和vercel上。结果第一个项目在github pages上可以正常访问,在vercel上访问失败。另一个项目在vercel上可以正常访问,在githubpages中却访问失败。报错内容都是访问时CSS加载失败。
-
一通研究,发现是publicPath/base搞的鬼。
- 我的第一个项目是使用vite+vue3+element ui搭建的To-Do List项目,刚开始在vite.config.js中设置了base,为了方便在Github Pages上部署。
javascript// vite.config.js import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [vue()], base: '/vue-todo-list/' })
- 我的第二个项目是使用vue2和@vue/cli5搭建的天气展示项目。在vue.config.js根据NODE_ENV动态设置了publicPath的值。
javascript// vue.config.js const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true, publicPath: process.env.NODE_ENV === 'production' ? '/weather-app/' : '/' })
- 原理分析
- 在 GitHub Pages 或Vercel上项目空白的问题,很可能是因为构建的静态资源路径与 GitHub Pages 或Vercel的部署方式不匹配导致的。
- 不同项目对于如何处理
静态资源路径问题
的配置方式不同- Vue CLI 项目通常在
vue.config.js
文件中配置 publicPath 。 - Vite 项目通常在
vite.config.js
文件中配置 base 。
- Vue CLI 项目通常在
- 不同平台的部署方式不同
- GitHub Pages通常将项目部署到项目仓库子目录下,此时需要将
publicPath
或base
设置为/<REPO_NAME>/
。 - Vercel通常将项目部署到根目录下,此时需要将
publicPath
或base
设置为/
。 - 在开发环境下,通常是
/
。
- GitHub Pages通常将项目部署到项目仓库子目录下,此时需要将
- 需要设置正确的
publicPath
或base
,以便 GitHub Pages和Vercel 都能够正确地找到CSS、JavaScript、图片等静态资源。
- 不同项目对于如何处理
- 解决方案
- 动态配置
publicPath
或base
(环境变量+条件判断)。-
Vite项目
- 修改vite.config.js,根据DEPLOY_TARGET是否为'github-pages'来决定base的值
javascript// vite.config.js import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' const isGitHubPages = process.env.DEPLOY_TARGET === 'github-pages' const base = isGitHubPages ? '/vue-todo-list/' : '/' export default defineConfig({ plugins: [vue()], base })
- 修改package.json,在部署到Github-pages上需要执行的"deploy"命令中添加
DEPLOY_TARGET=github-pages
。相当于在部署到Github-pages前先修改DEPLOY_TARGET的值。
json// package.json { // ..., "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview", "deploy": "DEPLOY_TARGET=github-pages npm run build && gh-pages -d dist" }, // ... }
-
Vue CLI项目
*- 修改vue.config.js,根据NODE_ENV以及DEPLOY_TARGET的值来决定publicPath的值
javascript// vue.config.js const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true, publicPath: (() => { if (process.env.NODE_ENV === 'production') { if (process.env.DEPLOY_TARGET === 'github-pages') { return '/weather-app/' } else if (process.env.DEPLOY_TARGET === 'vercel') { return '/' } } return '/' // 默认开发环境 })() })
- 修改package.json,在部署到Github-pages上需要执行的"deploy"命令中添加
DEPLOY_TARGET=github-pages
。相当于在执行build命令前先修改DEPLOY_TARGET的值。
json// package.json { // ..., "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build", "lint": "vue-cli-service lint", "deploy": "DEPLOY_TARGET = github-pages bash deploy.sh" }, // ... }
- 在Vercel里的Build and Deployment Setting中修改Build Command,在npm run build之前添加
DEPLOY_TARGET=vercel
。相当于在执行build命令前先修改DEPLOY_TARGET的值。Framework Preset选择了Vue.js时,点击Build Command右侧的Override即可修改。
-