diff --git a/.gitignore b/.gitignore index 628c2d1ad..127e37222 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ dist .eslintcache temp + +docs/.vitepress/dist +docs/.vitepress/cache diff --git a/README.md b/README.md index cbeea9614..704fa2237 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -tsdown
+tsdown
# tsdown [![npm](https://img.shields.io/npm/v/tsdown.svg)](https://npmjs.com/package/tsdown) [![Unit Test](https://github.com/rolldown/tsdown/actions/workflows/tests.yml/badge.svg)](https://github.com/rolldown/tsdown/actions/workflows/tests.yml) [![JSR](https://jsr.io/badges/@sxzz/tsdown)](https://jsr.io/@sxzz/tsdown) diff --git a/assets/header-illustration.svg b/assets/header-illustration.svg deleted file mode 100644 index 2d81158db..000000000 --- a/assets/header-illustration.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/logo.svg b/assets/logo.svg deleted file mode 100644 index 3d0db8248..000000000 --- a/assets/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/.vitepress/components/HomePage.vue b/docs/.vitepress/components/HomePage.vue new file mode 100644 index 000000000..fee472089 --- /dev/null +++ b/docs/.vitepress/components/HomePage.vue @@ -0,0 +1,39 @@ + + + + + diff --git a/docs/.vitepress/config/index.ts b/docs/.vitepress/config/index.ts new file mode 100644 index 000000000..b8190b073 --- /dev/null +++ b/docs/.vitepress/config/index.ts @@ -0,0 +1,46 @@ +import { defineConfig } from 'vitepress' +import { groupIconMdPlugin } from 'vitepress-plugin-group-icons' +import { getLocaleConfig } from './theme' + +// https://vitepress.dev/reference/site-config +export default defineConfig({ + locales: { + root: getLocaleConfig('en'), + 'zh-CN': getLocaleConfig('zh-CN'), + }, + + lastUpdated: true, + cleanUrls: true, + themeConfig: { + search: { + provider: 'local', + options: { + locales: { + 'zh-CN': { + translations: { + button: { + buttonText: '搜索文档', + buttonAriaLabel: '搜索文档', + }, + modal: { + noResultsText: '无法找到相关结果', + resetButtonTitle: '清除查询条件', + footer: { + selectText: '选择', + navigateText: '切换', + closeText: '关闭', + }, + }, + }, + }, + }, + }, + }, + }, + + markdown: { + config(md) { + md.use(groupIconMdPlugin) + }, + }, +}) diff --git a/docs/.vitepress/config/theme.ts b/docs/.vitepress/config/theme.ts new file mode 100644 index 000000000..44c398e99 --- /dev/null +++ b/docs/.vitepress/config/theme.ts @@ -0,0 +1,148 @@ +import { createTranslate } from '../i18n/utils' +import type { DefaultTheme, HeadConfig, LocaleConfig } from 'vitepress' + +export function getLocaleConfig(lang: string) { + const t = createTranslate(lang) + + const urlPrefix = lang && lang !== 'en' ? (`/${lang}` as const) : '' + const title = t('tsdown') + const description = t('The Elegant Bundler for Libraries') + const titleTemplate = `:title - ${description}` + + const head: HeadConfig[] = [ + [ + 'link', + { + rel: 'icon', + type: 'image/svg+xml', + href: '/tsdown.svg', + }, + ], + ['meta', { name: 'theme-color', content: '#ff7e17' }], + ['meta', { property: 'og:type', content: 'website' }], + ['meta', { property: 'og:locale', content: 'en' }], + [ + 'meta', + { + property: 'og:title', + content: `tsdown | ${description}`, + }, + ], + [ + 'meta', + { + property: 'og:image', + content: 'https://tsdown.dev/og-image.png', + }, + ], + ['meta', { property: 'og:site_name', content: 'Rolldown' }], + ['meta', { property: 'og:url', content: 'https://rolldown.rs/' }], + ['meta', { name: 'twitter:card', content: 'summary_large_image' }], + ['meta', { name: 'twitter:site', content: '@rolldown_rs' }], + ] + + const nav: DefaultTheme.NavItem[] = [ + { text: t('Home'), link: `${urlPrefix}/` }, + { text: t('Guide'), link: `${urlPrefix}/guide/` }, + { + text: t('API Reference'), + link: `${urlPrefix}/reference/config-options.md`, + }, + ] + + const sidebar: DefaultTheme.SidebarItem[] = [ + { + base: `${urlPrefix}/guide`, + items: [ + { + text: t('Guide'), + items: [ + { text: t('Introduction'), link: '/index.md' }, + { text: t('Getting Started'), link: '/getting-started.md' }, + { text: t('Migrate from tsup'), link: '/migrate-from-tsup.md' }, + ], + }, + { + text: t('Recipes'), + items: [ + { text: t('Entry'), link: '/entry.md' }, + { text: t('Config File'), link: '/config-file.md' }, + { text: t('Declaration Files (dts)'), link: '/dts.md' }, + { text: t('Output Format'), link: '/output-format.md' }, + { text: t('Output Directory'), link: '/output-directory.md' }, + { text: t('Cleaning'), link: '/cleaning.md' }, + { text: t('Watch Mode'), link: '/watch-mode.md' }, + { text: t('Target'), link: '/target.md' }, + { text: t('Platform'), link: '/platform.md' }, + { text: t('Tree-shaking'), link: '/tree-shaking.md' }, + { text: t('Source Maps'), link: '/sourcemap.md' }, + { text: t('Minification'), link: '/minification.md' }, + { text: t('Silent Mode'), link: '/silent-mode.md' }, + { text: t('Shims'), link: '/shims.md' }, + ], + }, + { + text: t('Advanced'), + items: [ + { text: t('Plugins'), link: '/plugins.md' }, + { text: t('Rolldown Options'), link: '/rolldown-options.md' }, + ], + }, + ], + }, + { + text: t('API Reference'), + base: `${urlPrefix}/reference`, + items: [ + { text: t('Config Options'), link: '/config-options.md' }, + { text: t('Command Line Interface'), link: '/cli.md' }, + ], + }, + ] + + const themeConfig: DefaultTheme.Config = { + logo: { src: '/tsdown.svg', width: 24, height: 24 }, + nav, + sidebar, + outline: 'deep', + socialLinks: [ + { icon: 'github', link: 'https://github.com/rolldown/tsdown' }, + { icon: 'npm', link: 'https://npmjs.com/package/tsdown' }, + { icon: 'jsr', link: 'https://jsr.io/@sxzz/tsdown' }, + ], + footer: { + message: 'Released under the MIT License.', + copyright: 'Copyright © 2025-present VoidZero Inc. & Contributors', + }, + } + + if (lang === 'zh-CN') { + Object.assign(themeConfig, { + outline: { + label: '页面导航', + level: 'deep', + }, + lastUpdatedText: '最后更新于', + darkModeSwitchLabel: '外观', + sidebarMenuLabel: '目录', + returnToTopLabel: '返回顶部', + langMenuLabel: '选择语言', + docFooter: { + prev: '上一页', + next: '下一页', + }, + } satisfies DefaultTheme.Config) + } + + const localeConfig: LocaleConfig[string] = { + label: t('English'), + lang: t('en'), + title, + titleTemplate, + description, + head, + themeConfig, + } + + return localeConfig +} diff --git a/docs/.vitepress/i18n/composable.ts b/docs/.vitepress/i18n/composable.ts new file mode 100644 index 000000000..f1b50e649 --- /dev/null +++ b/docs/.vitepress/i18n/composable.ts @@ -0,0 +1,7 @@ +import { useData } from 'vitepress' +import { t } from './utils' + +export function useTranslate(lang?: string) { + const { lang: vpLang } = useData() + return (key: string) => t(key, lang || vpLang.value) +} diff --git a/docs/.vitepress/i18n/translate-map.ts b/docs/.vitepress/i18n/translate-map.ts new file mode 100644 index 000000000..453afe320 --- /dev/null +++ b/docs/.vitepress/i18n/translate-map.ts @@ -0,0 +1,43 @@ +export const zhCN = { + // nav + Home: '首页', + Guide: '指南', + 'API Reference': 'API 参考', + + // sidebar + Introduction: '介绍', + 'Getting Started': '快速上手', + 'Migrate from tsup': ' 从 tsup 迁移', + + Recipes: '实践指南', + Entry: '入口文件', + Cleaning: '清理', + 'Config File': '配置文件', + Minification: '压缩', + 'Output Directory': '输出目录', + 'Output Format': '输出格式', + Platform: '运行平台(Platform)', + 'Silent Mode': '静默模式', + 'Source Maps': '源映射(Source Maps)', + Target: '构建目标(Target)', + 'Tree-shaking': '除屑优化(Tree-shaking)', + 'Watch Mode': '监听模式', + Shims: 'Shims(兼容代码)', + 'Declaration Files (dts)': '声明文件(dts)', + + Advanced: '高级功能', + 'Rolldown Options': 'Rolldown 选项', + Plugins: '插件', + + 'Config Options': '配置选项', + 'Command Line Interface': '命令行接口', + + 'The Elegant Bundler for Libraries': '优雅的库打包器', + + English: '简体中文', + en: 'zh-CN', +} + +export const translateMap: Record> = { + 'zh-CN': zhCN, +} diff --git a/docs/.vitepress/i18n/utils.ts b/docs/.vitepress/i18n/utils.ts new file mode 100644 index 000000000..4b4381731 --- /dev/null +++ b/docs/.vitepress/i18n/utils.ts @@ -0,0 +1,9 @@ +import { translateMap } from './translate-map' + +export function t(key: string, lang: string) { + return translateMap[lang]?.[key] || key +} + +export function createTranslate(lang: string) { + return (key: string) => t(key, lang) +} diff --git a/docs/.vitepress/scripts/docs-generate.sh b/docs/.vitepress/scripts/docs-generate.sh new file mode 100755 index 000000000..b2b7886ce --- /dev/null +++ b/docs/.vitepress/scripts/docs-generate.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +safe_sed() { + if [ "$(uname)" = "Darwin" ]; then + sed -i '' "$@" + else + sed -i "$@" + fi +} + +echo "📚 Generating reference..." + +# Generate API documentation +./node_modules/.bin/typedoc --tsconfig tsconfig.json >/dev/null 2>&1 + +echo "✅ Reference generated successfully!" + +echo "📚 Beautifying reference structure..." + +# Move Options.md to ./docs/reference +mv ./docs/reference/api/interfaces/Options.md ./docs/reference/config-options.md + +# Remove the type-aliases folder if it exists +if [ -d "./docs/reference/type-aliases" ]; then + rm -rf ./docs/reference/type-aliases +fi +# Create the type-aliases folder +mkdir -p ./docs/reference/type-aliases +# Move types-aliases/Sourcemap.md to ./docs/reference/type-aliases +mv ./docs/reference/api/type-aliases/Sourcemap.md ./docs/reference/type-aliases/Sourcemap.md + +# Remove the api folder +rm -rf ./docs/reference/api + +# In config-options.md, remove 6 first lines +safe_sed '1,6d' ./docs/reference/config-options.md +# In config-options.md, replace "../type-aliases" with "./type-aliases" +safe_sed 's/..\/type-aliases/.\/type-aliases/g' ./docs/reference/config-options.md + +# In type-aliases files, remove 6 first lines +safe_sed '1,6d' ./docs/reference/type-aliases/*.md + +# Initialize an array of all locales +locales=("zh-CN") +# Copy the config-options.md file and the type-aliases folder to each locale +for locale in "${locales[@]}"; do + # Copy config-options.md to the locale directory + cp ./docs/reference/config-options.md "./docs/$locale/reference/config-options.md" + # Remove the type-aliases folder if it exists in the locale directory + if [ -d "./docs/$locale/reference/type-aliases" ]; then + rm -rf "./docs/$locale/reference/type-aliases" + fi + # Copy the type-aliases folder to the locale directory + cp -r ./docs/reference/type-aliases "./docs/$locale/reference" +done + +echo "✅ Reference structure beautified successfully!" diff --git a/docs/.vitepress/theme/Layout.vue b/docs/.vitepress/theme/Layout.vue new file mode 100644 index 000000000..1bfd218dc --- /dev/null +++ b/docs/.vitepress/theme/Layout.vue @@ -0,0 +1,12 @@ + + + diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css new file mode 100644 index 000000000..6a9a9acd4 --- /dev/null +++ b/docs/.vitepress/theme/custom.css @@ -0,0 +1,26 @@ +:root { + --vp-c-brand-1: #ff7e17; + --vp-c-brand-2: #ff8700; + --vp-c-brand-3: #e37800; + --vp-code-color: #333; + --vp-button-brand-bg: #ff7e17; + + /* Hero Background Image */ + --vp-home-hero-image-background-image: linear-gradient( + -45deg, + rgba(255, 149, 0, 0.4) 40%, + rgba(48, 115, 122, 0.2) 50% + ); + --vp-home-hero-image-filter: blur(44px); + + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient( + 90deg, + #ff7e17, + rgb(84, 218, 233) + ); +} + +.dark { + --vp-code-color: #fff; +} diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts new file mode 100644 index 000000000..688e935ca --- /dev/null +++ b/docs/.vitepress/theme/index.ts @@ -0,0 +1,11 @@ +import DefaultTheme from 'vitepress/theme' +import Layout from './Layout.vue' + +import './custom.css' +import 'virtual:group-icons.css' +import 'uno.css' + +export default { + ...DefaultTheme, + Layout, +} diff --git a/docs/_redirects b/docs/_redirects deleted file mode 100644 index 68b6ba0ca..000000000 --- a/docs/_redirects +++ /dev/null @@ -1 +0,0 @@ -/* https://github.com/rolldown/tsdown diff --git a/docs/guide/cleaning.md b/docs/guide/cleaning.md new file mode 100644 index 000000000..293875373 --- /dev/null +++ b/docs/guide/cleaning.md @@ -0,0 +1,14 @@ +# Cleaning + + + +By default, `tsdown` does not clean the output folder for you. This means that if your bundling process generates files with different names compared to a previous build, the older files will remain in the output directory. + +To ensure the output directory is cleaned before building, you can use the `--clean` option: + +```bash +tsdown --clean +``` + +> [!NOTE] +> Using the `--clean` option will remove all files in the output directory before the build process begins. Make sure this behavior aligns with your project requirements to avoid accidentally deleting important files. diff --git a/docs/guide/config-file.md b/docs/guide/config-file.md new file mode 100644 index 000000000..a7dab0ce6 --- /dev/null +++ b/docs/guide/config-file.md @@ -0,0 +1,84 @@ +# Config File + +By default, `tsdown` will search for a configuration file by looking in the current working directory and traversing upward through parent directories until it finds one. It supports the following file names: + +- `tsdown.config.ts` +- `tsdown.config.mts` +- `tsdown.config.cts` +- `tsdown.config.js` +- `tsdown.config.mjs` +- `tsdown.config.cjs` +- `tsdown.config.json` +- `tsdown.config` + +Additionally, you can define your configuration directly in the `tsdown` field of your `package.json` file. + +## Writing a Config File + +The configuration file allows you to define and customize your build settings in a centralized and reusable way. Below is a simple example of a `tsdown` configuration file: + +```ts [tsdown.config.ts] +import { defineConfig } from 'tsdown/config' + +export default defineConfig({ + entry: 'src/index.ts', +}) +``` + +### Building Multiple Outputs + +`tsdown` also supports returning an **array of configurations** from the config file. This allows you to build multiple outputs with different settings in a single run. For example: + +```ts [tsdown.config.ts] +import { defineConfig } from 'tsdown/config' + +export default [ + defineConfig({ + entry: 'src/entry1.ts', + platfrom: 'node', + }), + defineConfig({ + entry: 'src/entry2.ts', + platfrom: 'browser', + }), +] +``` + +## Specifying a Custom Config File + +If your configuration file is located elsewhere or has a different name, you can specify its path using the `--config` (or `-c`) option: + +```bash +tsdown --config ./path/to/config +``` + +## Disabling the Config File + +To disable loading a configuration file entirely, use the `--no-config` option: + +```bash +tsdown --no-config +``` + +This is useful if you want to rely solely on command-line options or default settings. + +## Extending Vite or Vitest Config (Experimental) + +`tsdown` provides an **experimental** feature to extend your existing Vite or Vitest configuration files. This allows you to reuse specific configuration options, such as `resolve` and `plugins`, while ignoring others that are not relevant to `tsdown`. + +To enable this feature, use the `--from-vite` option: + +```bash +tsdown --from-vite # Load vite.config.* +tsdown --from-vite vitest # Load vitest.config.* +``` + +> [!WARNING] +> This feature is **experimental** and may not support all Vite or Vitest configuration options. Only specific options, such as `resolve` and `plugins`, are reused. Use with caution and test thoroughly in your project. + +> [!TIP] +> Extending Vite or Vitest configurations can save time and effort if your project already uses these tools, allowing you to build upon your existing setup without duplicating configuration. + +## Reference + +For a full list of available configuration options, refer to the [Config Options Reference](../reference/config-options.md). This includes detailed explanations of all supported fields and their usage. diff --git a/docs/guide/dts.md b/docs/guide/dts.md new file mode 100644 index 000000000..0b46e80ef --- /dev/null +++ b/docs/guide/dts.md @@ -0,0 +1,63 @@ +# Declaration Files (dts) + +Declaration files (`.d.ts`) are an essential part of TypeScript libraries, providing type definitions that allow consumers of your library to benefit from TypeScript's type checking and IntelliSense. + +`tsdown` makes it easy to generate and bundle declaration files for your library, ensuring a seamless developer experience for your users. + +## How dts Works in tsdown + +`tsdown` uses [rolldown-plugin-dts](https://github.com/sxzz/rolldown-plugin-dts) internally to generate and bundle `.d.ts` files. This plugin is specifically designed to handle declaration file generation efficiently and integrates seamlessly with `tsdown`. + +If you encounter any issues related to `.d.ts` generation, please report them directly to the [rolldown-plugin-dts repository](https://github.com/sxzz/rolldown-plugin-dts/issues). + +## Enabling dts Generation + +You can enable `.d.ts` generation using the `--dts` option in the CLI or by setting `dts: true` in your configuration file. + +### CLI + +```bash +tsdown --dts +``` + +### Config File + +```ts [tsdown.config.ts] +import { defineConfig } from 'tsdown' + +export default defineConfig({ + dts: true, +}) +``` + +## Performance Considerations + +The performance of `.d.ts` generation depends on your `tsconfig.json` configuration: + +### With `isolatedDeclarations` + +If your `tsconfig.json` has the `isolatedDeclarations` option enabled, `tsdown` will use **oxc-transform** for `.d.ts` generation. This method is **extremely fast** and highly recommended for optimal performance. + +```json [tsconfig.json] +{ + "compilerOptions": { + "isolatedDeclarations": true + } +} +``` + +### Without `isolatedDeclarations` + +If `isolatedDeclarations` is not enabled, `tsdown` will fall back to using the TypeScript compiler for `.d.ts` generation. While this approach is reliable, it is relatively slower compared to `oxc-transform`. + +> [!TIP] +> If speed is critical for your workflow, consider enabling `isolatedDeclarations` in your `tsconfig.json`. + +## Build Process for dts + +- **For ESM Output**: Both `.js` and `.d.ts` files are generated in the **same build process**. If you encounter compatibility issues, please report them. +- **For CJS Output**: A **separate build process** is used exclusively for `.d.ts` generation to ensure compatibility. + +## Advanced Options + +`rolldown-plugin-dts` provides several advanced options to customize `.d.ts` generation. For a detailed explanation of these options, refer to the [plugin's documentation](https://github.com/sxzz/rolldown-plugin-dts#options). diff --git a/docs/guide/entry.md b/docs/guide/entry.md new file mode 100644 index 000000000..b9f98c8df --- /dev/null +++ b/docs/guide/entry.md @@ -0,0 +1,80 @@ +# Entry + +The `entry` option specifies the entry files for your project. These files serve as the starting points for the bundling process. You can define entry files either via the CLI or in the configuration file. + +## Using the CLI + +You can specify entry files directly as command arguments when using the CLI. For example: + +```bash +tsdown src/entry1.ts src/entry2.ts +``` + +This command will bundle `src/entry1.ts` and `src/entry2.ts` as separate entry points. + +## Using the Config File + +In the configuration file, the `entry` option allows you to define entry files in various formats: + +### Single Entry File + +Specify a single entry file as a string: + +```ts [tsdown.config.ts] +import { defineConfig } from 'tsdown' + +export default defineConfig({ + entry: 'src/index.ts', +}) +``` + +### Multiple Entry Files + +Define multiple entry files as an array of strings: + +```ts [tsdown.config.ts] +import { defineConfig } from 'tsdown' + +export default defineConfig({ + entry: ['src/entry1.ts', 'src/entry2.ts'], +}) +``` + +### Entry Files with Aliases + +Use an object to define entry files with aliases. The keys represent alias names, and the values represent file paths: + +```ts [tsdown.config.ts] +import { defineConfig } from 'tsdown' + +export default defineConfig({ + entry: { + main: 'src/index.ts', + utils: 'src/utils.ts', + }, +}) +``` + +This configuration will create two bundles: one for `src/index.ts` (output as `dist/main.js`) and one for `src/utils.ts` (output as `dist/utils.js`). + +## Using Glob Patterns + +The `entry` option supports [glob patterns](https://code.visualstudio.com/docs/editor/glob-patterns), enabling you to match multiple files dynamically. For example: + +```ts [tsdown.config.ts] +import { defineConfig } from 'tsdown' + +export default defineConfig({ + entry: 'src/**/*.ts', +}) +``` + +This configuration will include all `.ts` files in the `src` directory and its subdirectories as entry points. + +> [!WARNING] +> The `entry` option is treated as a glob pattern by default. This means: +> +> - On **Windows**, you must use forward slashes (`/`) instead of backslashes (`\`) in file paths. +> - You cannot specify files that do not exist in the file system. +> +> If you need to bypass these limitations, you can use `inputOptions.input` directly in the configuration file for more precise control. diff --git a/docs/guide/getting-started.md b/docs/guide/getting-started.md new file mode 100644 index 000000000..aa9fd626e --- /dev/null +++ b/docs/guide/getting-started.md @@ -0,0 +1,151 @@ +# Getting Started + +:::warning 🚧 Beta Software +[Rolldown](https://rolldown.rs) is currently in beta status. While it can already handle most production use cases, there may still be bugs and rough edges. Most notably, the built-in minification feature is still a work in progress. +::: + +## Installation + +Install `tsdown` as a development dependency using your preferred package manager: + +::: code-group + +```sh [npm] +npm install -D tsdown +``` + +```sh [pnpm] +pnpm add -D tsdown +``` + +```sh [yarn] +yarn add -D tsdown +``` + +```sh [bun] +bun add -D tsdown +``` + +::: + +## Starter Template + +To get started even faster, you can use the [ts-starter](https://github.com/sxzz/ts-starter) template. This starter project is pre-configured for TypeScript library development with `tsdown`, allowing you to hit the ground running. + +Clone the repository: + +```bash +git clone https://github.com/sxzz/ts-starter my-library +cd my-library +pnpm install +``` + +This template includes a ready-to-use configuration and best practices for building TypeScript libraries. + +## Using the CLI + +To verify that `tsdown` is installed correctly, run the following command in your project directory: + +```sh +./node_modules/.bin/tsdown --version +``` + +You can also explore the available CLI options and examples with: + +```sh +./node_modules/.bin/tsdown --help +``` + +### Your First Bundle + +Let's create two source TypeScript files: + +```ts [src/index.ts] +import { hello } from './hello.ts' + +hello() +``` + +```ts [src/hello.ts] +export function hello() { + console.log('Hello tsdown!') +} +``` + +Next, initialize the `tsdown` configuration file: + +```ts [tsdown.config.ts] +import { defineConfig } from 'tsdown' + +export default defineConfig({ + entry: ['./src'], +}) +``` + +Now, run the following command to bundle your code: + +```sh +./node_modules/.bin/tsdown +``` + +You should see the bundled output written to `dist/index.mjs`. To verify it works, run the output file: + +```sh +node dist/index.mjs +``` + +You should see the message `Hello tsdown!` printed to the console. + +### Using the CLI in npm Scripts + +To simplify the command, you can add it to your `package.json` scripts: + +```json{5} [package.json] +{ + "name": "my-tsdown-project", + "type": "module", + "scripts": { + "build": "tsdown" + }, + "devDependencies": { + "tsdown": "^0.9.0" + } +} +``` + +Now, you can build your project with: + +```sh +npm run build +``` + +## Using the Config File + +While you can use the CLI directly, it's recommended to use a configuration file for more complex projects. This allows you to define and manage your build settings in a centralized and reusable way. + +For more details, refer to the [Config File](./config-file.md) documentation. + +## Using Plugins + +`tsdown` supports plugins to extend its functionality. You can use Rolldown plugins, Unplugin plugins, and most Rollup plugins seamlessly. To use plugins, add them to the `plugins` array in your configuration file. For example: + +```ts [tsdown.config.ts] +import { defineConfig } from 'tsdown' +import SomePlugin from 'some-plugin' + +export default defineConfig({ + plugins: [SomePlugin()], +}) +``` + +For more details, refer to the [Plugins](./plugins.md) documentation. + +## Using Watch Mode + +You can enable watch mode to automatically rebuild your project whenever files change. This is particularly useful during development to streamline your workflow. Use the `--watch` (or `-w`) option: + +```bash +tsdown --watch +``` + +For more details, refer to the [Watch Mode](./watch-mode.md) documentation. diff --git a/docs/guide/index.md b/docs/guide/index.md new file mode 100644 index 000000000..6c01acaf5 --- /dev/null +++ b/docs/guide/index.md @@ -0,0 +1,32 @@ +# Introduction + +**tsdown** is _The Elegant Library Bundler_. Designed with simplicity and speed in mind, it provides a seamless and efficient way to bundle your TypeScript and JavaScript libraries. Whether you're building a small utility or a complex library, `tsdown` empowers you to focus on your code while it handles the bundling process with elegance. + +## Why tsdown? + +`tsdown` is built on top of [Rolldown](https://rolldown.rs), a cutting-edge bundler written in Rust. While Rolldown is a powerful and general-purpose tool, `tsdown` takes it a step further by tailoring the experience specifically for library authors. It simplifies the configuration, optimizes for common library use cases, and provides a developer-friendly interface. + +As an **official project of Rolldown**, `tsdown` is deeply integrated into the Rolldown ecosystem. It is not only a standalone bundler but also serves as the foundation for **Rolldown-Vite Library Mode**, ensuring a unified and robust experience for library developers in the future. + +## What Can It Bundle? + +`tsdown` is designed to handle all the essentials for modern library development: + +- **TypeScript and JavaScript**: Seamlessly bundle `.ts` and `.js` files with support for modern syntax and features. +- **TypeScript Declarations**: Automatically generate `.d.ts` files for your library. +- **Multiple Output Formats**: Generate `esm`, `cjs`, and `iife` bundles to ensure compatibility across different environments. +- **Assets**: Include and process non-code assets like `.json` or `.wasm` files. + +With its built-in support for tree shaking, minification, and source maps, `tsdown` ensures your library is optimized for production. + +## Fast and Elegant + +`tsdown` is built to be **fast**. Leveraging Rolldown's Rust-based performance, it delivers blazing-fast builds even for large projects. At the same time, it is **elegant**—offering a clean and intuitive configuration system that minimizes boilerplate and maximizes productivity. + +## Getting Started + +Ready to dive in? Check out the [Getting Started](./getting-started.md) guide to set up your first project with `tsdown`. + +## Credits + +`tsdown` is built on the shoulders of giants. It is powered by [Rolldown](https://rolldown.rs) and inspired by tools like [tsup](https://github.com/egoist/tsup). Special thanks to the open-source community and contributors who make projects like this possible. diff --git a/docs/guide/migrate-from-tsup.md b/docs/guide/migrate-from-tsup.md new file mode 100644 index 000000000..300cb2880 --- /dev/null +++ b/docs/guide/migrate-from-tsup.md @@ -0,0 +1,28 @@ +# Migrate from tsup + +[tsup](https://tsup.egoist.dev/) is a powerful and widely-used bundler that shares many similarities with `tsdown`. While `tsup` is built on top of [esbuild](https://esbuild.github.io/), `tsdown` leverages the power of [Rolldown](https://rolldown.rs/) to deliver a **faster** and more **powerful** bundling experience. + +If you're currently using `tsup` and want to migrate to `tsdown`, the process is straightforward thanks to the dedicated `migrate` command: + +```bash +npx tsdown migrate +``` + +> [!WARNING] +> Please save your changes before migration. The migration process may modify your configuration files, so it's important to ensure all your changes are committed or backed up beforehand. + +### Migration Options + +The `migrate` command supports the following options to customize the migration process: + +- `--cwd ` (or `-c`): Specify the working directory for the migration. +- `--dry-run` (or `-d`): Perform a dry run to preview the migration without making any changes. + +With these options, you can easily tailor the migration process to fit your specific project setup. + +## Acknowledgements + +`tsdown` would not have been possible without the inspiration and contributions of the open-source community. We would like to express our heartfelt gratitude to the following: + +- **[tsup](https://tsup.egoist.dev/)**: `tsdown` was heavily inspired by `tsup`, and even incorporates parts of its codebase. The simplicity and efficiency of `tsup` served as a guiding light during the development of `tsdown`. +- **[@egoist](https://github.com/egoist)**: The creator of `tsup`, whose work has significantly influenced the JavaScript and TypeScript tooling ecosystem. Thank you for your dedication and contributions to the community. diff --git a/docs/guide/minification.md b/docs/guide/minification.md new file mode 100644 index 000000000..cc6a7a753 --- /dev/null +++ b/docs/guide/minification.md @@ -0,0 +1,50 @@ +# Minification + +Minification is the process of compressing your code to reduce its size and improve performance by removing unnecessary characters, such as whitespace, comments, and unused code. + +You can enable minification in `tsdown` using the `--minify` option: + +```bash +tsdown --minify +``` + +> [!WARNING] +> The minification feature is currently **experimental**. While it can be used, it may not handle all edge cases perfectly. Use it with caution, and thoroughly test your output in production environments. + +### Example + +Given the following input code: + +```ts [src/index.ts] +const x = 1 + +function hello(x: number) { + console.log('Hello World') + console.log(x) +} + +hello(x) +``` + +Here are the two possible outputs, depending on whether minification is enabled: + +::: code-group + +```js [dist/index.mjs (without --minify)] +//#region src/index.ts +const x = 1 +function hello(x$1) { + console.log('Hello World') + console.log(x$1) +} +hello(x) + +//#endregion +``` + + +```js [dist/index.mjs (with --minify)] +const e=1;function t(e){console.log(`Hello World`),console.log(e)}t(e); +``` + +::: diff --git a/docs/guide/output-directory.md b/docs/guide/output-directory.md new file mode 100644 index 000000000..edcb3ba4e --- /dev/null +++ b/docs/guide/output-directory.md @@ -0,0 +1,22 @@ +# Output Directory + +By default, `tsdown` bundles your code into the `dist` directory located in the current working folder. + +If you want to customize the output directory, you can use the `--out-dir` (or `-d`) option: + +```bash +tsdown -d ./custom-output +``` + +### Example + +```bash +# Default behavior: outputs to ./dist +tsdown + +# Custom output directory: outputs to ./build +tsdown -d ./build +``` + +> [!NOTE] +> The specified output directory will be created if it does not already exist. Ensure the directory path aligns with your project structure to avoid overwriting unintended files. diff --git a/docs/guide/output-format.md b/docs/guide/output-format.md new file mode 100644 index 000000000..9a719ba90 --- /dev/null +++ b/docs/guide/output-format.md @@ -0,0 +1,29 @@ +# Output Format + +By default, `tsdown` generates JavaScript code in the [ESM](https://nodejs.org/api/esm.html) (ECMAScript Module) format. However, you can specify the desired output format using the `--format` option: + +```bash +tsdown --format esm # default +``` + +### Available Formats + +- [`esm`](https://nodejs.org/api/esm.html): ECMAScript Module format, ideal for modern JavaScript environments, including browsers and Node.js. +- [`cjs`](https://nodejs.org/api/modules.html): CommonJS format, commonly used in Node.js projects. +- [`iife`](https://developer.mozilla.org/en-US/docs/Glossary/IIFE): Immediately Invoked Function Expression, suitable for embedding in `