diff --git a/docs/config/build-options.md b/docs/config/build-options.md index a40f62f3ceb8a8..da1d33d453e8d1 100644 --- a/docs/config/build-options.md +++ b/docs/config/build-options.md @@ -148,7 +148,7 @@ Options to pass on to [@rollup/plugin-dynamic-import-vars](https://github.com/ro - **Type:** `{ entry: string | string[] | { [entryAlias: string]: string }, name?: string, formats?: ('es' | 'cjs' | 'umd' | 'iife')[], fileName?: string | ((format: ModuleFormat, entryName: string) => string) }` - **Related:** [Library Mode](/guide/build#library-mode) -Build as a library. `entry` is required since the library cannot use HTML as entry. `name` is the exposed global variable and is required when `formats` includes `'umd'` or `'iife'`. Default `formats` are `['es', 'umd']`. `fileName` is the name of the package file output, default `fileName` is the name option of package.json, it can also be defined as function taking the `format` and `entryAlias` as arguments. +Build as a library. `entry` is required since the library cannot use HTML as entry. `name` is the exposed global variable and is required when `formats` includes `'umd'` or `'iife'`. Default `formats` are `['es', 'umd']`, or `['es', 'cjs']`, if multiple entries are used. `fileName` is the name of the package file output, default `fileName` is the name option of package.json, it can also be defined as function taking the `format` and `entryAlias` as arguments. ## build.manifest diff --git a/packages/vite/src/node/__tests__/build.spec.ts b/packages/vite/src/node/__tests__/build.spec.ts index e12187b1ce6dfc..27984280b4c38b 100644 --- a/packages/vite/src/node/__tests__/build.spec.ts +++ b/packages/vite/src/node/__tests__/build.spec.ts @@ -1,8 +1,9 @@ import { resolve } from 'node:path' import { fileURLToPath } from 'node:url' +import type { Logger } from 'vite' import { describe, expect, test } from 'vitest' import type { LibraryFormats, LibraryOptions } from '../build' -import { resolveLibFilename } from '../build' +import { resolveBuildOutputs, resolveLibFilename } from '../build' const __dirname = resolve(fileURLToPath(import.meta.url), '..') @@ -244,3 +245,26 @@ describe('resolveLibFilename', () => { expect(fileName2).toBe('custom-filename.mjs') }) }) + +describe('resolveBuildOutputs', () => { + test('default format: one entry', () => { + const libOptions: LibraryOptions = { + entry: 'entryA.js', + name: 'entryA' + } + + const outputs = resolveBuildOutputs(undefined, libOptions, {} as Logger) + + expect(outputs).toEqual([{ format: 'es' }, { format: 'umd' }]) + }) + + test('default format: multiple entries', () => { + const libOptions: LibraryOptions = { + entry: ['entryA.js', 'entryB.js'] + } + + const outputs = resolveBuildOutputs(undefined, libOptions, {} as Logger) + + expect(outputs).toEqual([{ format: 'es' }, { format: 'cjs' }]) + }) +}) diff --git a/packages/vite/src/node/build.ts b/packages/vite/src/node/build.ts index 9ed62f8d72b940..94f08c14b17b64 100644 --- a/packages/vite/src/node/build.ts +++ b/packages/vite/src/node/build.ts @@ -746,18 +746,21 @@ export function resolveLibFilename( return `${name}.${format}.${extension}` } -function resolveBuildOutputs( +export function resolveBuildOutputs( outputs: OutputOptions | OutputOptions[] | undefined, libOptions: LibraryOptions | false, logger: Logger ): OutputOptions | OutputOptions[] | undefined { if (libOptions) { - const formats = libOptions.formats || ['es', 'umd'] + const hasMultipleEntries = + typeof libOptions.entry !== 'string' && + Object.values(libOptions.entry).length > 1 + + const formats = + libOptions.formats || (hasMultipleEntries ? ['es', 'cjs'] : ['es', 'umd']) + if (formats.includes('umd') || formats.includes('iife')) { - if ( - typeof libOptions.entry !== 'string' && - Object.values(libOptions.entry).length > 1 - ) { + if (hasMultipleEntries) { throw new Error( `Multiple entry points are not supported when output formats include "umd" or "iife".` )