除了webpack和vite你还知道哪些主流并且简单的打包工具?

tsup

tsup 是@egois是我们最常用的工具之一,typescript项目的特性是零配置构建。就可以直接打包dist/index.js

tsup src/index.ts
//支持双重格式
tsup src/index.ts --format cjs,esm
//package.json中使用tsup
{
  "name": "my-cool-package",
  "main": "./dist/index.js",
  "module": "./dist/index.mjs",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "require": "./dist/index.js",
      "import": "./dist/index.mjs",
      "types": "./dist/index.d.ts"      
    }
  },
  "scripts": {
    "build": "tsup src/index.ts --format cjs,esm --dts --clean",
    "watch": "npm run build -- --watch src",
    "prepublishOnly": "npm run build"
  }
}

unbuild

如果说tsup是typescript的一个最小的打包工具,那么unbuild则是一个更通用的,可自定义的,但功能强大,unbuild被用来打包Nuxt3及其子包。要使用他,我们需要在根目录下创建build.config.ts文件

// build.config.ts
import { defineBuildConfig } from 'unbuild'

export default defineBuildConfig({
  entries: [
    './src/index'
  ],
  declaration: true, // generate .d.ts files
})
//执行命令 默认会生成ESM和CJS两种格式

unbuild
在next3代码库中发现unbuild引入了一个叫stub的新概念,每次修改源代码启动一个监视程序重新触发打包不同,stubbing在unbuild中的根本不需要您有另一个程序处理它。只需要调用命令

unbuild --stub

生成的文件内容

// dist/index.mjs
import jiti from 'jiti'
export default jiti(null, { interopDefault: true })('/Users/antfu/unbuild-test/src/index')

// dist/index.cjs
module.exports = require('jiti')(null, { interopDefault: true })('/Users/antfu/unbuild-test/src/index')

现在dist文件不在发布你的代码包,而是通过jit重定向到你的源代码。jiti通过动态编译模块,为typescript和esm提供了运行时支持,因为它直接指向你的源文件,所以在你的源代码和bundle dist之间不会有错位。因此不需要观察者进程!

Bundleless 的构建

unbuild由mkdist(另一个@unjs包 )提供支持,他还可以处理静态资源和文件到文件的编译。无需绑定构建允许您保持源代码的结构,便于按需导入子模块以优化性能
配置

// build.config.ts
import { defineBuildConfig } from 'unbuild'

export default defineBuildConfig({
  entries: [
    // bundling
    'src/index',
    // bundleless, or just copy assets
    { input: 'src/components/', outDir: 'dist/components' },
  ],
  declaration: true,
})

他最酷的一个特性是他可以直接处理.vue 例如src/components下有一个组件MyComponent.vue 例如

<!-- src/components/MyComponent.vue -->
<template>
  <div>{{ count }}</div>
</template>

<script lang="ts">
const count: number | string = 0

export default {
  data: () => ({ count }),
}
</script>

请注意,我们在Vue文件中使用TypeScript,当我们进行构建时,组件将被复制,但TypeScript注释将被删除,同时生成MyComponent.Vue.d.ts。

<!-- dist/components/MyComponent.vue -->
<template>
  <div>{{ count }}</div>
</template>

<script>
const count = 0
export default {
  data: () => ({ count })
}
</script>

// dist/components/MyComponent.vue.d.ts
declare const _default: {
  data: () => {
    count: number | string
  }
}
export default _default

使用上述任何一种工具,现在我们都可以将typescript编写为单一的试试来源,病史整个代码库变得更易于维护。但是,您仍然需要注意一些注意事项

在ESM中,没有__dirname,__filename,require,require.resolve.相反,您需要使用import.meta,url并进行一些转化来获取文件路径字符串。因此我们的代码被编译成CJS和ESM,因此最好尽可能避免使用这些特定于环境的上下文。如果却行使用可以参考[参考地址]

(https://antfu.me/notes#isomorphic-dirname)
import { dirname } from 'path'
import { fileURLToPath } from 'url'

const _dirname = typeof __dirname !== 'undefined'
  ? __dirname
  : dirname(fileURLToPath(import.meta.url))

对于requireand require.resolve,您可以使用

import { createRequire } from 'module'

const require = createRequire(import.meta.url)

注意:好消息是,如果正在使用‘unbuild’,我们可以直接打开‘cjsBridge’标志并‘unbuild’自动为我们填充ESM中的那些CJS上下文

import { defineBuildConfig } from 'unbuild'

export default defineBuildConfig({
  cjsBridge: true, // <--
})

相反,如果您使用的是tsup,则轻松import.meta.url在 CJS 中为您填充ESM 。

对于tsup的使用我在utils的开发中有详细的搭建和配置过程可以参考utils公共组件独立开发

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值