vite插件与发包的一次简单的尝试

简介

在和群友聊天的过程中了解到每次配置别名都需要在tsconfig与vite.config.ts中设置有点小麻烦希望能有工具解决一下 在解决过程中也了解到已有的解决方案,各位根据自己需要选择

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!

相关推荐
y先森3 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy3 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189113 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿4 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡5 小时前
commitlint校验git提交信息
前端
虾球xz6 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇6 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒6 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员6 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐6 小时前
前端图像处理(一)
前端