Vite笔记之14-resolve.alias 原理

621 阅读3分钟

本文主要介绍vite配置文件中,别名配置的原理。

案例说明

1. 通用配置

  1. 目录结构
├─aliasResolve.js // 别名处理插件
├─index.html
├─main.js
├─vite.config.js
├─src
|  └test.js
  1. main.js
import "@/test.js";
  1. vite.config.js
const path = require("path");

module.exports = {
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src"),
    },
  },
};
  1. 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;
};
  1. 获取别名配置的键值对:使用Object.entries(aliasConf)获取别名配置对象的所有键值对,存储在entries数组中。每个键值对都是一个数组,其中第一个元素是别名,第二个元素是实际路径。

  2. 遍历别名配置:使用forEach遍历entries数组中的每个别名配置。

  3. 处理路径

    • 首先,将实际路径中的反斜杠(``,Windows路径分隔符)替换为正斜杠(/),以确保路径格式的一致性。
    • 然后,找到实际路径中/src的索引位置(这里假设所有路径都包含/src,这可能是为了简化处理或满足特定需求)。注意,这里对Windows路径进行了特别处理,但在注释中提到了在macOS上可能不需要这种替换。
    • 使用slice方法从/src的索引位置开始截取实际路径的剩余部分,赋值给realPath。这一步假设我们只对/src之后的部分感兴趣,可能是为了将别名替换为相对于src目录的路径。
  4. 替换别名:在JSContent中查找所有的别名(alias),并将它们替换为realPath。同时,再次将所有反斜杠替换为正斜杠,以确保路径的一致性。这一步确保了即使原始JavaScript内容中的路径使用了Windows风格的路径分隔符,替换后的路径也会使用正斜杠。

  5. 返回更新后的内容:遍历完成后,返回更新后的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