@hypernym/bundler
Version:
ESM & TS module bundler.
710 lines (699 loc) • 16.7 kB
text/typescript
import { OutputOptions, Plugin, LogLevel, RollupLog } from 'rollup';
import { RollupReplaceOptions } from '@rollup/plugin-replace';
import { RollupJsonOptions } from '@rollup/plugin-json';
import { RollupNodeResolveOptions } from '@rollup/plugin-node-resolve';
import { RollupAliasOptions, Alias } from '@rollup/plugin-alias';
import { TransformOptions } from 'esbuild';
import { Options as Options$1 } from 'rollup-plugin-dts';
interface TransformersChunk {
esbuild?: TransformOptions;
resolve?: RollupNodeResolveOptions | true;
replace?: RollupReplaceOptions;
json?: RollupJsonOptions | true;
alias?: RollupAliasOptions;
}
interface TransformersDeclaration {
dts?: Options$1;
alias?: RollupAliasOptions;
}
interface EntryBase {
/**
* Specifies the format of the generated module.
*
* @default 'esm'
*/
format?: OutputOptions['format'];
/**
* Specifies the module IDs, or regular expressions to match module IDs,
* that should remain external to the bundle.
*
* If not specified, infers the IDs from the global `options.externals` option.
*
* @default undefined
*/
externals?: (string | RegExp)[];
/**
* Specifies the string to be inserted at the beginning of the module.
*
* @default undefined
*/
banner?: OutputOptions['banner'];
/**
* Specifies the string to be inserted at the end of the module.
*
* @default undefined
*/
footer?: OutputOptions['footer'];
/**
* Specifies the code at the beginning that goes inside any _format-specific_ wrapper.
*
* @default undefined
*/
intro?: OutputOptions['intro'];
/**
* Specifies the code at the end that goes inside any _format-specific_ wrapper.
*
* @default undefined
*/
outro?: OutputOptions['outro'];
/**
* Maps external module IDs to paths.
*
* @default undefined
*/
paths?: OutputOptions['paths'];
/**
* Specifies custom filters that will display only certain log messages.
*
* @default undefined
*/
logFilter?: string[];
/**
* Specifies `rollup` plugins.
*
* Adding custom plugins disables all built-in `transformers` for full customization.
*
* @default undefined
*/
plugins?: Plugin[];
}
interface EntryChunk extends EntryBase {
/**
* Specifies the path of the build source.
*
* @example
*
* ```ts
* export default defineConfig({
* entries: [
* { input: './src/index.ts' }, // => './dist/index.mjs'
* ]
* })
* ```
*/
input?: string;
/**
* Specifies the path of the transformed file.
*
* @example
*
* ```ts
* export default defineConfig({
* entries: [
* {
* input: './src/index.ts',
* output: './out/index.js', // => './out/index.js'
* },
* ]
* })
* ```
*
* @default undefined
*/
output?: string;
/**
* Specifies the built-in `transformers` options.
*
* Available transformers:
*
* - `esbuild`
* - `resolve`
* - `replace`
* - `json`
* - `alias`
*
* @default undefined
*/
transformers?: TransformersChunk;
/**
* Specifies the global variable name that representing exported bundle.
*
* Intended for `umd/iife` formats.
*
* @default undefined
*/
name?: OutputOptions['name'];
/**
* Specifies global _module ID_ and _variable name_ pairs necessary for external imports.
*
* Intended for `umd/iife` formats.
*
* @default undefined
*/
globals?: OutputOptions['globals'];
/**
* Specifies whether to extend the global variable defined by the `name` option.
*
* Intended for `umd/iife` formats.
*/
extend?: OutputOptions['extend'];
/**
* Minifies the generated code if enabled.
*
* @default undefined
*/
minify?: boolean;
declaration?: never;
dts?: never;
copy?: never;
template?: never;
}
interface EntryDeclaration extends EntryBase {
/**
* Specifies the path of the TypeScript `declaration` build source.
*
* @example
*
* ```ts
* export default defineConfig({
* entries: [
* { dts: './src/types.ts' }, // => './dist/types.d.mts'
* ]
* })
* ```
*/
dts?: string;
/**
* Specifies the path of the TypeScript `declaration` build source.
*
* Also, it is possible to use `dts` alias.
*
* @example
*
* ```ts
* export default defineConfig({
* entries: [
* { declaration: './src/types.ts' }, // => './dist/types.d.mts'
* ]
* })
* ```
*/
declaration?: string;
/**
* Specifies the path of the TypeScript transformed `declaration` file.
*
* @example
*
* ```ts
* export default defineConfig({
* entries: [
* {
* dts: './src/types.ts',
* output: './out/types.d.ts', // => './out/types.d.ts'
* },
* ]
* })
* ```
*
* @default undefined
*/
output?: string;
/**
* Specifies the built-in `transformers` options.
*
* Available transformers:
*
* - `dts`
* - `alias`
*
* @default undefined
*/
transformers?: TransformersDeclaration;
input?: never;
copy?: never;
template?: never;
name?: never;
globals?: never;
extend?: never;
minify?: never;
}
interface CopyOptions {
/**
* Specifies the path of the source.
*/
input: string | string[];
/**
* Specifies the path of the destination directory.
*/
output: string;
/**
* Copy directories recursively.
*
* @default true
*/
recursive?: boolean;
/**
* Filters copied `files/directories`.
*
* Returns `true` to copy the item, `false` to ignore it.
*
* @default undefined
*/
filter?(source: string, destination: string): boolean;
}
interface EntryCopy {
/**
* Copies the single `file` or entire `directory` structure from source to destination, including subdirectories and files.
*
* This can be very useful for copying some assets that don't need a transformation process, but a simple copy paste feature.
*
* @example
*
* ```ts
* export default defineConfig({
* entries: [
* {
* copy: {
* input: './src/path/file.ts', // or ['path-dir', 'path-file.ts', ...]
* output: './dist/out', // path to output dir
* }
* }
* ]
* })
* ```
*
* @default undefined
*/
copy?: CopyOptions;
input?: never;
declaration?: never;
dts?: never;
template?: never;
name?: never;
globals?: never;
extend?: never;
minify?: never;
}
interface EntryTemplate {
/**
* Specifies the content of the `template` file.
*
* Provides the ability to dynamically inject template content during the build phase.
*
* @example
*
* ```ts
* export default defineConfig({
* entries: [
* {
* template: `// TypeScript code...`,
* output: './dist/template.ts',
* },
* ]
* })
* ```
*/
template: string;
/**
* Specifies the path of the transformed `template` file.
*/
output: string;
input?: never;
declaration?: never;
dts?: never;
copy?: never;
name?: never;
globals?: never;
extend?: never;
minify?: never;
}
type EntryOptions = EntryChunk | EntryDeclaration | EntryCopy | EntryTemplate;
interface Options {
/**
* Specifies the bundle's entry points.
*
* It allows you to manually set all build entries and adjust options for each one individually.
*
* @example
*
* ```ts
* export default defineConfig({
* entries: [
* { input: './src/index.ts' }, // => './dist/index.mjs'
* { dts: './src/types.ts' }, // => './dist/types.d.mts'
* // ...
* ]
* })
* ```
*/
entries: EntryOptions[];
/**
* Specifies the output directory for production bundle.
*
* @example
*
* ```ts
* export default defineConfig({
* outDir: 'output',
* })
* ```
*
* @default 'dist'
*/
outDir?: string;
/**
* Specifies the module IDs, or regular expressions to match module IDs,
* that should remain external to the bundle.
*
* IDs and regexps from this option are applied globally to all entries.
*
* Also, it is possible to define externals individually per entry (`entry.externals`).
*
* @example
*
* ```ts
* export default defineConfig({
* externals: ['id-1', 'id-2', /regexp/],
* })
* ```
*
* @default [/^node:/, /^@types/, /^@rollup/, /^@hypernym/, /^rollup/, ...pkg.dependencies]
*/
externals?: (string | RegExp)[];
/**
* Provides a powerful hooking system to further expand bundling mode.
*
* @example
*
* ```ts
* export default defineConfig({
* hooks: {
* 'build:end': async (options, buildStats) => {
* // ...
* }
* }
* })
* ```
*
* @default undefined
*/
hooks?: HooksOptions;
/**
* Specifies prefixes that will resolve imports with custom paths.
*
* Enables these `alias` by default:
*
* ```ts
* // Imports module from './src/utils/index.js'
* import { module } from '@/utils' // @
* import { module } from '~/utils' // ~
* ```
*
* Also, it is possible to completely override the default aliases by setting custom ones.
*
* @example
*
* ```ts
* export default defineConfig({
* alias: [
* { find: /^#/, replacement: resolve('./src') },
* ]
* })
* ```
*
* Now imports can be used like this:
*
* ```ts
* // Imports module from './src/utils/index.js'
* import { module } from '#/utils' // #
* ```
*
* @default undefined
*/
alias?: Alias[];
/**
* Specifies the minification for all `chunk` entries.
*
* @example
*
* ```ts
* export default defineConfig({
* minify: true,
* })
* ```
*
* It can also be set per entry.
*
* ```ts
* export default defineConfig({
* entries: [
* {
* input: './src/index.ts',
* minify: true,
* },
* ],
* })
* ```
*
* @default undefined
*/
minify?: boolean;
}
interface BuildLogs {
level: LogLevel;
log: RollupLog;
}
interface BuildEntryStats {
/**
* The root path of the project.
*/
cwd: string;
/**
* Module output path.
*/
path: string;
/**
* Module size.
*/
size: number;
/**
* Build time of individual module.
*/
buildTime: number;
/**
* Module format.
*/
format: string;
/**
* List of warnings from build plugins.
*/
logs: BuildLogs[];
}
interface BuildStats {
/**
* The root path of the project.
*/
cwd: string;
/**
* Final bundle size.
*/
size: number;
/**
* Total bundle build time.
*/
buildTime: number;
/**
* List of generated bundle modules.
*/
files: BuildEntryStats[];
}
type PickEntryChunkOptions = 'input' | 'name' | 'globals' | 'extend' | 'minify' | 'transformers';
type PickEntryDtsOptions = 'declaration' | 'dts' | 'transformers';
interface BuildEntryOptions extends EntryBase, Pick<EntryChunk, PickEntryChunkOptions>, Pick<EntryDeclaration, PickEntryDtsOptions> {
/**
* Specifies the path of the transformed file.
*
* @default undefined
*/
output?: string;
/**
* Specifies options for default plugins.
*
* @default undefined
*/
transformers?: TransformersChunk & TransformersDeclaration;
/**
* Specifies list of default plugins.
*/
defaultPlugins: Plugin[];
}
interface HooksOptions {
/**
* Called at the beginning of bundling.
*
* @example
*
* ```ts
* export default defineConfig({
* hooks: {
* 'bundle:start': async (options) => {
* // ...
* }
* }
* })
* ```
*
* @default undefined
*/
'bundle:start'?: (options: Options) => void | Promise<void>;
/**
* Called at the beginning of building.
*
* @example
*
* ```ts
* export default defineConfig({
* hooks: {
* 'build:start': async (options, stats) => {
* // ...
* }
* }
* })
* ```
*
* @default undefined
*/
'build:start'?: (options: Options, stats: BuildStats) => void | Promise<void>;
/**
* Called on each entry just before the build process.
*
* Provides the ability to customize entry options before they are passed to the next phase.
*
* @example
*
* ```ts
* export default defineConfig({
* hooks: {
* 'build:entry:start': async (entry, stats) => {
* // ...
* }
* }
* })
* ```
*
* @default undefined
*/
'build:entry:start'?: (entry: BuildEntryOptions, stats: BuildEntryStats) => void | Promise<void>;
/**
* Called on each entry right after the build process is completed.
*
* @example
*
* ```ts
* export default defineConfig({
* hooks: {
* 'build:entry:end': async (entry, stats) => {
* // ...
* }
* }
* })
* ```
*
* @default undefined
*/
'build:entry:end'?: (entry: BuildEntryOptions, stats: BuildEntryStats) => void | Promise<void>;
/**
* Called right after building is complete.
*
* @example
*
* ```ts
* export default defineConfig({
* hooks: {
* 'build:end': async (options, stats) => {
* // ...
* }
* }
* })
* ```
*
* @default undefined
*/
'build:end'?: (options: Options, stats: BuildStats) => void | Promise<void>;
/**
* Called right after bundling is complete.
*
* @example
*
* ```ts
* export default defineConfig({
* hooks: {
* 'bundle:end': async (options) => {
* // ...
* }
* }
* })
* ```
*
* @default undefined
*/
'bundle:end'?: (options: Options) => void | Promise<void>;
}
interface ConfigLoader {
options: Options;
path: string;
}
/**
* List of global defaults for externals.
*
* @example
*
* ```ts
* import { externals } from '@hypernym/bundler'
*
* export default defineConfig({
* entries: [
* {
* input: './src/index.ts',
* externals: [...externals, 'id', /regexp/]
* },
* ]
* })
* ```
*/
declare const externals: RegExp[];
/**
* `Hyperbundler` automatically detects custom configuration from the project root that can override or extend the build behavior.
*
* Configuration file also accepts `.js`, `.mjs`, `.ts`, `.mts` formats.
*
* @example
*
* ```ts
* import { defineConfig } from '@hypernym/bundler'
*
* export default defineConfig({
* // ...
* })
* ```
*/
declare function defineConfig(options: Options): Options;
/**
* Resolves external module IDs into custom paths.
*
* @example
*
* ```ts
* import { defineConfig, resolvePaths } from '@hypernym/bundler'
*
* export default defineConfig({
* entries: [
* {
* input: './src/index.ts',
* externals: [/^@\/path/],
* paths: resolvePaths([
* // replaces `@/path` with `./path/index.mjs`
* { find: /^@\/path/, replacement: './path/index.mjs', }
* ]),
* },
* ]
* })
* ```
*/
declare function resolvePaths(options: ResolvePathsOptions[]): (id: string) => string;
interface ResolvePathsOptions {
find: string | RegExp;
replacement: string;
}
export { defineConfig, externals, resolvePaths };
export type { BuildLogs, BuildStats, ConfigLoader, CopyOptions, EntryBase, EntryChunk, EntryCopy, EntryDeclaration, EntryOptions, EntryTemplate, HooksOptions, Options, ResolvePathsOptions, TransformersChunk, TransformersDeclaration };