本文主要介绍vite配置文件中,别名配置的原理。
案例说明
1. 通用配置
- 目录结构
├─aliasResolve.js // 别名处理插件
├─index.html
├─main.js
├─vite.config.js
├─src
| └test.js
- main.js
import "@/test.js";
- vite.config.js
const path = require("path");
module.exports = {
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
};
- aliasResolve.js
主要处理内容中/src
module.exports = function (aliasConf, JSContent) {
const entries = Object.entries(aliasConf);
let lastContent = JSContent;
entries.forEach((entry) => {
const [alias, path] = entry;
const srcIndex = path.replace(/\\/g,'/').indexOf("/src") // windows 下
//const srcIndex = path.indexOf("/src"); //mac
const realPath = path.slice(srcIndex, path.length);
lastContent = JSContent.replace(alias, realPath).replace(/\\/,'/');
//lastContent = JSContent.replace(alias, realPath);//mac
});
return lastContent;
};
-
获取别名配置的键值对:使用
Object.entries(aliasConf)
获取别名配置对象的所有键值对,存储在entries
数组中。每个键值对都是一个数组,其中第一个元素是别名,第二个元素是实际路径。 -
遍历别名配置:使用
forEach
遍历entries
数组中的每个别名配置。 -
处理路径:
- 首先,将实际路径中的反斜杠(``,Windows路径分隔符)替换为正斜杠(
/
),以确保路径格式的一致性。 - 然后,找到实际路径中
/src
的索引位置(这里假设所有路径都包含/src
,这可能是为了简化处理或满足特定需求)。注意,这里对Windows路径进行了特别处理,但在注释中提到了在macOS上可能不需要这种替换。 - 使用
slice
方法从/src
的索引位置开始截取实际路径的剩余部分,赋值给realPath
。这一步假设我们只对/src
之后的部分感兴趣,可能是为了将别名替换为相对于src
目录的路径。
- 首先,将实际路径中的反斜杠(``,Windows路径分隔符)替换为正斜杠(
-
替换别名:在
JSContent
中查找所有的别名(alias
),并将它们替换为realPath
。同时,再次将所有反斜杠替换为正斜杠,以确保路径的一致性。这一步确保了即使原始JavaScript内容中的路径使用了Windows风格的路径分隔符,替换后的路径也会使用正斜杠。 -
返回更新后的内容:遍历完成后,返回更新后的
JSContent
字符串。
index.js
const Koa = require("koa"); // 不能用esmodule 必须使用commonjs
const fs = require("fs"); // ./ / npm install yarn add ,如果是原生直接取node中找
const path = require("path");
const app = new Koa(); // const app = new Vue()
// 我们不用返回给客户端的吧 而且我们这里约定的名字就叫做vite.config.js
const viteConfig = require("./vite.config");
console.log("打印***viteConfig", typeof viteConfig);
const aliasResolve = require("./aliasResolve");
app.use(async (ctx) => {
if (ctx.request.url === "/") {
const indexContent = await fs.promises.readFile(
path.resolve(__dirname, "./index.html")
);
ctx.response.body = indexContent;
ctx.response.set("Content-Type", "text/html");
}
if (ctx.request.url.endsWith(".js")) {
console.log("打印***ctx.request.url js", ctx.request.url);
// 路径缺少. /main.js
// 直接进行@assets的替换
const mainContent = await fs.promises.readFile(
path.resolve(__dirname, "." + ctx.request.url),
"utf-8"
);
const lastResult = aliasResolve(viteConfig.resolve.alias, mainContent);
console.log("打印***mainContent", mainContent);
ctx.response.body = lastResult;
ctx.response.set("Content-Type", "text/javascript");
}
});
app.listen(5173, () => {
console.log(`
koa v4.1.2 ready in 775 ms
➜ Local: <http://localhost:5173/>
➜ Network: use --host to expose
➜ press h to show help
`);
});
- 当请求 URL 为
/
时,服务器会读取当前目录下的index.html
文件,并将其内容作为响应体返回给客户端,同时设置响应的Content-Type
为text/html
。 - 当请求 URL 以
.js
结尾时,服务器会尝试读取对应的 JavaScript 文件。但这里有一个问题:直接使用"." + ctx.request.url
来拼接文件路径是不正确的,因为它没有考虑到可能存在的别名或基于根目录的路径问题。正确的做法应该是根据 Vite 的配置和别名解析逻辑来找到实际的文件路径。 - 在处理 JavaScript 文件时,通过
aliasResolve
函数(该函数接受 Vite 的别名配置和 JavaScript 文件内容作为参数)来解析别名,并返回处理后的文件内容。然后,将处理后的内容作为响应体返回给客户端,并设置响应的Content-Type
为text/javascript
。