Skip to content

Commit

Permalink
feat: new option outExtension
Browse files Browse the repository at this point in the history
  • Loading branch information
EGOIST committed May 30, 2022
1 parent a175339 commit b9cd8d5
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 41 deletions.
33 changes: 32 additions & 1 deletion docs/README.md
Expand Up @@ -224,6 +224,37 @@ dist
└── index.js
```

### Output extension

You can also change the output extension of the files by using `outExtension` option:

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

This will generate your files to `[name].[format].js`.

The signature of `outExtension` is:

```ts
type OutExtension = (ctx: Context) => Result

type Context = {
options: NormalizedOptions
format: Format
/** "type" field in project's package.json */
pkgType?: string
}

type Result = { js?: string }
```
### Code Splitting
Code splitting currently only works with the `esm` output format, and it's enabled by default. If you want code splitting for `cjs` output format as well, try using `--splitting` flag which is an experimental feature to get rid of [the limitation in esbuild](https://esbuild.github.io/api/#splitting).
Expand Down Expand Up @@ -319,7 +350,7 @@ export default defineConfig({
})
```

### Tree Shaking
### Tree shaking

esbuild has [tree shaking](https://esbuild.github.io/api/#tree-shaking) enabled by default, but sometimes it's not working very well, see [#1794](https://github.com/evanw/esbuild/issues/1794) [#1435](https://github.com/evanw/esbuild/issues/1435), so tsup offers an additional option to let you use Rollup for tree shaking instead:

Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -63,7 +63,7 @@
"svelte": "3.46.4",
"ts-essentials": "9.1.2",
"tsconfig-paths": "3.12.0",
"tsup": "5.12.5",
"tsup": "6.0.1",
"typescript": "4.6.3",
"vitest": "0.8.4",
"wait-for-expect": "3.0.2"
Expand Down
30 changes: 14 additions & 16 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 31 additions & 10 deletions src/esbuild/index.ts
Expand Up @@ -18,23 +18,44 @@ import { truthy } from '../utils'
import { swcPlugin } from './swc'
import { nativeNodeModulesPlugin } from './native-node-module'
import { PluginContainer } from '../plugin'
import { OutExtensionFactory } from '../options'

const getOutputExtensionMap = (
pkgTypeField: string | undefined,
const defaultOutExtension = ({
format,
pkgType,
}: {
format: Format
) => {
const isModule = pkgTypeField === 'module'
const map: Record<string, string> = {}
pkgType?: string
}): { js: string } => {
let jsExtension = '.js'
const isModule = pkgType === 'module'
if (isModule && format === 'cjs') {
map['.js'] = '.cjs'
jsExtension = '.cjs'
}
if (!isModule && format === 'esm') {
map['.js'] = '.mjs'
jsExtension = '.mjs'
}
if (format === 'iife') {
map['.js'] = '.global.js'
jsExtension = '.global.js'
}
return {
js: jsExtension,
}
}

const getOutputExtensionMap = (
options: NormalizedOptions,
format: Format,
pkgType: string | undefined
) => {
const outExtension: OutExtensionFactory =
options.outExtension || defaultOutExtension

const defaultExtension = defaultOutExtension({ format, pkgType })
const extension = outExtension({ options, format, pkgType })
return {
'.js': extension.js || defaultExtension.js,
}
return map
}

export async function runEsbuild(
Expand Down Expand Up @@ -62,7 +83,7 @@ export async function runEsbuild(
]
const outDir = options.outDir

const outExtension = getOutputExtensionMap(pkg.type, format)
const outExtension = getOutputExtensionMap(options, format, pkg.type)
const env: { [k: string]: string } = {
...options.env,
}
Expand Down
13 changes: 2 additions & 11 deletions src/index.ts
Expand Up @@ -13,7 +13,7 @@ import execa from 'execa'
import kill from 'tree-kill'
import { version } from '../package.json'
import { createLogger, setSilent } from './log'
import { DtsConfig, Format, Options } from './options'
import { NormalizedOptions, Format, Options } from './options'
import { runEsbuild } from './esbuild'
import { shebang } from './plugins/shebang'
import { cjsSplitting } from './plugins/cjs-splitting'
Expand All @@ -22,16 +22,7 @@ import { es5 } from './plugins/es5'
import { sizeReporter } from './plugins/size-reporter'
import { treeShakingPlugin } from './plugins/tree-shaking'

export type { Format, Options }

export type NormalizedOptions = Omit<
MarkRequired<Options, 'entry' | 'format' | 'outDir'>,
'dts'
> & {
dts?: DtsConfig
tsconfigResolvePaths: Record<string, string[]>
tsconfigDecoratorMetadata?: boolean
}
export type { Format, Options, NormalizedOptions }

export const defineConfig = (
options:
Expand Down
28 changes: 26 additions & 2 deletions src/options.ts
@@ -1,10 +1,24 @@
import type { BuildOptions, Plugin as EsbuildPlugin, Loader } from 'esbuild'
import type { InputOption } from 'rollup'
import { Plugin } from './plugin'
import { TreeshakingStrategy } from './plugins/tree-shaking'
import { MarkRequired } from 'ts-essentials'
import type { Plugin } from './plugin'
import type { TreeshakingStrategy } from './plugins/tree-shaking'

export type Format = 'cjs' | 'esm' | 'iife'

export type ContextForOutPathGeneration = {
options: NormalizedOptions
format: Format
/** "type" field in project's package.json */
pkgType?: string
}

export type OutExtensionObject = { js?: string }

export type OutExtensionFactory = (
ctx: ContextForOutPathGeneration
) => OutExtensionObject

export type DtsConfig = {
entry?: InputOption
/** Resolve external types used in dts files from node_modules */
Expand Down Expand Up @@ -57,6 +71,7 @@ export type Options = {
jsxFactory?: string
jsxFragment?: string
outDir?: string
outExtension?: OutExtensionFactory
format?: Format[]
globalName?: string
env?: {
Expand Down Expand Up @@ -158,3 +173,12 @@ export type Options = {
*/
treeshake?: TreeshakingStrategy
}

export type NormalizedOptions = Omit<
MarkRequired<Options, 'entry' | 'format' | 'outDir'>,
'dts'
> & {
dts?: DtsConfig
tsconfigResolvePaths: Record<string, string[]>
tsconfigDecoratorMetadata?: boolean
}
26 changes: 26 additions & 0 deletions test/index.test.ts
Expand Up @@ -860,3 +860,29 @@ test('use rollup for treeshaking', async () => {
`import { inject } from 'vue'`
)
})

test('custom output extension', async () => {
const { outFiles } = await run(
getTestName(),
{
'input.ts': `export const foo = [1,2,3]`,
'tsup.config.ts': `export default {
outExtension({ format }) {
return {
js: '.' + format + '.js'
}
}
}`,
},
{
entry: ['input.ts'],
flags: ['--format', 'esm,cjs'],
}
)
expect(outFiles).toMatchInlineSnapshot(`
[
"input.cjs.js",
"input.esm.js",
]
`)
})

0 comments on commit b9cd8d5

Please sign in to comment.