一文学会 ts 构建工具 —— tsup

ops/2024/10/21 23:04:10/

在这里插入图片描述

文章目录

  • 能打包什么?
  • 安装
  • 用法
    • 自定义配置文件
    • 条件配置
    • 在 package.json 中配置
    • 多入口打包
    • 生成类型声明文件
    • sourcemap
    • 生成格式
    • 自定义输出文件
    • 代码分割
    • 产物目标环境
    • 支持 es5
    • 编译的环境变量
    • 对开发命令行工具友好
    • 监听模式 watch
    • 提供成功构建的钩子 onSuccess
    • 压缩产物 minify
    • 自定义 loader
    • Tree shaking
    • 类型检查
    • 支持 CSS (实验性功能)
    • 元数据文件 metafile
    • 自定义 esbuild 插件和配置
    • 注入 cjs 和 esm shims (垫片)
    • 复制文件到输出目录
    • 在项目中使用 tsup
  • 常见问题
    • error: No matching export in "xxx.ts" for import "xxx"

tsup

Bundle your TypeScript library with no config, powered by esbuild.

tsup 号称不用配置文件,打包 ts 库。底层为 esbuild。tsup 这么宣传,说明它肯定做了很多预设封装,不需要太多配置,开箱即用。

rollup 已经是牛夫人了。

能打包什么?

node.js 支持的都能打包,.js, .json, .mjs.。加上 ts 相关的 .ts, .tsx。

安装

npm i tsup -D
# Or Yarn
yarn add tsup --dev
# Or pnpm
pnpm add tsup -D

用法

tsup [...files]

默认打包到 ./dist
能自动排除 node_modules 。
默认打包为 es5,CommonJS,

eg:

tsup src/index.ts src/cli.ts

生成 dist/index.js 和 dist/cli.js

自定义配置文件

可选的文件:

–config 配置项可指定配置文件。

typescript">import { defineConfig } from 'tsup'export default defineConfig({entry: ['src/index.ts'],splitting: false,sourcemap: true,clean: true,
})

条件配置

导出一个函数,tsup cli 会执行这个函数。

typescript">import { defineConfig } from 'tsup'export default defineConfig((options) => {return {minify: !options.watch,}
})

在 package.json 中配置

typescript">{"tsup": {"entry": ["src/index.ts"],"splitting": false,"sourcemap": true,"clean": true},"scripts": {"build": "tsup"}
}

多入口打包

typescript">export default defineConfig({// Outputs `dist/a.js` and `dist/b.js`.entry: ['src/a.ts', 'src/b.ts'],// Outputs `dist/foo.js` and `dist/bar.js`entry: {foo: 'src/a.ts',bar: 'src/b.ts',},
})

生成类型声明文件

typescript">tsup index.ts --dts

sourcemap

typescript">tsup index.ts --sourcemap

生成格式

支持 esm,cjs (默认) 和 iife。

tsup src/index.ts --format esm,cjs,iife
dist
├── index.mjs         # esm
├── index.global.js   # iife
└── index.js          # cjs

如果 package.json 的 type 字段为 module。命名会变成:

dist
├── index.js          # esm
├── index.global.js   # iife
└── index.cjs         # cjs

自定义输出文件

typescript">export default defineConfig({outExtension({ format }) {return {js: `.${format}.js`,}},
})

代码分割

默认支持 esm ,并且默认开启。CJS 需要 --splitting 手动开启。

产物目标环境

target 选项配置构建产物的目标环境,默认是 node16。

可支持:

  • chrome
  • edge
  • firefox
  • hermes
  • ie
  • ios
  • node
  • opera
  • rhino
  • safari

target 也可以指定 js 版本,比如 es2020,es5。

支持 es5

esbuild 是不支持 es5 的。tsup 是怎么做到的?

tsup 会先打包成 es2020,然后通过 SWC 转成 es5。

编译的环境变量

typescript">tsup src/index.ts --env.NODE_ENV production

对开发命令行工具友好

当入口文件如 src/cli.ts 包含 hashbang(即 #!/bin/env node)时,tsup 会自动使输出文件可执行,因此您无需运行 chmod +x dist/cli.js 来手动设置可执行权限。

监听模式 watch

typescript">tsup src/index.ts --watch

可选择忽视监听的文件:

typescript">tsup src src/index.ts --watch --ignore-watch folder1 --ignore-watch folder2

提供成功构建的钩子 onSuccess

这在监听模式下非常有用。

typescript">import { defineConfig } from 'tsup'export default defineConfig({async onSuccess() {// Start some long running task// Like a serverconst server = http.createServer((req, res) => {res.end('Hello World!')})server.listen(3000)return () => {server.close()}},
})

压缩产物 minify

typescript">tsup src/index.ts --minify

默认是用 esbuild 压缩,也可以用 terser 代替。前提必须安装 terser。

typescript">npm install -D tersertsup src/index.ts --minify terser

tsup.config.js 中,您可以传递 terserOptions,这些选项将原封不动地传递给 terser.minify。

自定义 loader

esbuild 提供这些 loader:

typescript">type Loader =| 'js'| 'jsx'| 'ts'| 'tsx'| 'css'| 'json'| 'text'| 'base64'| 'file'| 'dataurl'| 'binary'| 'copy'| 'default'

会发现上面没有图片的 loader,但我们可以指定 loader 去处理某些后缀的图片。

typescript">import { defineConfig } from 'tsup'export default defineConfig({loader: {'.jpg': 'base64', '.webp': 'file',},
})

Tree shaking

esbuild 默认开启了 tree shaking。但它的 tree shaking 可能有问题,所以 tsup 允许你选择 rollup 的 tree shaking 去替代 esbuild。

typescript">import { defineConfig } from 'tsup'export default defineConfig({treeshake: true, // 使用 rollup tree shaking
}

类型检查

esbuild 之所以快,就是因为它不会执行 ts 类型检查。你应该依靠 IDE 在完成类型检查。
如果你就想在构建时,执行类型检查,可以开启 --dts。
它会生成类型声明文件,自然也会进行类型检查。

支持 CSS (实验性功能)

元数据文件 metafile

传递 --metafile 标志,告诉 esbuild 以 JSON 格式生成一些关于构建的元数据。您可以将输出文件提供给像 bundle buddy 这样的分析工具,以可视化您的包中的模块以及每个模块占用多少空间。

生成的文件格式为:metafile-{format}.json。eg:metafile-cjs.json

自定义 esbuild 插件和配置

typescript">import { defineConfig } from 'tsup'export default defineConfig({esbuildPlugins: [YourPlugin],esbuildOptions(options, context) {options.define.foo = '"bar"'},
})

注入 cjs 和 esm shims (垫片)

shims 本意为垫片,类似于补丁的意思

启用此选项将在构建 esm/cjs 项目时填充一些代码以使其工作。

例如 __dirname 仅在 cjs 模块中可用,而 import.meta.url 仅在 esm 模块中可用。打完补丁后,esm 中就也能用 __dirname 了。

typescript">import { defineConfig } from 'tsup'export default defineConfig({shims: true,
})

打的补丁具体是什么样的?

CJS 项目会添加如下代码:

typescript">// import.meta.url:
(import.meta.url as typeof document) === "undefined"? new URL("file:" + __filename).href: (document.currentScript && document.currentScript.src) || new URL("main.js", document.baseURI).href;

esm 项目会添加如下代码:

typescript">// __dirname
path.dirname(fileURLToPath(import.meta.url))

vite 早期配置中就得使用这段代码。现在可以直接使用 __diranme 了。看来也是把这段代码作为了补丁,默认提供。

复制文件到输出目录

使用 --publicDir 将 ./public 文件夹内的文件复制到输出目录。
您还可以使用 --publicDir [dir] 来选择一个自定义目录。

tsup_347">在项目中使用 tsup

tsup 提供了 js API,可以在 js 中使用。

typescript">import { build } from 'tsup'await build({entry: ['src/index.ts'],sourcemap: true,dts: true,
})

常见问题

error: No matching export in “xxx.ts” for import “xxx”

当您在 tsconfig 中启用了emitDecoratorMetadata时,通常会发生这种情况。
在这种模式下,我们使用 SWC 将装饰器转换为 JavaScript,因此导出的类型将被消除,这就是为什么 esbuild 无法找到相应的导出。
您可以通过将 import 语句从 import {SomeType}更改为import {type SomeType}import type {SomeType}来修复此问题。


http://www.ppmy.cn/ops/5554.html

相关文章

linux离线安装mysql

一、下载mysql 地址:MySQL 这里选择64为还是32为要根据操作系统来 uname -m 二、上传解压配置mysql 使用root账户登录linux服务器,在opt文件下创建mysql文件夹 cd /opt sudo mkdir mysql 使用Xftp上传mysql压缩包到此文件夹下(自行决定路径) cd mysql/…

.NET 设计模式—备忘录模式(Memento Pattern)

简介 备忘录模式,又称之为快照模式(Snapshop Pattern),是一种行为型设计模式,,它允许在不破坏对象封装性的前提下,捕获并保存一个对象的内部状态,以便在需要时恢复该对象到原先的状态。备忘录模式可以为我们…

【K8S系列】深入解析K8S中PV 和PVC

在 Kubernetes 中,PV(持久卷)和 PVC(持久卷声明)之间的关系是一种动态匹配和绑定关系,用于实现 Pod 与存储资源的解耦。 一、概念介绍 1.1 PV(持久卷): PV 是集群中的一…

【数据结构】插值排序

插值排序(Interpolation Search)是一种用于在有序数组中查找特定元素的搜索算法。它是二分查找算法的改进版本,通过使用当前查找值与数组中值的比例来估计下一次查找的位置,而不是简单地取中点。 算法步骤 在开始搜索之前&#…

YOLOv9改进策略 | 添加注意力篇 | 挤压和激励单元SENetV2助力YOLOv9细节涨点(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是SENetV2,其是一种通过调整卷积网络中的通道关系来提升性能的网络结构。SENet并不是一个独立的网络模型,而是一个可以和现有的任何一个模型相结合的模块(可以看作是一种通道型的注意力机制但是相对于SENetV1来说…

ROS分布式通讯配置

4WD 必读:分布式通讯是相对于用虚拟机来连接小车上主机来说,如果是 4WD 笔记本无主 机用户,不存在分布式通讯一说。 1.4WD 用户单笔记设置一,连接底盘和雷达还有摄像头。 因为虚拟机带宽问题,无法保证摄像头正常运行。…

MacOS安装openMP报错该如何处理

在 macOS 上安装 OpenMP 可能会遇到一些问题,特别是因为 macOS 不像 Linux 系统那样默认支持 OpenMP。以下是一种可能的解决方法: 步骤一:安装 Homebrew 1.打开终端应用程序。 2.运行以下命令安装 Homebrew: /bin/bash -c &qu…

React-基础语法学习

1、教程:井字棋游戏 本教程将引导你逐步实现一个简单的井字棋游戏,并且不需要你对 React 有任何了解。在此过程中你会学习到一些编写 React 程序的基本知识,完全理解它们可以让你对 React 有比较深入的理解。 1.1、教程分成以下几个部分&am…