客户端配置项的特别
客户端要实现动态加载配置项,也就是文件服务器每次读取到不同的内容,从而去渲染不同的页面结果。这种动态通常用于改动不大的场景,例如页面布局,某些功能的开关。
而浏览器客户端不是 NodeJS 环境,没办法通过 fs 之类的库去读取文件中的内容,没办法 writeFile 等去写入文件,而通常需要在页面打开时请求到文件服务器存储的所有配置文件,然后通过 fetch 去动态读取解析,然后保存起来。
下面是一个配置项,其中配置了 2 个配置项。我们希望部署在本地服务器或者 nginx 之类的服务器上的页面,通过修改 enable 后,页面刷新后会立刻接受到该值,然后 javascript 执行不同的结果。
{
"isFlex": {
"enable": true,
"comment": "是否xxx采用弹性布局"
},
"findImmediatly": {
"enable": false,
"comment": "是否在xxx之后立刻执行find"
}
}
前端怎么请求配置项文件
那么要配置项,首先配置文件需要让人能够易读,所以我们会约定好 json 格式等,然后让这个文件在打包后格式保持原样,在页面加载的时候还能读取这个配置。
以 Vite 为例,要让配置项能够在打包的时候不被修改,而是直接复制到打包文件夹下,我们需要把文件放在根路径 public 文件夹下。重要的是我不能不能将它引入到源码中,也就是不能通过 import 导入这个文件然后通过 parser 解析成我们要的 js 对象。这是 vite 的规定,因为 静态文件如果引入到源码中,它会被打包成 js,最后保留在 js 代码中,这个时候配置项的动态性已经丢失,因为打包文件会把我们最后一次修改的配置项 json,以实实在在的变量值写入到 js 源码中,成了固定的值。
那么我们要访问这个文件,例如configuration.json,在项目中访问中的路径是/configs/configuration.json,这个文件显然是放在public文件夹下的。
那如果 import 去引入 public 下的 json 文件等,会报错。意思是说,我们不能 import 一个 public 下的文件。
Cannot import non-asset file /configs/configuration.json which is inside /public. JS/CSS files inside /public are copied as-is on build and can only be referenced via <script src> or <link href> in html. If you want to get the URL of that file, use /configs/configuration.json?url instead.
因此我们借用 fetch 去请求这个文件。例如下面这个函数,我们传入/configs/configuration.json给第一个参数 path,这样 fetch 的时候会寻找根目录下的configs/configuration.json文件,而在打包后的 dist 文件夹下面确实有 configs 文件夹内,下面有 configuration.json,这样文件处理器会将这个文件发送给 fetch 的请求方——浏览器,从而获得我们想要的文件。
export default async <T>(path: string, errorMsg?: string) => {
const data: T = await fetch(path)
.then((res) => res.json())
.catch(() => {
console.error(errorMsg ? errorMsg : `请检查${path}文件格式是否正确`);
});
return data;
};
这种方式其实就是借用后端服务器,去转接我们的路径。只不过这个服务器是文件服务器,而不是我们写的后端服务器。