diff --git a/bin/src/run/build.ts b/bin/src/run/build.ts index fd5e28595b8..fc4c0183e57 100644 --- a/bin/src/run/build.ts +++ b/bin/src/run/build.ts @@ -3,11 +3,11 @@ import ms from 'pretty-ms'; import * as rollup from 'rollup'; import { InputOptions, - OutputBundle, + OutputAsset, OutputChunk, OutputOptions, RollupBuild, - RollupSingleFileBuild + RollupOutput } from '../../../src/rollup/types'; import { mapSequence } from '../../../src/utils/promise'; import relativeId from '../../../src/utils/relativeId'; @@ -22,12 +22,7 @@ export default function build( warnings: BatchWarnings, silent = false ) { - const useStdout = - outputOptions.length === 1 && - !outputOptions[0].file && - !outputOptions[0].dir && - inputOptions.input instanceof Array === false && - typeof inputOptions.input !== 'object'; + const useStdout = !outputOptions[0].file && !outputOptions[0].dir; const start = Date.now(); const files = useStdout ? ['stdout'] : outputOptions.map(t => relativeId(t.file || t.dir)); @@ -47,7 +42,7 @@ export default function build( return rollup .rollup(inputOptions) - .then((bundle: RollupSingleFileBuild | RollupBuild) => { + .then((bundle: RollupBuild) => { if (useStdout) { const output = outputOptions[0]; if (output.sourcemap && output.sourcemap !== 'inline') { @@ -57,22 +52,29 @@ export default function build( }); } - return (bundle).generate(output).then(({ code, map }) => { - if (!code) return; - if (output.sourcemap === 'inline') { - code += `\n//# ${SOURCEMAPPING_URL}=${map.toUrl()}\n`; + return bundle.generate(output).then(({ output: outputs }) => { + for (const file of outputs) { + let source: string | Buffer; + if ((file).isAsset) { + source = (file).source; + } else { + source = (file).code; + if (output.sourcemap === 'inline') { + source += `\n//# ${SOURCEMAPPING_URL}=${(file).map.toUrl()}\n`; + } + } + if (outputs.length > 1) + process.stdout.write(`\n${chalk.cyan(chalk.bold(file.fileName))}:\n`); + process.stdout.write(source); } - - process.stdout.write(code); }); } - return mapSequence>( - outputOptions, - output => bundle.write(output) + return mapSequence>(outputOptions, output => + bundle.write(output) ).then(() => bundle); }) - .then((bundle?: RollupSingleFileBuild | RollupBuild) => { + .then((bundle?: RollupBuild) => { warnings.flush(); if (!silent) stderr( diff --git a/bin/src/run/index.ts b/bin/src/run/index.ts index 461292a0914..15c2d8841f7 100644 --- a/bin/src/run/index.ts +++ b/bin/src/run/index.ts @@ -20,29 +20,24 @@ export default function runRollup(command: any) { } } - if (command.dir) { - if (command._.length && !command._.some((input: string) => input.indexOf('=') !== -1)) { - command.input = command._; - } else if ( - command._.length || - Array.isArray(command.input) || - typeof command.input === 'string' - ) { - let input: string[]; - if (command._.length) input = command._; - else input = typeof command.input === 'string' ? [command.input] : command.input; - command.input = {}; - input.forEach((input: string) => { - const equalsIndex = input.indexOf('='); - const value = input.substr(equalsIndex + 1); - let key = input.substr(0, equalsIndex); - if (!key) key = getAliasName(input); - command.input[key] = value; - }); - } - command._ = []; - } else if (command._.length === 1) { - command.input = command._[0]; + if (command._.length && !command._.some((input: string) => input.indexOf('=') !== -1)) { + command.input = command._; + } else if ( + command._.length || + Array.isArray(command.input) || + typeof command.input === 'string' + ) { + let input: string[]; + if (command._.length) input = command._; + else input = typeof command.input === 'string' ? [command.input] : command.input; + command.input = {}; + input.forEach((input: string) => { + const equalsIndex = input.indexOf('='); + const value = input.substr(equalsIndex + 1); + let key = input.substr(0, equalsIndex); + if (!key) key = getAliasName(input); + command.input[key] = value; + }); } if (command.environment) { diff --git a/bin/src/run/loadConfigFile.ts b/bin/src/run/loadConfigFile.ts index fe7a3eaab3e..89014a592c4 100644 --- a/bin/src/run/loadConfigFile.ts +++ b/bin/src/run/loadConfigFile.ts @@ -1,7 +1,7 @@ import chalk from 'chalk'; import path from 'path'; import rollup from 'rollup'; -import { InputOptions, RollupSingleFileBuild } from '../../../src/rollup/types'; +import { InputOptions, RollupBuild, RollupOutput } from '../../../src/rollup/types'; import relativeId from '../../../src/utils/relativeId'; import { handleError, stderr } from '../logging'; import batchWarnings from './batchWarnings'; @@ -20,12 +20,13 @@ export default function loadConfigFile( return rollup .rollup({ input: configFile, + treeshake: false, external: (id: string) => { return (id[0] !== '.' && !path.isAbsolute(id)) || id.slice(-5, id.length) === '.json'; }, onwarn: warnings.add }) - .then((bundle: RollupSingleFileBuild) => { + .then((bundle: RollupBuild) => { if (!silent && warnings.count > 0) { stderr(chalk.bold(`loaded ${relativeId(configFile)} with warnings`)); warnings.flush(); @@ -35,7 +36,7 @@ export default function loadConfigFile( format: 'cjs' }); }) - .then(({ code }: { code: string }) => { + .then(({ output: [{ code }] }: RollupOutput) => { // temporarily override require const defaultLoader = require.extensions['.js']; require.extensions['.js'] = (module: NodeModuleWithCompile, filename: string) => { diff --git a/src/rollup/index.ts b/src/rollup/index.ts index 90c37f6e86a..b363c8e7f2a 100644 --- a/src/rollup/index.ts +++ b/src/rollup/index.ts @@ -1,29 +1,27 @@ import { optimizeChunks } from '../chunk-optimization'; import Graph from '../Graph'; import { createAddons } from '../utils/addons'; +import { createAssetPluginHooks, finaliseAsset } from '../utils/assetHooks'; import commondir from '../utils/commondir'; import { Deprecation } from '../utils/deprecateOptions'; import ensureArray from '../utils/ensureArray'; import error from '../utils/error'; import { writeFile } from '../utils/fs'; +import getExportMode from '../utils/getExportMode'; import mergeOptions, { GenericConfigObject } from '../utils/mergeOptions'; import { basename, dirname, resolve } from '../utils/path'; import { SOURCEMAPPING_URL } from '../utils/sourceMappingURL'; import { getTimings, initialiseTimers, timeEnd, timeStart } from '../utils/timers'; - -import Chunk from '../Chunk'; -import { createAssetPluginHooks, finaliseAsset } from '../utils/assetHooks'; -import getExportMode from '../utils/getExportMode'; import { Watcher } from '../watch'; import { InputOptions, + OutputAsset, OutputBundle, OutputChunk, - OutputFile, OutputOptions, Plugin, RollupBuild, - RollupSingleFileBuild, + RollupOutput, WarningHandler } from './types'; @@ -105,25 +103,6 @@ function getInputOptions(rawInputOptions: GenericConfigObject): any { inputOptions.plugins = ensureArray(inputOptions.plugins); inputOptions = inputOptions.plugins.reduce(applyOptionHook, inputOptions); - if (!inputOptions.experimentalCodeSplitting) { - inputOptions.inlineDynamicImports = true; - if (inputOptions.manualChunks) - error({ - code: 'INVALID_OPTION', - message: '"manualChunks" option is only supported for experimentalCodeSplitting.' - }); - if (inputOptions.optimizeChunks) - error({ - code: 'INVALID_OPTION', - message: '"optimizeChunks" option is only supported for experimentalCodeSplitting.' - }); - if (inputOptions.input instanceof Array || typeof inputOptions.input === 'object') - error({ - code: 'INVALID_OPTION', - message: 'Multiple inputs are only supported for experimentalCodeSplitting.' - }); - } - if (inputOptions.inlineDynamicImports) { if (inputOptions.manualChunks) error({ @@ -136,26 +115,29 @@ function getInputOptions(rawInputOptions: GenericConfigObject): any { code: 'INVALID_OPTION', message: '"optimizeChunks" option is not supported for inlineDynamicImports.' }); - if (inputOptions.input instanceof Array || typeof inputOptions.input === 'object') + if ( + (inputOptions.input instanceof Array && inputOptions.input.length > 1) || + (typeof inputOptions.input === 'object' && Object.keys(inputOptions.input).length > 1) + ) error({ code: 'INVALID_OPTION', message: 'Multiple inputs are not supported for inlineDynamicImports.' }); - } else if (inputOptions.experimentalPreserveModules) { + } else if (inputOptions.preserveModules) { if (inputOptions.inlineDynamicImports) error({ code: 'INVALID_OPTION', - message: `experimentalPreserveModules does not support the inlineDynamicImports option.` + message: `preserveModules does not support the inlineDynamicImports option.` }); if (inputOptions.manualChunks) error({ code: 'INVALID_OPTION', - message: 'experimentalPreserveModules does not support the manualChunks option.' + message: 'preserveModules does not support the manualChunks option.' }); if (inputOptions.optimizeChunks) error({ code: 'INVALID_OPTION', - message: 'experimentalPreserveModules does not support the optimizeChunks option.' + message: 'preserveModules does not support the optimizeChunks option.' }); } @@ -167,9 +149,7 @@ export function setWatcher(watcher: Watcher) { curWatcher = watcher; } -export default function rollup( - rawInputOptions: GenericConfigObject -): Promise { +export default function rollup(rawInputOptions: GenericConfigObject): Promise { try { const inputOptions = getInputOptions(rawInputOptions); initialiseTimers(inputOptions); @@ -185,7 +165,7 @@ export default function rollup( inputOptions.input, inputOptions.manualChunks, inputOptions.inlineDynamicImports, - inputOptions.experimentalPreserveModules + inputOptions.preserveModules ) ) .then( @@ -201,63 +181,26 @@ export default function rollup( .then(chunks => { timeEnd('BUILD', 1); - // TODO: deprecate legacy single chunk return - let singleChunk: Chunk | void; - const singleInput = - typeof inputOptions.input === 'string' || - (inputOptions.input instanceof Array && inputOptions.input.length === 1); - //let imports: string[], exports: string[]; - if (!inputOptions.experimentalPreserveModules) { - if (singleInput) { - for (const chunk of chunks) { - if (chunk.entryModule === undefined) continue; - if (singleChunk) { - singleChunk = undefined; - break; - } - singleChunk = chunk; - } - } - } - // ensure we only do one optimization pass per build let optimized = false; function generate(rawOutputOptions: GenericConfigObject, isWrite: boolean) { const outputOptions = normalizeOutputOptions(inputOptions, rawOutputOptions); - if (inputOptions.experimentalCodeSplitting) { - if (typeof outputOptions.file === 'string' && typeof outputOptions.dir === 'string') - error({ - code: 'INVALID_OPTION', - message: - 'Build must set either output.file for a single-file build or output.dir when generating multiple chunks.' - }); - if (chunks.length > 1) { - if (outputOptions.format === 'umd' || outputOptions.format === 'iife') - error({ - code: 'INVALID_OPTION', - message: - 'UMD and IIFE output formats are not supported with the experimentalCodeSplitting option.' - }); - - if (outputOptions.sourcemapFile) - error({ - code: 'INVALID_OPTION', - message: '"sourcemapFile" is only supported for single-file builds.' - }); - } - if (!singleChunk && typeof outputOptions.file === 'string') - error({ - code: 'INVALID_OPTION', - message: singleInput - ? 'When building a bundle using dynamic imports, the output.dir option must be used, not output.file. Alternatively set inlineDynamicImports: true to output a single file.' - : 'When building multiple entry point inputs, the output.dir option must be used, not output.file.' - }); - } - - if (!outputOptions.file && inputOptions.experimentalCodeSplitting) - singleChunk = undefined; + if (typeof outputOptions.file === 'string' && typeof outputOptions.dir === 'string') + error({ + code: 'INVALID_OPTION', + message: + 'Build must set either output.file for a single-file build or output.dir when generating multiple chunks.' + }); + if ( + chunks.length > 1 && + (outputOptions.format === 'umd' || outputOptions.format === 'iife') + ) + error({ + code: 'INVALID_OPTION', + message: 'UMD and IIFE output formats are not supported for code-splitting builds.' + }); timeStart('GENERATE', 1); @@ -273,8 +216,7 @@ export default function rollup( .then(addons => { // pre-render all chunks for (const chunk of chunks) { - if (!inputOptions.experimentalPreserveModules) - chunk.generateInternalExports(outputOptions); + if (!inputOptions.preserveModules) chunk.generateInternalExports(outputOptions); if (chunk.isEntryModuleFacade) chunk.exportMode = getExportMode(chunk, outputOptions); } @@ -293,22 +235,9 @@ export default function rollup( const exports = chunk.getExportNames(); const modules = chunk.renderedModules; - if (chunk === singleChunk) { - singleChunk.id = basename( - outputOptions.file || - (inputOptions.input instanceof Array - ? inputOptions.input[0] - : inputOptions.input) - ); - const outputChunk: OutputChunk = { - imports, - exports, - modules, - code: undefined, - map: undefined - }; - outputBundle[singleChunk.id] = outputChunk; - } else if (inputOptions.experimentalPreserveModules) { + if (outputOptions.file) { + chunk.id = basename(outputOptions.file); + } else if (inputOptions.preserveModules) { chunk.generateIdPreserveModules(inputBase); } else { let pattern, patternName; @@ -322,6 +251,8 @@ export default function rollup( chunk.generateId(pattern, patternName, addons, outputOptions, outputBundle); } outputBundle[chunk.id] = { + fileName: chunk.id, + isEntry: chunk.entryModule !== undefined, imports, exports, modules, @@ -390,56 +321,47 @@ export default function rollup( } const cache = graph.getCache(); - const result: RollupSingleFileBuild | RollupBuild = { + const result: RollupBuild = { cache, generate: ((rawOutputOptions: GenericConfigObject) => { - const promise = generate(rawOutputOptions, false).then( - result => - inputOptions.experimentalCodeSplitting - ? { output: result } - : result[chunks[0].id] - ); + const promise = generate(rawOutputOptions, false).then(result => createOutput(result)); Object.defineProperty(promise, 'code', throwAsyncGenerateError); Object.defineProperty(promise, 'map', throwAsyncGenerateError); return promise; }), write: ((outputOptions: OutputOptions) => { - if ( - inputOptions.experimentalCodeSplitting && - (!outputOptions || (!outputOptions.dir && !outputOptions.file)) - ) { + if (!outputOptions || (!outputOptions.dir && !outputOptions.file)) { error({ code: 'MISSING_OPTION', message: 'You must specify output.file or output.dir for the build.' }); - } else if ( - !inputOptions.experimentalCodeSplitting && - (!outputOptions || !outputOptions.file) - ) { - error({ - code: 'MISSING_OPTION', - message: 'You must specify output.file.' - }); } - return generate(outputOptions, true).then(result => - Promise.all( + return generate(outputOptions, true).then(result => { + if (Object.keys(result).length > 1) { + if (outputOptions.sourcemapFile) + error({ + code: 'INVALID_OPTION', + message: '"sourcemapFile" is only supported for single-file builds.' + }); + if (typeof outputOptions.file === 'string') + error({ + code: 'INVALID_OPTION', + message: + 'When building multiple chunks, the output.dir option must be used, not output.file.' + + (typeof inputOptions.input !== 'string' || + inputOptions.inlineDynamicImports === true + ? '' + : ' To inline dynamic imports set the inlineDynamicImports: true option.') + }); + } + return Promise.all( Object.keys(result).map(chunkId => { - return writeOutputFile(graph, chunkId, result[chunkId], outputOptions); + return writeOutputFile(graph, result[chunkId], outputOptions); }) - ).then( - () => - inputOptions.experimentalCodeSplitting - ? { output: result } - : result[chunks[0].id] - ) - ); + ).then(() => createOutput(result)); + }); }) }; - if (!inputOptions.experimentalCodeSplitting) { - (result).imports = (singleChunk).getImportIds(); - (result).exports = (singleChunk).getExportNames(); - (result).modules = cache.modules; - } if (inputOptions.perf === true) result.getTimings = getTimings; return result; }); @@ -448,40 +370,53 @@ export default function rollup( } } -function isOutputChunk(file: OutputFile): file is OutputChunk { - return typeof (file).code === 'string'; +function createOutput(outputBundle: Record): RollupOutput { + return { + output: Object.keys(outputBundle) + .map(fileName => outputBundle[fileName]) + .sort((outputFileA, outputFileB) => { + // sort by entry chunks, shared chunks, then assets + if (isOutputAsset(outputFileA)) return isOutputAsset(outputFileB) ? 0 : 1; + if (isOutputAsset(outputFileB)) return -1; + if (outputFileA.isEntry) return outputFileB.isEntry ? 0 : -1; + outputFileB.isEntry ? 1 : 0; + }) + }; +} + +function isOutputAsset(file: OutputAsset | OutputChunk): file is OutputAsset { + return (file).isAsset === true; } function writeOutputFile( graph: Graph, - outputFileName: string, - outputFile: OutputFile, + outputFile: OutputAsset | OutputChunk, outputOptions: OutputOptions ): Promise { - const filename = resolve(outputOptions.dir || dirname(outputOptions.file), outputFileName); + const filename = resolve(outputOptions.dir || dirname(outputOptions.file), outputFile.fileName); let writeSourceMapPromise: Promise; let source: string | Buffer; - if (isOutputChunk(outputFile)) { + if (isOutputAsset(outputFile)) { + source = outputFile.source; + } else { source = outputFile.code; if (outputOptions.sourcemap && outputFile.map) { let url: string; if (outputOptions.sourcemap === 'inline') { url = outputFile.map.toUrl(); } else { - url = `${basename(outputFileName)}.map`; + url = `${basename(outputFile.fileName)}.map`; writeSourceMapPromise = writeFile(`${filename}.map`, outputFile.map.toString()); } source += `//# ${SOURCEMAPPING_URL}=${url}\n`; } - } else { - source = outputFile; } return writeFile(filename, source) .then(() => writeSourceMapPromise) .then( () => - isOutputChunk(outputFile) && + !isOutputAsset(outputFile) && Promise.all( graph.plugins .filter(plugin => plugin.onwrite) diff --git a/src/rollup/types.d.ts b/src/rollup/types.d.ts index 23fb5d61f54..716b9eb5ef6 100644 --- a/src/rollup/types.d.ts +++ b/src/rollup/types.d.ts @@ -135,6 +135,10 @@ export type ResolveDynamicImportHook = ( export type AddonHook = string | ((this: PluginContext) => string | Promise); +export interface OutputBundle { + [fileName: string]: OutputAsset | OutputChunk; +} + export interface Plugin { name: string; options?: (options: InputOptions) => InputOptions | void; @@ -142,23 +146,24 @@ export interface Plugin { resolveId?: ResolveIdHook; missingExport?: MissingExportHook; transform?: TransformHook; - // TODO: deprecate + /** @deprecated */ transformBundle?: TransformChunkHook; transformChunk?: TransformChunkHook; buildStart?: (this: PluginContext, options: InputOptions) => Promise | void; buildEnd?: (this: PluginContext, err?: any) => Promise | void; - // TODO: deprecate + /** @deprecated */ ongenerate?: ( this: PluginContext, options: OutputOptions, chunk: OutputChunk ) => void | Promise; - // TODO: deprecate + /** @deprecated */ onwrite?: ( this: PluginContext, options: OutputOptions, chunk: OutputChunk ) => void | Promise; + /** @deprecated */ generateBundle?: ( this: PluginContext, options: OutputOptions, @@ -199,9 +204,8 @@ export interface InputOptions { moduleContext?: string | ((id: string) => string) | { [id: string]: string }; watch?: WatcherOptions; inlineDynamicImports?: boolean; - experimentalCodeSplitting?: boolean; preserveSymlinks?: boolean; - experimentalPreserveModules?: boolean; + preserveModules?: boolean; optimizeChunks?: boolean; chunkGroupingSize?: number; @@ -212,9 +216,13 @@ export interface InputOptions { /** @deprecated */ entry?: string; + /** @deprecated */ transform?: TransformHook; + /** @deprecated */ load?: LoadHook; + /** @deprecated */ resolveId?: ResolveIdHook; + /** @deprecated */ resolveExternal?: any; } @@ -258,23 +266,14 @@ export interface OutputOptions { namespaceToStringTag?: boolean; compact?: boolean; - // undocumented? + /** @deprecated */ noConflict?: boolean; - - // deprecated + /** @deprecated */ dest?: string; + /** @deprecated */ moduleId?: string; } -export interface OutputOptionsFile extends OutputOptions { - file?: string; -} - -export interface OutputOptionsDir extends OutputOptions { - // only required for bundles.write - dir?: string; -} - export interface RollupWarning { message?: string; code?: string; @@ -308,7 +307,12 @@ export interface SerializedTimings { [label: string]: number; } -export type OutputFile = string | Buffer | OutputChunk; +export interface OutputAsset { + isAsset: true; + code?: undefined; + fileName: string; + source: string | Buffer; +} export interface RenderedModule { renderedExports: string[]; @@ -318,6 +322,8 @@ export interface RenderedModule { } export interface OutputChunk { + fileName: string; + isEntry: boolean; imports: string[]; exports: string[]; modules: { @@ -331,43 +337,26 @@ export interface RollupCache { modules: ModuleJSON[]; } -export interface RollupSingleFileBuild { - // TODO: consider deprecating to match code splitting - imports: string[]; - exports: { name: string; originalName: string; moduleId: string }[]; - modules: ModuleJSON[]; - cache: RollupCache; - - generate: (outputOptions: OutputOptions) => Promise; - write: (options: OutputOptions) => Promise; - getTimings?: () => SerializedTimings; -} - -export interface OutputBundle { - [fileName: string]: OutputChunk | OutputFile; +export interface RollupOutput { + // when supported in TypeScript (https://github.com/Microsoft/TypeScript/pull/24897): + // output: [OutputChunk, ...(OutputChunk | OutputAsset)[]]; + output: (OutputChunk | OutputAsset)[]; } export interface RollupBuild { cache: RollupCache; - generate: (outputOptions: OutputOptions) => Promise<{ output: OutputBundle }>; - write: (options: OutputOptions) => Promise<{ output: OutputBundle }>; + generate: (outputOptions: OutputOptions) => Promise; + write: (options: OutputOptions) => Promise; getTimings?: () => SerializedTimings; } -export interface RollupFileOptions extends InputOptions { - cache?: RollupCache; - input: string; - output?: OutputOptionsFile; -} - -export interface RollupDirOptions extends InputOptions { +export interface RollupOptions extends InputOptions { cache?: RollupCache; - input: string[] | { [entryName: string]: string }; - output?: OutputOptionsDir; + input: string | string[] | { [entryName: string]: string }; + output?: OutputOptions; } -export function rollup(options: RollupFileOptions): Promise; -export function rollup(options: RollupDirOptions): Promise; +export function rollup(options: RollupOptions): Promise; export interface Watcher extends EventEmitter {} diff --git a/src/utils/assetHooks.ts b/src/utils/assetHooks.ts index b9d1b3908de..886d019bef4 100644 --- a/src/utils/assetHooks.ts +++ b/src/utils/assetHooks.ts @@ -101,5 +101,9 @@ export function createAssetPluginHooks( export function finaliseAsset(asset: Asset, outputBundle: OutputBundle, assetFileNames: string) { const fileName = getAssetFileName(asset, outputBundle, assetFileNames); asset.fileName = fileName; - outputBundle[fileName] = asset.source; + outputBundle[fileName] = { + isAsset: true, + fileName, + source: asset.source + }; } diff --git a/src/utils/mergeOptions.ts b/src/utils/mergeOptions.ts index a7c614ccfdf..f92761287f1 100644 --- a/src/utils/mergeOptions.ts +++ b/src/utils/mergeOptions.ts @@ -200,8 +200,6 @@ function getInputOptions( acornInjectPlugins: config.acornInjectPlugins, cache: getOption('cache'), context: config.context, - experimentalCodeSplitting: getOption('experimentalCodeSplitting'), - experimentalPreserveModules: getOption('experimentalPreserveModules'), external: getExternal(config, command), inlineDynamicImports: getOption('inlineDynamicImports', false), input: getOption('input'), @@ -213,11 +211,16 @@ function getInputOptions( perf: getOption('perf', false), plugins: config.plugins, preferConst: getOption('preferConst'), + preserveModules: getOption('preserveModules'), preserveSymlinks: getOption('preserveSymlinks'), treeshake: getObjectOption(config, command, 'treeshake'), watch: config.watch }; + // support rollup({ cache: prevBuildObject }) + if (inputOptions.cache && (inputOptions.cache).cache) + inputOptions.cache = (inputOptions.cache).cache; + // legacy to make sure certain plugins still work if (Array.isArray(inputOptions.input)) { inputOptions.entry = inputOptions.input[0]; diff --git a/test/chunking-form/index.js b/test/chunking-form/index.js index ccf4317555c..f3fe41d8cd2 100644 --- a/test/chunking-form/index.js +++ b/test/chunking-form/index.js @@ -27,7 +27,6 @@ describe('chunking form', () => { {}, { input: [samples + '/' + dir + '/main.js'], - experimentalCodeSplitting: true, onwarn: msg => { if (/No name was provided for/.test(msg)) return; if (/as external dependency/.test(msg)) return; diff --git a/test/chunking-form/samples/preserve-modules-empty/_config.js b/test/chunking-form/samples/preserve-modules-empty/_config.js index 18b2eac8492..40a998bf69b 100644 --- a/test/chunking-form/samples/preserve-modules-empty/_config.js +++ b/test/chunking-form/samples/preserve-modules-empty/_config.js @@ -2,6 +2,6 @@ module.exports = { description: 'Preserve modules remove empty dependencies', options: { input: 'main.js', - experimentalPreserveModules: true + preserveModules: true } }; diff --git a/test/chunking-form/samples/preserve-modules-export-alias/_config.js b/test/chunking-form/samples/preserve-modules-export-alias/_config.js index ecc66ba447f..5b0d222a443 100644 --- a/test/chunking-form/samples/preserve-modules-export-alias/_config.js +++ b/test/chunking-form/samples/preserve-modules-export-alias/_config.js @@ -2,6 +2,6 @@ module.exports = { description: 'confirm export aliases are preserved in modules', options: { input: ['main1.js', 'main2.js'], - experimentalPreserveModules: true + preserveModules: true } }; diff --git a/test/chunking-form/samples/preserve-modules-non-entry-imports/_config.js b/test/chunking-form/samples/preserve-modules-non-entry-imports/_config.js index c671aa639b3..c5fa075124d 100644 --- a/test/chunking-form/samples/preserve-modules-non-entry-imports/_config.js +++ b/test/chunking-form/samples/preserve-modules-non-entry-imports/_config.js @@ -2,6 +2,6 @@ module.exports = { description: 'imports and exports of non-entry points are tracked', options: { input: 'main.js', - experimentalPreserveModules: true + preserveModules: true } }; diff --git a/test/chunking-form/samples/preserve-modules-reaching-outside/_config.js b/test/chunking-form/samples/preserve-modules-reaching-outside/_config.js index fc9a082ba88..ac0a33eec3d 100644 --- a/test/chunking-form/samples/preserve-modules-reaching-outside/_config.js +++ b/test/chunking-form/samples/preserve-modules-reaching-outside/_config.js @@ -2,6 +2,6 @@ module.exports = { description: 'change the module destination', options: { input: 'src/lib/main.js', - experimentalPreserveModules: true + preserveModules: true } }; diff --git a/test/chunking-form/samples/preserve-modules-single-entry/_config.js b/test/chunking-form/samples/preserve-modules-single-entry/_config.js index 19425bc35a4..0a48e7f9c8b 100644 --- a/test/chunking-form/samples/preserve-modules-single-entry/_config.js +++ b/test/chunking-form/samples/preserve-modules-single-entry/_config.js @@ -2,6 +2,6 @@ module.exports = { description: 'single entry names file correctly', options: { input: 'main.js', - experimentalPreserveModules: true + preserveModules: true } }; diff --git a/test/chunking-form/samples/preserve-modules/_config.js b/test/chunking-form/samples/preserve-modules/_config.js index e2537fe0c1a..7c666fc33ab 100644 --- a/test/chunking-form/samples/preserve-modules/_config.js +++ b/test/chunking-form/samples/preserve-modules/_config.js @@ -2,6 +2,6 @@ module.exports = { description: 'Rewrite modules in-place', options: { input: ['main1.js', 'main2.js'], - experimentalPreserveModules: true + preserveModules: true } }; diff --git a/test/form/samples/dynamic-import-inlining/_config.js b/test/form/samples/dynamic-import-inlining/_config.js index 7a849e05263..a83eaef5244 100644 --- a/test/form/samples/dynamic-import-inlining/_config.js +++ b/test/form/samples/dynamic-import-inlining/_config.js @@ -1,3 +1,6 @@ module.exports = { - description: 'dynamic import inlining' + description: 'dynamic import inlining', + options: { + inlineDynamicImports: true + } }; diff --git a/test/function/index.js b/test/function/index.js index 011aad0b484..42c10008e86 100644 --- a/test/function/index.js +++ b/test/function/index.js @@ -57,7 +57,7 @@ describe('function', () => { }) ); }) - .then(code => { + .then(({ output: [code] }) => { if (config.generateError) { unintendedError = new Error('Expected an error while generating output'); } diff --git a/test/function/samples/adds-timings-to-bundle-when-codesplitting/_config.js b/test/function/samples/adds-timings-to-bundle-when-codesplitting/_config.js index 06a9a88d783..862fa789fb2 100644 --- a/test/function/samples/adds-timings-to-bundle-when-codesplitting/_config.js +++ b/test/function/samples/adds-timings-to-bundle-when-codesplitting/_config.js @@ -5,7 +5,6 @@ module.exports = { description: 'Adds timing information to bundle when bundling with perf=true', options: { input: ['main1.js', 'main2.js'], - experimentalCodeSplitting: true, perf: true }, bundle(bundle) { diff --git a/test/function/samples/duplicate-input-entry-fails/_config.js b/test/function/samples/duplicate-input-entry-fails/_config.js index d58f90fde25..dc44ba1a1a2 100644 --- a/test/function/samples/duplicate-input-entry-fails/_config.js +++ b/test/function/samples/duplicate-input-entry-fails/_config.js @@ -3,7 +3,6 @@ const path = require('path'); module.exports = { description: 'duplicate entry modules', options: { - experimentalCodeSplitting: true, input: ['main.js', 'main.js'] }, error: { diff --git a/test/function/samples/dynamic-import-duplicates/_config.js b/test/function/samples/dynamic-import-duplicates/_config.js index f553fb9240c..37a8ab80e18 100644 --- a/test/function/samples/dynamic-import-duplicates/_config.js +++ b/test/function/samples/dynamic-import-duplicates/_config.js @@ -4,6 +4,7 @@ var path = require('path'); module.exports = { description: 'Dynamic import inlining', options: { + inlineDynamicImports: true, plugins: [ { resolveDynamicImport(specifier, parent) { diff --git a/test/function/samples/dynamic-import-inlining/_config.js b/test/function/samples/dynamic-import-inlining/_config.js index f553fb9240c..37a8ab80e18 100644 --- a/test/function/samples/dynamic-import-inlining/_config.js +++ b/test/function/samples/dynamic-import-inlining/_config.js @@ -4,6 +4,7 @@ var path = require('path'); module.exports = { description: 'Dynamic import inlining', options: { + inlineDynamicImports: true, plugins: [ { resolveDynamicImport(specifier, parent) { diff --git a/test/function/samples/has-modules-array/_config.js b/test/function/samples/has-modules-array/_config.js index 38f2ec9664d..cdd8c1413e1 100644 --- a/test/function/samples/has-modules-array/_config.js +++ b/test/function/samples/has-modules-array/_config.js @@ -4,9 +4,9 @@ var assert = require('assert'); module.exports = { description: 'user-facing bundle has modules array', bundle: function(bundle) { - assert.ok(bundle.modules); - assert.equal(bundle.modules.length, 2); - assert.equal(path.relative(bundle.modules[1].id, path.resolve(__dirname, 'foo.js')), ''); - assert.equal(path.relative(bundle.modules[0].id, path.resolve(__dirname, 'main.js')), ''); + assert.ok(bundle.cache.modules); + assert.equal(bundle.cache.modules.length, 2); + assert.equal(path.relative(bundle.cache.modules[1].id, path.resolve(__dirname, 'foo.js')), ''); + assert.equal(path.relative(bundle.cache.modules[0].id, path.resolve(__dirname, 'main.js')), ''); } }; diff --git a/test/function/samples/has-resolved-ids/_config.js b/test/function/samples/has-resolved-ids/_config.js deleted file mode 100644 index a90e503ae02..00000000000 --- a/test/function/samples/has-resolved-ids/_config.js +++ /dev/null @@ -1,13 +0,0 @@ -var path = require('path'); -var assert = require('assert'); - -module.exports = { - description: 'user-facing bundle has resolvedIds map in every modules', - bundle: function(bundle) { - assert.ok(bundle.modules[0].resolvedIds); - assert.ok(bundle.modules[1].resolvedIds); - assert.equal(Object.keys(bundle.modules[1].resolvedIds).length, 0); - assert.equal(Object.keys(bundle.modules[0].resolvedIds).length, 1); - assert.equal(bundle.modules[0].resolvedIds['./foo'], path.resolve(__dirname, 'foo.js')); - } -}; diff --git a/test/function/samples/has-resolved-ids/foo.js b/test/function/samples/has-resolved-ids/foo.js deleted file mode 100644 index 7a4e8a723a4..00000000000 --- a/test/function/samples/has-resolved-ids/foo.js +++ /dev/null @@ -1 +0,0 @@ -export default 42; diff --git a/test/function/samples/has-resolved-ids/main.js b/test/function/samples/has-resolved-ids/main.js deleted file mode 100644 index 3206f53821c..00000000000 --- a/test/function/samples/has-resolved-ids/main.js +++ /dev/null @@ -1,2 +0,0 @@ -import foo from './foo'; -assert.equal( foo, 42 ); diff --git a/test/function/samples/manual-chunks-invalid/_config.js b/test/function/samples/manual-chunks-invalid/_config.js index e1567665c2b..b23619f458a 100644 --- a/test/function/samples/manual-chunks-invalid/_config.js +++ b/test/function/samples/manual-chunks-invalid/_config.js @@ -1,7 +1,6 @@ module.exports = { description: 'manual chunks support', options: { - experimentalCodeSplitting: true, input: ['main.js'], manualChunks: { 'dep1': ['dep1.js'], diff --git a/test/function/samples/module-tree/_config.js b/test/function/samples/module-tree/_config.js index 389ce982ba3..fd032360b88 100644 --- a/test/function/samples/module-tree/_config.js +++ b/test/function/samples/module-tree/_config.js @@ -4,7 +4,7 @@ const assert = require('assert'); module.exports = { description: 'bundle.modules includes dependencies (#903)', bundle(bundle) { - const modules = bundle.modules.map(module => { + const modules = bundle.cache.modules.map(module => { return { id: path.relative(__dirname, module.id), dependencies: module.dependencies.map(id => path.relative(__dirname, id)) diff --git a/test/hooks/index.js b/test/hooks/index.js index cafd48b8f6e..a7ce2ceb5b5 100644 --- a/test/hooks/index.js +++ b/test/hooks/index.js @@ -125,7 +125,7 @@ describe('hooks', () => { .then(bundle => { return bundle.generate({ format: 'es' }); }) - .then(output => { + .then(({ output: [output] }) => { assert.equal(output.code, `alert('hello');\n`); }); }); @@ -251,7 +251,6 @@ describe('hooks', () => { return rollup .rollup({ input: 'input', - experimentalCodeSplitting: true, plugins: [ loader({ input: '' }), { @@ -266,8 +265,12 @@ describe('hooks', () => { return bundle.generate({ format: 'es' }); }) .then(({ output }) => { - assert.equal(output['assets/test-19916f7d.ext'], 'hello world'); - assert.equal(output['input.js'].code, `var input = new URL('../assets/test-19916f7d.ext', import.meta.url).href;\n\nexport default input;\n`); + assert.equal(output[1].isAsset, true); + assert.equal(output[1].fileName, 'assets/test-19916f7d.ext') + assert.equal(output[1].source, 'hello world'); + assert.equal(output[0].fileName, 'input.js'); + assert.equal(output[0].isEntry, true); + assert.equal(output[0].code, `var input = new URL('../assets/test-19916f7d.ext', import.meta.url).href;\n\nexport default input;\n`); }); }); @@ -275,7 +278,6 @@ describe('hooks', () => { return rollup .rollup({ input: 'input', - experimentalCodeSplitting: true, plugins: [ loader({ input: '' }), { @@ -289,8 +291,8 @@ describe('hooks', () => { .then(bundle => { return bundle.generate({ format: 'cjs' }); }) - .then(({ output }) => { - assert.equal(output['input.js'].code, `'use strict'; + .then(({ output: [{ code }] }) => { + assert.equal(code, `'use strict'; var input = new (typeof URL !== 'undefined' ? URL : require('ur'+'l').URL)((process.browser ? '' : 'file:') + __dirname + '/assets/test-19916f7d.ext', process.browser && document.baseURI).href; @@ -303,7 +305,6 @@ module.exports = input; return rollup .rollup({ input: 'input', - experimentalCodeSplitting: true, plugins: [ loader({ input: `alert('hello')` }), { @@ -320,8 +321,9 @@ module.exports = input; assetFileNames: '[name][extname]' }); }) - .then(({ output }) => { - assert.equal(output['test.ext'], 'hello world'); + .then(({ output: [,output] }) => { + assert.equal(output.fileName, 'test.ext'); + assert.equal(output.source, 'hello world'); }); }); @@ -330,7 +332,6 @@ module.exports = input; return rollup .rollup({ input: 'input', - experimentalCodeSplitting: true, plugins: [ loader({ input: `alert('hello')` }), { @@ -347,8 +348,9 @@ module.exports = input; .then(bundle => { return bundle.generate({ format: 'es' }); }) - .then(({ output }) => { - assert.equal(output['assets/test-19916f7d.ext'], 'hello world'); + .then(({ output: [,output] }) => { + assert.equal(output.fileName, 'assets/test-19916f7d.ext'); + assert.equal(output.source, 'hello world'); }); }); @@ -356,7 +358,6 @@ module.exports = input; return rollup .rollup({ input: 'input', - experimentalCodeSplitting: true, plugins: [ loader({ input: `alert('hello')` }), { @@ -378,8 +379,9 @@ module.exports = input; .then(bundle => { return bundle.generate({ format: 'es' }); }) - .then(({ output }) => { - assert.equal(output['assets/test-19916f7d.ext'], 'hello world'); + .then(({ output: [,output] }) => { + assert.equal(output.fileName, 'assets/test-19916f7d.ext'); + assert.equal(output.source, 'hello world'); }); }); @@ -388,7 +390,6 @@ module.exports = input; return rollup .rollup({ input: 'input', - experimentalCodeSplitting: true, plugins: [ loader({ input: `alert('hello')` }), { @@ -405,8 +406,8 @@ module.exports = input; .then(bundle => { return bundle.generate({ format: 'es' }); }) - .then(({ output }) => { - assert.equal(output['assets/test-19916f7d.ext'], 'hello world'); + .then(({ output: [,output] }) => { + assert.equal(output.source, 'hello world'); }); }); @@ -415,7 +416,6 @@ module.exports = input; return rollup .rollup({ input: 'input', - experimentalCodeSplitting: true, plugins: [ loader({ input: `alert('hello')` }), { @@ -447,7 +447,6 @@ module.exports = input; return rollup .rollup({ input: 'input', - experimentalCodeSplitting: true, plugins: [ loader({ input: `alert('hello')` }), { @@ -479,7 +478,6 @@ module.exports = input; return rollup .rollup({ input: 'input', - experimentalCodeSplitting: true, plugins: [ loader({ input: `alert('hello')` }), { @@ -488,7 +486,7 @@ module.exports = input; return `export default import.meta.ROLLUP_ASSET_URL_${assetId};`; }, generateBundle (options, outputBundle, isWrite) { - assert.equal(outputBundle['assets/test-19916f7d.ext'], 'hello world'); + assert.equal(outputBundle['assets/test-19916f7d.ext'].source, 'hello world'); assert.equal(outputBundle['input.js'].code, `var input = new URL('../assets/test-19916f7d.ext', import.meta.url).href;\n\nexport default input;\n`); } } @@ -503,7 +501,6 @@ module.exports = input; return rollup .rollup({ input: 'input', - experimentalCodeSplitting: true, plugins: [ loader({ input: `alert('hello')` }), { @@ -529,15 +526,15 @@ module.exports = input; ) ) .then(([{ output: output1 }, { output: output2 }]) => { - assert.equal(output1['input.js'].code, `alert('hello');\n`); - assert.equal(output1['assets/lateDepAsset-671f747d'], `custom source`); - assert.equal(output1['assets/lateMainAsset-863ea4b5'], `references assets/lateDepAsset-671f747d`); - - assert.equal(output2['input.js'].code, `'use strict';\n\nalert('hello');\n`); - assert.equal(output2['assets/lateDepAsset-671f747d'], undefined); - assert.equal(output2['assets/lateMainAsset-863ea4b5'], undefined); - assert.equal(output2['assets/lateDepAsset-c107f5fc'], `different source`); - assert.equal(output2['assets/lateMainAsset-6dc2262b'], `references assets/lateDepAsset-c107f5fc`); + assert.equal(output1.length, 3); + assert.equal(output1[0].code, `alert('hello');\n`); + assert.equal(output1[1].source, 'custom source'); + assert.equal(output1[2].source, `references assets/lateDepAsset-671f747d`); + + assert.equal(output2.length, 3); + assert.equal(output2[0].code, `'use strict';\n\nalert('hello');\n`); + assert.equal(output2[1].source, 'different source'); + assert.equal(output2[2].source, `references assets/lateDepAsset-c107f5fc`); }); }); @@ -545,7 +542,6 @@ module.exports = input; return rollup .rollup({ input: 'input', - experimentalCodeSplitting: true, plugins: [ loader({ input: `alert('hello')` }), { @@ -568,7 +564,6 @@ module.exports = input; return rollup .rollup({ input: 'input', - experimentalCodeSplitting: true, plugins: [ loader({ input: `export { a as default } from 'dep';`, diff --git a/test/incremental/index.js b/test/incremental/index.js index aa3592ad314..681d2fc3705 100644 --- a/test/incremental/index.js +++ b/test/incremental/index.js @@ -47,7 +47,7 @@ describe('incremental', () => { return rollup.rollup({ input: 'entry', plugins: [plugin], - cache: bundle + cache: bundle.cache }); }) .then(bundle => { @@ -76,7 +76,7 @@ describe('incremental', () => { assert.equal(result, 42); modules.foo = `export default 43`; - cache = bundle; + cache = bundle.cache; }); }) .then(() => { @@ -111,7 +111,7 @@ describe('incremental', () => { assert.equal(result, 42); modules.entry = `import bar from 'bar'; export default bar;`; - cache = bundle; + cache = bundle.cache; }); }) .then(() => { @@ -139,7 +139,7 @@ describe('incremental', () => { }) .then(bundle => { const asts = {}; - bundle.modules.forEach(module => { + bundle.cache.modules.forEach(module => { asts[module.id] = module.ast; }); @@ -200,12 +200,11 @@ describe('incremental', () => { plugins: [plugin] }) .then(bundle => { - assert.deepEqual(bundle.imports, ['external']); - assert.equal(bundle.modules[1].id, 'foo'); - assert.equal(bundle.modules[0].id, 'entry'); + assert.equal(bundle.cache.modules[1].id, 'foo'); + assert.equal(bundle.cache.modules[0].id, 'entry'); - assert.deepEqual(bundle.modules[0].resolvedIds, { + assert.deepEqual(bundle.cache.modules[0].resolvedIds, { foo: 'foo', external: 'external' }); diff --git a/test/misc/index.js b/test/misc/index.js index a5189905c63..0bfa0aa2485 100644 --- a/test/misc/index.js +++ b/test/misc/index.js @@ -95,7 +95,7 @@ describe('sanity checks', () => { .then(bundle => { return bundle.generate({ format: 'iife' }); }) - .then(({ code }) => { + .then(({ output: [{ code }] }) => { assert.ok(code[code.length - 1] === '\n'); }); }); @@ -175,7 +175,7 @@ describe('in-memory sourcemaps', () => { sourcemapFile: path.resolve('bundle.js') }); }) - .then(generated => { + .then(({ output: [generated] }) => { const smc = new SourceMapConsumer(generated.map); const locator = getLocator(generated.code, { offsetLine: 1 }); @@ -200,7 +200,7 @@ describe('deprecations', () => { } }) .then(executeBundle) - .then(result => { + .then((result) => { assert.equal(result, 42); assert.deepEqual(warnings, [ { @@ -272,7 +272,7 @@ describe('deprecations', () => { return rollup .rollup({ input: 'x', plugins: [loader({ x: 'export const x = function () {}' })] }) .then(bundle => bundle.generate({ format: 'esm' })) - .then(({ code }) => { + .then(({ output: [{ code }] }) => { assert.equal(code, 'const x = function () {};\n\nexport { x };\n'); }); }); diff --git a/test/misc/optionList.js b/test/misc/optionList.js index e35a0a4af62..f7222e4d082 100644 --- a/test/misc/optionList.js +++ b/test/misc/optionList.js @@ -1,3 +1,3 @@ -exports.input = 'acorn, acornInjectPlugins, cache, chunkGroupingSize, context, entry, experimentalCodeSplitting, experimentalPreserveModules, external, inlineDynamicImports, input, manualChunks, moduleContext, onwarn, optimizeChunks, perf, plugins, preferConst, preserveSymlinks, treeshake, watch'; -exports.flags = 'acorn, acornInjectPlugins, amd, assetFileNames, banner, c, cache, chunkFileNames, chunkGroupingSize, compact, config, context, dir, e, entry, entryFileNames, environment, esModule, experimentalCodeSplitting, experimentalPreserveModules, exports, extend, external, f, file, footer, format, freeze, g, globals, h, i, indent, inlineDynamicImports, input, interop, intro, m, manualChunks, moduleContext, n, name, namespaceToStringTag, noConflict, o, onwarn, optimizeChunks, outro, paths, perf, plugins, preferConst, preserveSymlinks, silent, sourcemap, sourcemapFile, strict, treeshake, v, w, watch'; +exports.input = 'acorn, acornInjectPlugins, cache, chunkGroupingSize, context, entry, external, inlineDynamicImports, input, manualChunks, moduleContext, onwarn, optimizeChunks, perf, plugins, preferConst, preserveModules, preserveSymlinks, treeshake, watch'; +exports.flags = 'acorn, acornInjectPlugins, amd, assetFileNames, banner, c, cache, chunkFileNames, chunkGroupingSize, compact, config, context, dir, e, entry, entryFileNames, environment, esModule, exports, extend, external, f, file, footer, format, freeze, g, globals, h, i, indent, inlineDynamicImports, input, interop, intro, m, manualChunks, moduleContext, n, name, namespaceToStringTag, noConflict, o, onwarn, optimizeChunks, outro, paths, perf, plugins, preferConst, preserveModules, preserveSymlinks, silent, sourcemap, sourcemapFile, strict, treeshake, v, w, watch'; exports.output = 'amd, assetFileNames, banner, dir, chunkFileNames, compact, entryFileNames, exports, extend, file, footer, format, freeze, esModule, globals, indent, interop, intro, name, namespaceToStringTag, noConflict, outro, paths, sourcemap, sourcemapFile, strict'; diff --git a/test/sourcemaps/index.js b/test/sourcemaps/index.js index caf1585334b..15a08c4ef75 100644 --- a/test/sourcemaps/index.js +++ b/test/sourcemaps/index.js @@ -50,7 +50,7 @@ describe('sourcemaps', () => { throw new Error(`Unexpected warnings`); } - return bundle.generate(outputOptions).then(({ code, map }) => { + return bundle.generate(outputOptions).then(({ output: [{ code, map }] }) => { if (config.test) { return config.test(code, map, { format }); } diff --git a/test/utils.js b/test/utils.js index ed1e8fd6236..a54c30ad29e 100644 --- a/test/utils.js +++ b/test/utils.js @@ -63,7 +63,7 @@ function executeBundle(bundle) { .generate({ format: 'cjs' }) - .then(cjs => { + .then(({ output: [cjs] }) => { const m = new Function('module', 'exports', cjs.code); const module = { exports: {} };