Skip to content

Commit

Permalink
fix: Throw error only when 'umd' or 'iife' are used
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmyersdev committed Sep 3, 2022
1 parent 4158b98 commit 6f47bbb
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 20 deletions.
101 changes: 99 additions & 2 deletions packages/vite/src/node/__tests__/build.spec.ts
@@ -1,8 +1,10 @@
import { resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import { describe, expect, test } from 'vitest'
import type { OutputOptions } from 'rollup'
import { describe, expect, test, vi } from 'vitest'
import type { LibraryFormats, LibraryOptions } from '../build'
import { resolveLibFilename } from '../build'
import { resolveBuildOutputs, resolveLibFilename } from '../build'
import { createLogger } from '../logger'

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

Expand All @@ -12,6 +14,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
45 changes: 27 additions & 18 deletions packages/vite/src/node/build.ts
Expand Up @@ -644,36 +644,45 @@ 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']
if (
(formats.includes('umd') || formats.includes('iife')) &&
!libOptions.name
) {
throw new Error(
`Option "build.lib.name" is required when output formats ` +
`include "umd" or "iife".`
)
const libFormats = libOptions.formats || ['es', 'umd']

if (!Array.isArray(outputs)) {
const requiresName =
libFormats.includes('umd') || libFormats.includes('iife')

if (requiresName && !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 6f47bbb

Please sign in to comment.