Skip to content

Commit

Permalink
fix: throw missing name error only when 'umd' or 'iife' are used (#9886)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmyersdev authored Nov 8, 2022
1 parent 0c295e0 commit b8aa825
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 24 deletions.
99 changes: 98 additions & 1 deletion packages/vite/src/node/__tests__/build.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import type { Logger } from 'vite'
import { describe, expect, test } from 'vitest'
import { describe, expect, test, vi } from 'vitest'
import type { OutputOptions } from 'rollup'
import type { LibraryFormats, LibraryOptions } from '../build'
import { resolveBuildOutputs, resolveLibFilename } from '../build'
import { createLogger } from '../logger'

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

Expand All @@ -13,6 +15,101 @@ const baseLibOptions: LibraryOptions = {
entry: 'mylib.js'
}

describe('resolveBuildOutputs', () => {
test('resolves outputs correctly', () => {
const logger = createLogger()
const libOptions: LibraryOptions = { ...baseLibOptions }
const outputs: OutputOptions[] = [{ format: 'es' }]
const resolvedOutputs = resolveBuildOutputs(outputs, libOptions, logger)

expect(resolvedOutputs).toEqual([
{
format: 'es'
}
])
})

test('resolves outputs from lib options', () => {
const logger = createLogger()
const libOptions: LibraryOptions = { ...baseLibOptions, name: 'lib' }
const resolvedOutputs = resolveBuildOutputs(void 0, libOptions, logger)

expect(resolvedOutputs).toEqual([
{
format: 'es'
},
{
format: 'umd'
}
])
})

test('does not change outputs when lib options are missing', () => {
const logger = createLogger()
const outputs: OutputOptions[] = [{ format: 'es' }]
const resolvedOutputs = resolveBuildOutputs(outputs, false, logger)

expect(resolvedOutputs).toEqual(outputs)
})

test('logs a warning when outputs is an array and formats are specified', () => {
const logger = createLogger()
const loggerSpy = vi.spyOn(logger, 'warn').mockImplementation(() => {})
const libOptions: LibraryOptions = {
...baseLibOptions,
formats: ['iife']
}
const outputs: OutputOptions[] = [{ format: 'es' }]

resolveBuildOutputs(outputs, libOptions, logger)

expect(loggerSpy).toHaveBeenCalledWith(
expect.stringContaining('"build.lib.formats" will be ignored because')
)
})

test('throws an error when lib.name is missing on iife format', () => {
const logger = createLogger()
const libOptions: LibraryOptions = {
...baseLibOptions,
formats: ['iife']
}
const resolveBuild = () => resolveBuildOutputs(void 0, libOptions, logger)

expect(resolveBuild).toThrowError(/Option "build\.lib\.name" is required/)
})

test('throws an error when lib.name is missing on umd format', () => {
const logger = createLogger()
const libOptions: LibraryOptions = { ...baseLibOptions, formats: ['umd'] }
const resolveBuild = () => resolveBuildOutputs(void 0, libOptions, logger)

expect(resolveBuild).toThrowError(/Option "build\.lib\.name" is required/)
})

test('throws an error when output.name is missing on iife format', () => {
const logger = createLogger()
const libOptions: LibraryOptions = { ...baseLibOptions }
const outputs: OutputOptions[] = [{ format: 'iife' }]
const resolveBuild = () => resolveBuildOutputs(outputs, libOptions, logger)

expect(resolveBuild).toThrowError(
/Entries in "build\.rollupOptions\.output" must specify "name"/
)
})

test('throws an error when output.name is missing on umd format', () => {
const logger = createLogger()
const libOptions: LibraryOptions = { ...baseLibOptions }
const outputs: OutputOptions[] = [{ format: 'umd' }]
const resolveBuild = () => resolveBuildOutputs(outputs, libOptions, logger)

expect(resolveBuild).toThrowError(
/Entries in "build\.rollupOptions\.output" must specify "name"/
)
})
})

describe('resolveLibFilename', () => {
test('custom filename function', () => {
const filename = resolveLibFilename(
Expand Down
54 changes: 31 additions & 23 deletions packages/vite/src/node/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -783,41 +783,49 @@ export function resolveBuildOutputs(
logger: Logger
): OutputOptions | OutputOptions[] | undefined {
if (libOptions) {
const hasMultipleEntries =
const libHasMultipleEntries =
typeof libOptions.entry !== 'string' &&
Object.values(libOptions.entry).length > 1
const libFormats =
libOptions.formats ||
(libHasMultipleEntries ? ['es', 'cjs'] : ['es', 'umd'])

if (!Array.isArray(outputs)) {
if (libFormats.includes('umd') || libFormats.includes('iife')) {
if (libHasMultipleEntries) {
throw new Error(
'Multiple entry points are not supported when output formats include "umd" or "iife".'
)
}

const formats =
libOptions.formats || (hasMultipleEntries ? ['es', 'cjs'] : ['es', 'umd'])

if (formats.includes('umd') || formats.includes('iife')) {
if (hasMultipleEntries) {
throw new Error(
`Multiple entry points are not supported when output formats include "umd" or "iife".`
)
if (!libOptions.name) {
throw new Error(
'Option "build.lib.name" is required when output formats include "umd" or "iife".'
)
}
}

if (!libOptions.name) {
throw new Error(
`Option "build.lib.name" is required when output formats ` +
`include "umd" or "iife".`
)
}
return libFormats.map((format) => ({ ...outputs, format }))
}
if (!outputs) {
return formats.map((format) => ({ format }))
} else if (!Array.isArray(outputs)) {
return formats.map((format) => ({ ...outputs, format }))
} else if (libOptions.formats) {
// user explicitly specifying own output array

// By this point, we know "outputs" is an Array.
if (libOptions.formats) {
logger.warn(
colors.yellow(
`"build.lib.formats" will be ignored because ` +
`"build.rollupOptions.output" is already an array format`
'"build.lib.formats" will be ignored because "build.rollupOptions.output" is already an array format.'
)
)
}

outputs.forEach((output) => {
if (['umd', 'iife'].includes(output.format!) && !output.name) {
throw new Error(
'Entries in "build.rollupOptions.output" must specify "name" when the format is "umd" or "iife".'
)
}
})
}

return outputs
}

Expand Down

0 comments on commit b8aa825

Please sign in to comment.