简介
在和群友聊天的过程中了解到每次配置别名都需要在tsconfig与vite.config.ts中设置有点小麻烦希望能有工具解决一下 在解决过程中也了解到已有的解决方案,各位根据自己需要选择
- vite-tsconfig-paths 大致思路是解析ts路径然后拦截vite的路径处理
- vite-plugin-tsconfig-paths 没仔细看
- vite-plugin-tsconfig-paths2 十分简单的路径替换写入config的alias 可能考虑不周谨慎选择(我写的)
vite钩子
最开始的方案是选择vite的钩子configResolved,但是将路径解析后push到config.resolve.alias数组后无法正确解析路径。 后选择config钩子,效果是解析用户配置前调用,思路即为将tsconfig paths解析一下存放到config.resolve.alias对象中,让vite解析。存在问题有root如果没有配置则为未定义,使用process.cwd()暂作处理
ts
let projectRoot = process.cwd();
let workspaceRoot!: string;
let { root } = opts;
if (root) {
root = path.resolve(projectRoot, root);
} else {
workspaceRoot = searchForWorkspaceRoot(projectRoot);
}
上述代码是对路径的处理vite项目路径 tsconfig路径 与在使用插件传入的路径的一个处理
ts
const parseOptions: tsconfck.TSConfckParseOptions = {
cache: new tsconfck.TSConfckCache(),
};
const parsedProjects = new Set(
await Promise.all(
projects.map((tsconfigFile) =>
tsconfck.parse(tsconfigFile, parseOptions).catch((error) => {
return null;
})
)
)
);
上述代码是使用tsconfck解析tsconfig文件后得到parsedProjects数组
ts
function createResolver(project: tsconfck.TSConfckParseResult, root: string) {
const paths: Record<string, string[]> =
project.tsconfig.compilerOptions.paths;
const result: Record<string, string> = {};
const keys = Object.keys(paths);
// ignore extra paths
for (const key of keys) {
const firstPath = paths[key]?.[0];
if (key.endsWith(END) && firstPath.endsWith(END)) {
const aliasKey = key.replace(END, "");
result[aliasKey] = normalizePath(
path.resolve(root, firstPath.replace(END, ""))
);
} else {
result[key] = normalizePath(path.resolve(root, firstPath));
}
}
return result;
}
上述代码首先是从tsconfig读取paths设置然后寻找通配符*如果找到则对健进行替换作为vite alias的新键,之后获取对应值的数组第一项将其与root路径使用resolve方法拼起来获取绝对路径作为alias的值 最后获取所有的结果返回出去
ts
parsedProjects.forEach((project) => {
if (!project) {
return;
}
const aliasFromPaths = createResolver(project, projectRoot);
for (const key of Object.keys(aliasFromPaths)) {
// @ts-ignore
config.resolve.alias[key] = aliasFromPaths[key];
}
});
return config;
将解析配置获取的对象写入config.resolve.alias大功告成
打包
打包选择tsup(一个基于esbuild的ts打包工具优点是很快) 在项目的package.json中的scrpt写入"bundle": "tsup-node src/index.ts --dts --format cjs,esm"含义是使用tsup打包出cjs与ems模块规范的包,并且生产描述文件 在package.json中加入以下设置
json
"files": [
"dist"
],
"main": "dist/index.js",
"module": "dist/index.mjs",
"exports": {
"import": "./dist/index.mjs",
"require": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
}
},
files字段规定npm发包时上穿的文件默认包含package.json与readme.md main module exports规定包的不同形式的入口文件
调试
在项目平级目录新建vite vue3 ts项目并在packag.josn增加如下开发依赖
json
"vite-plugin-tsconfig-path": "link:.."
一定要使用pnpm安装以来别的玩意不支持 意思就是链接到上级目录
github workflow
yml
name: Publish to NPM registry
on:
release:
types: [created]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
registry-url: https://registry.npmjs.com/
- name: Setup pnpm
uses: pnpm/action-setup@v2.2.4
with:
version: 8.2.0
- name: Get version
run: echo "TAG_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Get git head
run: echo "GIT_HEAD=${GITHUB_SHA}" >> $GITHUB_ENV
- name: Gen npmrc
run: echo "//registry.npmjs.com/:_authToken=${{ secrets.NPM_PUBLISH_TOKEN }}" >> ./.npmrc
- name: who am i
run: npm who am i
- name: Build&publish
run: sh ./scripts/publish.sh
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_PUBLISH_TOKEN}}
TAG_VERSION: ${{env.TAG_VERSION}}
GIT_HEAD: ${{env.GIT_HEAD}}
REGISTRY: https://registry.npmjs.com/
NODE_OPTIONS: --max-old-space-size=4096
上述配置告诉github工作流在我创建tag的时候拉取打包环境,把版本信息写入环境变量,设置npm user,并执行发版脚本
shell
#!/bin/sh
set -e
pnpm i --frozen-lockfile --ignore-scripts
pnpm run update-version
pnpm run build
npm publish --access public
echo "✅ Publish completed"
shell脚本 首先下载依赖,然后更新版本,执行build命令,发版本
ts
import path from "node:path";
import { fileURLToPath } from "node:url";
import process from "node:process";
import consola from "consola";
import chalk from "chalk";
import { findWorkspacePackages } from "@pnpm/find-workspace-packages";
import type { Project } from "@pnpm/find-workspace-packages";
export const projectRoot = path.resolve(
fileURLToPath(import.meta.url),
"..",
".."
);
const getWorkspacePackages = () => findWorkspacePackages(projectRoot);
function errorAndExit(err: Error): never {
consola.error(err);
process.exit(1);
}
async function main() {
const version = process.env.TAG_VERSION || "0.0.1";
const gitHead = process.env.GIT_HEAD;
if (!version) {
errorAndExit(new Error("No version"));
}
consola.log(chalk.cyan(`$new version: ${version}`));
consola.log(chalk.cyan(`$GIT_HEAD: ${gitHead}`));
consola.debug(
chalk.yellow("Updating package.json for vite-plugin-tsconfig-paths2")
);
const pkgs = Object.fromEntries(
(await getWorkspacePackages()).map((pkg) => [pkg.manifest.name!, pkg])
);
const BaicieCli = pkgs["vite-plugin-tsconfig-paths2"];
const writeVersion = async (project: Project) => {
await project.writeProjectManifest({
...project.manifest,
version,
gitHead,
} as any);
};
try {
await writeVersion(BaicieCli);
} catch (error) {
errorAndExit(error as Error);
}
consola.success(
chalk.green(
`package vite-plugin-tsconfig-paths2 updated successfully to version ${version}`
)
);
}
main();
这段是更新版本的代码 借助pnpm的工具函数findWorkspacePackages找到对应的package.json并且写入版本信息与git信息 之后就是npm publish了发版成功后就可以下载使用了
最后
新人多多关照哈哈 如果你想变强b站 掘金搜索小满zs!