Vue
在 vue 部署到 github pages 时,我们可以借助 vue 脚手架可以读取 --mode
命令参数的特性,自定义一个 github 环境。
-
在项目根目录下建立
.env.github
:NODE_ENV = 'github' VUE_APP_PATH = '/repo-name/'
-
在
package.json
添加 script :"scripts": {"build": "vue-cli-service build","github": "vue-cli-service build --mode github",}
此时执行
yarn build
就是 production 环境,执行yarn github
就是 github 环境,他会自动读取.env.github
文件内的全局变量,从而我们在 webpack 配置 publicPath 即可。 -
在
vue.config.js
内配置 publicPath :module.exports = {publicPath: process.env.NODE_ENV != 'github' ? '/' : process.env.VUE_APP_PATH }
由此就解决了 github pages 部署子路径的问题,此时该 publicPath
会同步到 process.env.BASE_URL
。
React
PUBLIC_URL 的限制
对于 react 来说,首先 PUBLIC_URL
(等同于 vue 中的 BASE_URL
)是要被 react 打包时特殊处理的,并不是我们如何配就如何使用。
这里说的特殊处理即结尾去斜线的机制,即使指定 PUBLIC_URL
为 /
同样也要被去空。
路由匹配的严格
对于 react 的路由,并不会自动添加 PUBLIC_URL
,所以部署到子路径上,路由 path 都要经过添加子路径处理。
看到这里,可能会想到,既然 vue 里我从 webpack 里配置了 publicPath
,他就会帮我们添加路由前缀,并且同步到 BASE_URL
解决资源前缀,那么我们在 react 里也注入把 publicPath
改掉不就好了?
追溯 webpack.publicPath
我们开一份 eject 的 react 项目,可以清楚的发现在 webpack.config.js
内所有的 publicPath
都采用了 paths.publicUrlOrPath
:
继续追溯 paths.js
中的 publicUrlOrPath
来源:
可以知道,他还是来自于 PUBLIC_URL
。
那么 PUBLIC_URL
哪里来?在 webpack.config.js
内可以找到:
这里也写了去尾 /
机制,react 认为尾部你可以写 /
,但是我会帮你去掉。
到此为止,应该像 vue 一样配置 webpack 的 publicPath
是不现实的,因为他最终还是要从 .env
文件中读取 PUBLIC_URL
。
解决
既然如此,我们在 .env.production
文件内配置 PUBLIC_URL
:
# 部署到 Github Pages 使用,正常生产环境请注释掉本行
PUBLIC_URL = '/repo-name'
在路由表内用函数处理 path :
const rawPath = (path) => {return process.env.NODE_ENV === 'development' ? path : process.env.PUBLIC_URL + path
}
对于一个路由的 path 来说:
{path: rawPath('/'),exact: true,// ...
},
{path: rawPath('/about'),exact: true,// ...
},
{path: '*',exact: false,// ...
},
到此为止,我们只解决了两件事情:
-
配置了
PUBLIC_URL
以便于静态资源在子路径上加载,此PUBLIC_URL
在配置时一定会被去尾斜线,我们不需要写尾斜线。 -
给所有路由匹配添加前缀,就是我们的
PUBLIC_URL
。
此问题到此解决。