本文作者:云初冀北

WindiCSS实现加载windi.config.ts配置文件详解

WindiCSS实现加载windi.config.ts配置文件详解摘要: 背景我们知道WindiCSS的配置文件既支持js后缀也支持ts后缀,即:windi.config.js和windi.config.ts我们在 vscode 安装的WindiCSS...

?=背景

我们知道WindiCSS配置文件既支持JS后缀也支持TS后缀,即:winDI.config.jswindi.config.ts

WindiCSS实现加载windi.config.ts配置文件详解

我们在 VSCode 安装WindiCSS intelliSense也支持读取多种后缀格式的配置文件。vscode 基于 electron 实现Electron 底层是一个Node.js + v8的集成终端,支持运行 js 格式的代码WindiCSS IntelliSense最终打包出来的运的代码也是 js 格式的代码

WindiCSS IntelliSense是怎么实现 js 文件加载 ts 文件的呢?

这个问题困惑了我大半天,正好最近在写脚手架,需要支持加载 ts 后缀的配置文件

于是下定决心,把这个问题搞清楚,最后终于在源码里找到了答案

解惑

WindiCSS IntelliSense源码

我们将WindiCSS IntelliSense源码直接clone下来
$ git clone https://github.com/windicss/windicss-intellisense.Git 
找到读取配置文件的核心代码
<!--src\lib\index.ts--> // ... async init() { try {   const config = await this.lOAdConfig();   this.PROCessor = new Processor( config   ) as Processor;   this.attrPrefix = this.processor.config('attributify.prefix') as | string | undefined;   this.variants = this.processor.resolveVariants();   this.colors = flatColors( this.processor.theme('colors', {}) as colorobject   );   this.register(); } catch (error) {   Log.error(error); }   }   // ... 
关键实现
<!--src\lib\index.ts--> // ... import { loadConfig } from 'unconfig'; // ... async loadConfig(File?: string) { if(!workspace.workspaceFolders) return; const { config, sources } = await loadConfig<Config>({   sources: [ {   files: 'windi.config',   extensiONs: ['ts', 'mts', 'cts', 'js', 'mjs', 'cjs'], }, {   files: 'tailwind.config',   extensions: ['ts', 'mts', 'cts', 'js', 'mjs', 'cjs'], },   ],   Merge: false,   cwd: workspace.workspaceFolders[0].uri.fspath, }); Log.info(`loading Config File: ${sources}`); return config;   } // ... 

从关键实现的代码上看,我们就找到了答案:使用unconfig来实现加载不同后缀的文件

WindiCSS实现加载windi.config.ts配置文件详解

看到这里,我们还是没有搞懂:为什么js能加载ts,我们继续深入了解一下unconfig的内部实现

unconfig源码

我们将unconfig源码直接clone下来
git clone https://github.com/antfu/unconfig.git 
核心代码
<!--src\index.ts--> // ... import jiti from 'jiti' // ... async function loadConfigFile<T>(filepath: string, source: LoadConfigSource<T>): Promise<LoadConfigResult<T> | undefined> {   let config: T | undefined   let parser = source.parser || 'auto'   let bundleFilepath = filepath   let code: string | undefined   async function read() { if (code == null)   code = await fs.readFile(filepath, 'utf-8') return code   }   if (source.transform) { const transfORMed = await source.transform(await read(), filepath) if (transformed) {   bundleFilepath = join(dirname(filepath), `__unconfig_${basename(filepath)}`)   await fs.writeFile(bundleFilepath, transformed, 'utf-8')   code = transformed }   }   if (parser === 'auto') { try {   config = JSON.parse(await read())   parser = 'json' } catch {   parser = 'reqUIre' }   }   try { if (!config) {   if (typeof parser === 'function') { config = await parser(filepath)   }   else if (parser === 'require') { config = await jiti(filepath, {   interopDefault: true,   cache: false,   requireCache: false,   v8cache: false,   esmResolve: true, })(bundleFilepath)   }   else if (parser === 'json') { config = JSON.parse(await read())   } } if (!config)   return const rewritten = source.rewrite   ? await source.rewrite(config, filepath)   : config if (!rewritten)   return undefined return {   config: rewritten,   sources: [filepath], }   }   catch (e) { if (source.skIPOnError)   return throw e   }   finally { if (bundleFilepath !== filepath)   await fs.unlink(bundleFilepath).catch()   } } // ... 
把核心代码进行精简,找到关键实现
<!--src\index.ts--> // ... import jiti from 'jiti' // ... async function loadConfigFile<T>(filepath: string, source: LoadConfigSource<T>): Promise<LoadConfigResult<T> | undefined> { // ... try { if (!config) {   if (Typeof parser === 'function') { config = await parser(filepath)   }   else if (parser === 'require') { config = await jiti(filepath, {   interopDefault: true,   cache: false,   requireCache: false,   v8cache: false,   esmResolve: true, })(bundleFilepath)   }   else if (parser === 'json') { config = JSON.parse(await read())   } } // ... } // ... 

从关键实现的代码上看,我们就找到了答案:使用jiti来实现 js 文件加载 ts 文件时,动态编译 ts 文件并返回结果

WindiCSS实现加载windi.config.ts配置文件详解

jiti文档中这么描述:Runtime TypeScript and ESM support for node.js (CommonJS),我们可以更加粗暴地理解为require-ts

为了让大家更好地理解unconfig的工作流程,楼主根据上述的unconfig核心代码,整理出一个unconfig核心工作原理流程图

WindiCSS实现加载windi.config.ts配置文件详解

关于js文件如何加载ts文件的疑惑得以解开

代码实践

看过没练过,等于没看过 - B 站梦觉教游泳

我们在写脚手架的时候可以直接使用unconfig读取配置文件即可,例如:读取Vite.config.ts可以这么实现

import { loadConfig } from 'unconfig' const { config } = await loadConfig({   sources: [ {   files: 'vite.config',   async rewrite(config) { return await (typeof config === 'function' ? config() : config)   }, },   ] })

以上就是WindiCSS实现加载windi.config.ts配置文件详解的详细内容,更多关于WindiCSS加载windi.config.ts的资料请关注云初冀北其它相关文章!

免责声明
本站提供的资源,都来自网络,版权争议与本站无关,所有内容及软件的文章仅限用于学习和研究目的。不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负,我们不保证内容的长久可用性,通过使用本站内容随之而来的风险与本站无关,您必须在下载后的24个小时之内,从您的电脑/手机中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。侵删请致信E-mail:Goliszhou@gmail.com
$

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

阅读
分享

发表评论

快捷回复:

评论列表 (暂无评论,151人围观)参与讨论

还没有评论,来说两句吧...