Vite 是如何加载 vite.config.ts 配置文件的?

AI 概述
Vite 作为一个 npm 依赖库,它是如何加载我们项目中的vite.config.ts文件的? 你可能会觉得没什么吧,不就是通过文件路径 require 或 import 一下吗?或者使用readFile不也能读取到文件内容吗? 但是,如果你站在 Vite 库的开发者角度思考,你会发现,事情没有这么简单。 首先,readFile肯定是不可以的。因为我们不是要...

Vite 作为一个 npm 依赖库,它是如何加载我们项目中的vite.config.ts文件的?

你可能会觉得没什么吧,不就是通过文件路径 require 或 import 一下吗?或者使用readFile不也能读取到文件内容吗?

但是,如果你站在 Vite 库的开发者角度思考,你会发现,事情没有这么简单。

  1. 首先,readFile肯定是不可以的。因为我们不是要拿到文件的内容,而是要执行里面的代码,并且拿到执行后的结果;
  2. 还需要考虑配置文件使用的是 cjs 还是 esm,以此来决定使用require还是import来进行加载;
  3. 如果配置文件是 js 或者 JSON 类型,直接require 自然是没问题的;但是如果配置文件是 ts,那就没法直接require了。

这篇文章主要讨论配置文件是 ts 的情况。

先看一个 ts 的配置文件:

import { defineConfig } from 'vite';

export default defineConfig({
  // ...
});

对于 Vite 来说,vite.config.ts配置文件其实就是一个模块。只不过这个模块不是库内部的文件模块,而是通过用户提供的一个文件模块。

自然,要使用一个模块,当然是require这个模块就行了;如果是 ES Module,就使用import

但是,由于 node 本身无法直接执行 ts 代码。因此,我们在执行这个模块代码之前,必须要先将此模块代码转成 js 代码,然后再requireimport

那么 Vite 是如何将 ts 转成 js 代码的呢?

从 Vite 官网可以找到这样一段话:

Vite 官网一段话

我们只需要关注第一句话:默认情况下,Vite 会使用 esbuild 将配置文件打包成一个临时文件,然后再加载该临时文件

关键词:esbuild,我们前往 Vite 源码,就能看到:

Vite 源码

其中build函数就是从esbuild库中导入的。它的作用就是将vite.config.ts配置文件编译并打包成一个js 模块,然后写入一个临时的 js 文件中并进行加载。

我们可以写一个简化版的实现:

/**
 * 导出一个定义配置文件的函数
 */
exportfunction defineConfig(config: UserConfig) {
return config;
}

// 加载配置文件
exportasync funcrion loadConfig() {
const configFile = path.resolve('vite.config.ts');
const tmpFile = path.resolve('vite.config.js');

// 1. 编译打包
await esbuild.build({
    entryPoints: [configFile],
    platform: 'node',
    format: 'cjs',
    outfile: tmpFile,
  });

// 2. 加载模块
const mod = require(tmpFile);
  fs.rm(tmpFile);
return mod.default || mod;
}

很简单,就是先编译,再加载。

也许强迫症的你会对产生的“临时文件”耿耿于怀,有没有什么办法不产生临时文件呢?

如果你使用的是 cjs(上面的例子),那么恭喜你,是可以做到的。

// 加载配置文件
exportasync funcrion loadConfig() {
// 1. 编译打包
const result = await esbuild.build({
    entryPoints: [path.resolve('vite.config.ts')],
    platform: 'node',
    format: 'cjs',
    write: false,
  });

// 2. 加载模块
constmodule = new Module('vite.config.ts');
module.paths = Module._nodeModulePaths(process.cwd());
module._compile(result.outputFiles[0].text, 'vite.config.ts');

  return module.exports.default;
}

如果是esm模块,网上说可以使用data URL实现(import('data:...')),这里就不去探讨了。

以上的方法都是基于esbuild来实现的,如果你觉得使用麻烦的话,那么你或许可以试试ts-node

// 加载配置文件
exportasyncfunction loadConfig() {
const tsNode = awaitimport('ts-node');
  tsNode.register({
    transpileOnly: true,
    compilerOptions: {
      module: 'commonjs'
    }
  });

  const mod = await import(path.resolve('vite.config.ts'));
  return mod.default ?? mod;
}

ts-node这个库可以让你的 Nodejs 支持加载 ts 模块,它是在运行时动态将 ts 代码转译成 js,然后再交给 Node 来执行

以上关于Vite 是如何加载 vite.config.ts 配置文件的?的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

「点点赞赏,手留余香」

1

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » Vite 是如何加载 vite.config.ts 配置文件的?

发表回复