From 85cfd15c7fd06407c839b188ac3f9b41d611d1e4 Mon Sep 17 00:00:00 2001 From: EGOIST <0x142857@gmail.com> Date: Sat, 20 Nov 2021 19:43:30 +0800 Subject: [PATCH] fix: add default loaders, closes #459 --- docs/README.md | 39 +++++++++++++++++++++++++++++++++++++++ src/cli-main.ts | 12 ++++++++++++ src/esbuild/index.ts | 44 ++++++++++++++++++++++++++++++++------------ src/index.ts | 3 ++- src/options.ts | 10 +++++++++- 5 files changed, 94 insertions(+), 14 deletions(-) diff --git a/docs/README.md b/docs/README.md index a1b684a9..3197bb5f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -258,6 +258,45 @@ You can also minify the output, resulting into lower bundle sizes by using the ` tsup src/index.ts --minify ``` +### CUstom loader + +Esbuild loader list: + +```ts +type Loader = + | 'js' + | 'jsx' + | 'ts' + | 'tsx' + | 'css' + | 'json' + | 'text' + | 'base64' + | 'file' + | 'dataurl' + | 'binary' + | 'default' +``` + +To use a custom loader via CLI flag: + +```bash +tsup --loader ".jpg=base64" --loader ".webp=file" +``` + +Or via `tsup.config.ts`: + +```ts +import { defineConfig } from 'tsup' + +export default defineConfig({ + loader: { + '.jpg': 'base64', + '.webp': 'file', + }, +}) +``` + ### What about type checking? esbuild is fast because it doesn't perform any type checking, you already get type checking from your IDE like VS Code or WebStorm. diff --git a/src/cli-main.ts b/src/cli-main.ts index 07219bb7..3d0f14ee 100644 --- a/src/cli-main.ts +++ b/src/cli-main.ts @@ -80,6 +80,8 @@ export async function main(options: Options = {}) { .option('--platform ', 'Target platform', { default: 'node', }) + .option('--loader ', 'Specify the loader for a file extension') + .option('--no-config', 'Disable config file') .action(async (files: string[], flags) => { const { build } = await import('.') Object.assign(options, { @@ -113,6 +115,16 @@ export async function main(options: Options = {}) { const define: any = flat(flags.define) options.define = define } + if (flags.loader) { + const loader = ensureArray(flags.loader) + options.loader = loader.reduce((result, item) => { + const parts = item.split('=') + return { + ...result, + [parts[0]]: parts[1], + } + }, {}) + } await build(options) }) diff --git a/src/esbuild/index.ts b/src/esbuild/index.ts index f19c88e3..eed14ce6 100644 --- a/src/esbuild/index.ts +++ b/src/esbuild/index.ts @@ -1,14 +1,7 @@ import fs from 'fs' import path from 'path' -import type { InputOption } from 'rollup' import { transform as transformToEs5 } from 'buble' -import { - build as esbuild, - BuildOptions, - BuildResult, - Plugin as EsbuildPlugin, - formatMessages, -} from 'esbuild' +import { build as esbuild, BuildResult, formatMessages } from 'esbuild' import { NormalizedOptions, Format } from '..' import { getDeps, loadPkg } from '../load' import { log } from '../log' @@ -76,6 +69,7 @@ export async function runEsbuild( : format === 'esm' const platform = options.platform || 'node' + const loader = options.loader || {} try { result = await esbuild({ @@ -90,6 +84,28 @@ export async function runEsbuild( target: options.target === 'es5' ? 'es2016' : options.target, footer: options.footer, banner: options.banner, + loader: { + '.aac': 'file', + '.css': 'file', + '.eot': 'file', + '.flac': 'file', + '.gif': 'file', + '.jpeg': 'file', + '.jpg': 'file', + '.mp3': 'file', + '.mp4': 'file', + '.ogg': 'file', + '.otf': 'file', + '.png': 'file', + '.svg': 'file', + '.ttf': 'file', + '.wav': 'file', + '.webm': 'file', + '.webp': 'file', + '.woff': 'file', + '.woff2': 'file', + ...loader, + }, mainFields: platform === 'node' ? ['module', 'main'] @@ -106,10 +122,14 @@ export async function runEsbuild( }, // esbuild's `external` option doesn't support RegExp // So here we use a custom plugin to implement it - ...(format !== 'iife' ? [externalPlugin({ - patterns: external, - skipNodeModulesBundle: options.skipNodeModulesBundle, - })] : []), + ...(format !== 'iife' + ? [ + externalPlugin({ + patterns: external, + skipNodeModulesBundle: options.skipNodeModulesBundle, + }), + ] + : []), postcssPlugin({ css }), sveltePlugin({ css }), ...(options.esbuildPlugins || []), diff --git a/src/index.ts b/src/index.ts index 14258e66..5de7edee 100644 --- a/src/index.ts +++ b/src/index.ts @@ -104,7 +104,8 @@ const normalizeOptions = async ( } export async function build(_options: Options) { - const config = await loadTsupConfig(process.cwd()) + const config = + _options.config === false ? {} : await loadTsupConfig(process.cwd()) const configData = typeof config.data === 'function' ? config.data(_options) : config.data diff --git a/src/options.ts b/src/options.ts index 3c974a21..1e9ef809 100644 --- a/src/options.ts +++ b/src/options.ts @@ -1,4 +1,4 @@ -import type { BuildOptions, Plugin as EsbuildPlugin } from 'esbuild' +import type { BuildOptions, Plugin as EsbuildPlugin, Loader } from 'esbuild' import type { InputOption } from 'rollup' export type Format = 'cjs' | 'esm' | 'iife' @@ -101,4 +101,12 @@ export type Options = { * @default `node` */ platform?: 'node' | 'browser' + /** + * Esbuild loader option + */ + loader?: Record + /** + * Disable config file with `false` + */ + config?: boolean }