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!

相关推荐
小白学前端66614 分钟前
React Router 深入指南:从入门到进阶
前端·react.js·react
web1309332039835 分钟前
前端下载后端文件流,文件可以下载,但是打不开,显示“文件已损坏”的问题分析与解决方案
前端
outstanding木槿1 小时前
react+antd的Table组件编辑单元格
前端·javascript·react.js·前端框架
好名字08211 小时前
前端取Content-Disposition中的filename字段与解码(vue)
前端·javascript·vue.js·前端框架
隐形喷火龙2 小时前
element ui--下拉根据拼音首字母过滤
前端·vue.js·ui
m0_748241122 小时前
Selenium之Web元素定位
前端·selenium·测试工具
风无雨2 小时前
react杂乱笔记(一)
前端·笔记·react.js
前端小魔女2 小时前
2024-我赚到自媒体第一桶金
前端·rust
鑫~阳2 小时前
快速建站(网站如何在自己的电脑里跑起来) 详细步骤 一
前端·内容管理系统cms
egekm_sefg2 小时前
webrtc学习----前端推流拉流,局域网socket版,一对多
前端·学习·webrtc