Skip to content

Commit

Permalink
feat(lib): multiple entries for umd/iife
Browse files Browse the repository at this point in the history
  • Loading branch information
schummar committed Oct 23, 2022
1 parent de6323f commit 0fc767d
Show file tree
Hide file tree
Showing 4 changed files with 367 additions and 96 deletions.
2 changes: 1 addition & 1 deletion docs/config/build-options.md
Expand Up @@ -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']`, 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 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'` and entry is not defined as object (in which case the object keys define names for each entry). 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
Expand Down
142 changes: 139 additions & 3 deletions packages/vite/src/node/__tests__/build.spec.ts
Expand Up @@ -3,7 +3,11 @@ import { fileURLToPath } from 'node:url'
import type { Logger } from 'vite'
import { describe, expect, test } from 'vitest'
import type { LibraryFormats, LibraryOptions } from '../build'
import { resolveBuildOutputs, resolveLibFilename } from '../build'
import {
resolveBuildOutputs,
resolveBuilds,
resolveLibFilename
} from '../build'

const __dirname = resolve(fileURLToPath(import.meta.url), '..')

Expand Down Expand Up @@ -253,7 +257,12 @@ describe('resolveBuildOutputs', () => {
name: 'entryA'
}

const outputs = resolveBuildOutputs(undefined, libOptions, {} as Logger)
const outputs = resolveBuildOutputs(
libOptions.entry,
undefined,
libOptions,
{} as Logger
)

expect(outputs).toEqual([{ format: 'es' }, { format: 'umd' }])
})
Expand All @@ -263,8 +272,135 @@ describe('resolveBuildOutputs', () => {
entry: ['entryA.js', 'entryB.js']
}

const outputs = resolveBuildOutputs(undefined, libOptions, {} as Logger)
const outputs = resolveBuildOutputs(
libOptions.entry,
undefined,
libOptions,
{} as Logger
)

expect(outputs).toEqual([{ format: 'es' }, { format: 'cjs' }])
})

test('error on missing name', () => {
const libOptions: LibraryOptions = {
entry: 'entryA.js',
formats: ['umd']
}

expect(() =>
resolveBuildOutputs(libOptions.entry, undefined, libOptions, {} as Logger)
).toThrow(
'Entries must be defined as object or option "build.lib.name" must be provided when output formats include "umd" or "iife".'
)
})

test('error on missing names for multiple entries', () => {
const libOptions: LibraryOptions = {
entry: ['entryA.js', 'entryB.js'],
formats: ['umd']
}

expect(() =>
resolveBuildOutputs(libOptions.entry, undefined, libOptions, {} as Logger)
).toThrow(
'Entries must be defined as object when there are multiple entries and output formats include "umd" or "iife".'
)
})
})

describe('resolveBuilds', () => {
test('one entry, one build', () => {
const libOptions: LibraryOptions = {
entry: 'entryA.js',
name: 'entryA',
formats: ['es', 'cjs', 'umd', 'iife']
}

const builds = resolveBuilds(
libOptions.entry,
undefined,
libOptions,
(_input) => (output) => output,
{} as Logger
)

expect(builds).toEqual([
{
input: 'entryA.js',
output: [
{ format: 'es' },
{ format: 'cjs' },
{ format: 'umd' },
{ format: 'iife' }
]
}
])
})

test('multiple entries, one build', () => {
const libOptions: LibraryOptions = {
entry: {
entryA: 'entryA.js',
entryB: 'entryB.js'
},
formats: ['es', 'cjs']
}

const builds = resolveBuilds(
libOptions.entry,
undefined,
libOptions,
(_input) => (output) => output,
{} as Logger
)

expect(builds).toEqual([
{
input: {
entryA: 'entryA.js',
entryB: 'entryB.js'
},
output: [{ format: 'es' }, { format: 'cjs' }]
}
])
})

test('multiple builds', () => {
const libOptions: LibraryOptions = {
entry: {
entryA: 'entryA.js',
entryB: 'entryB.js'
},
formats: ['es', 'cjs', 'umd', 'iife']
}

const builds = resolveBuilds(
libOptions.entry,
undefined,
libOptions,
(_input) => (output) => output,
{} as Logger
)

expect(builds).toEqual([
{
input: {
entryA: 'entryA.js',
entryB: 'entryB.js'
},
output: [{ format: 'es' }, { format: 'cjs' }]
},
{
input: { entryA: 'entryA.js' },
output: [{ format: 'umd' }, { format: 'iife' }],
label: 'Extra non code splitting build for entry: entryA'
},
{
input: { entryB: 'entryB.js' },
output: [{ format: 'umd' }, { format: 'iife' }],
label: 'Extra non code splitting build for entry: entryB'
}
])
})
})

0 comments on commit 0fc767d

Please sign in to comment.