From 37af402d5fe398d3fcfd07a871355cf71d8d1f76 Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Tue, 30 Aug 2022 14:10:58 +0200 Subject: [PATCH] [v3.0] Always try to load config files via Node if possible (#4621) * Support ES modules in bundles config files * Always try to load config files directly if possible * Fix build * Fix test * Debug test --- LICENSE.md | 29 ---- build-plugins/clean-before-write.ts | 4 +- build-plugins/copy-types.ts | 4 +- build-plugins/esm-dynamic-import.ts | 6 +- build-plugins/get-banner.ts | 11 +- cli/run/loadConfigFile.ts | 120 ++++++++------ docs/01-command-line-reference.md | 18 ++- package-lock.json | 7 +- package.json | 3 +- src/rollup/types.d.ts | 1 + src/utils/error.ts | 41 +++-- src/utils/options/mergeOptions.ts | 1 + test/cli/node_modules/esm-dep/index.js | 1 + test/cli/node_modules/esm-dep/package.json | 4 + .../rollup-plugin-esm-test/index.mjs | 0 .../rollup-plugin-esm-test/package.json | 2 +- .../node_modules_rename_me/esm-dep/index.js | 1 + .../esm-dep/package.json | 4 + .../rollup-plugin-esm-test/index.mjs | 9 ++ .../rollup-plugin-esm-test/package.json | 4 + .../{rollup.config.js => rollup.config.mjs} | 0 .../{rollup.config.js => rollup.config.mjs} | 0 .../config-defineConfig-mjs/_config.js | 1 - test/cli/samples/config-es6/_config.js | 2 +- .../{rollup.config.js => rollup.config.mjs} | 0 .../{rollup.config.js => rollup.config.mjs} | 0 .../config-function-modify-command/_config.js | 2 +- .../config-function-modify-command/main.js | 4 +- .../{rollup.config.js => rollup.config.mjs} | 0 test/cli/samples/config-function/_config.js | 2 +- test/cli/samples/config-function/main.js | 4 +- .../{rollup.config.js => rollup.config.mjs} | 0 .../cli/samples/config-import-meta/_config.js | 2 +- test/cli/samples/config-json/_config.js | 2 +- .../cli/samples/config-mjs-plugins/_config.js | 1 - .../{rollup.config.js => rollup.config.mjs} | 0 .../config-multiple-source-maps/_config.js | 2 +- test/cli/samples/config-no-module/_config.js | 16 -- .../samples/config-no-module/rollup.config.js | 7 - test/cli/samples/config-no-module/sub/main.js | 1 - .../{rollup.config.js => rollup.config.mjs} | 0 .../{rollup.config.js => rollup.config.mjs} | 0 .../samples/config-plugin-entry/_config.js | 2 +- .../cli/samples/config-promise-mjs/_config.js | 1 - test/cli/samples/config-promise/_config.js | 2 +- .../{rollup.config.js => rollup.config.mjs} | 0 test/cli/samples/config-true/_config.js | 2 +- .../cli/samples/config-type-module/_config.js | 2 +- test/cli/samples/config-warnings/_config.js | 2 +- test/cli/samples/custom-frame/_config.js | 2 +- .../{rollup.config.js => rollup.config.mjs} | 0 .../{rollup.config.js => rollup.config.mjs} | 0 .../{rollup.config.js => rollup.config.mjs} | 0 .../cli/samples/import-esm-package/_config.js | 5 + .../import-esm-package/_expected/main.js | 2 + test/cli/samples/import-esm-package/main.js | 1 + .../import-esm-package/rollup.config.js | 10 ++ .../{rollup.config.js => rollup.config.mjs} | 0 .../{rollup.config.js => rollup.config.mjs} | 0 .../{rollup.config.js => rollup.config.mjs} | 0 .../{rollup.config.js => rollup.config.mjs} | 0 .../samples/plugin/absolute-esm/_config.js | 1 - test/cli/samples/plugin/absolute/_config.js | 1 - .../samples/plugin/advanced-esm/_config.js | 3 +- .../{rollup.config.js => rollup.config.mjs} | 2 +- test/cli/samples/plugin/advanced/_config.js | 1 - .../{rollup.config.js => rollup.config.mjs} | 2 +- .../samples/plugin/named-export/_config.js | 1 - .../{rollup.config.js => rollup.config.mjs} | 2 +- .../samples/plugin/relative-esm/_config.js | 1 - .../{rollup.config.js => rollup.config.mjs} | 0 .../{rollup.config.js => rollup.config.mjs} | 0 .../{rollup.config.js => rollup.config.mjs} | 0 test/cli/samples/symlinked-config/_config.js | 2 +- .../samples/symlinked-named-config/_config.js | 2 +- .../{rollup.config.js => rollup.config.mjs} | 0 .../unfulfilled-hook-actions-error/_config.js | 1 - .../cli/samples/watch/bundle-error/_config.js | 2 +- .../{rollup.config.js => rollup.config.mjs} | 0 .../{rollup.config.js => rollup.config.mjs} | 0 .../{rollup.config.js => rollup.config.mjs} | 0 .../{rollup.config.js => rollup.config.mjs} | 0 .../{rollup.config.js => rollup.config.mjs} | 0 .../{rollup.config.js => rollup.config.mjs} | 0 .../watch-config-early-update/_config.js | 14 +- .../watch/watch-config-error/_config.js | 2 +- .../watch-config-initial-error/_config.js | 2 +- .../watch/watch-config-no-update/_config.js | 2 +- .../{rollup.config.js => rollup.config.mjs} | 0 .../{rollup.config.js => rollup.config.mjs} | 0 .../samples/class-method-returns/_config.js | 3 +- .../samples/class-prop-returns/_config.js | 1 - .../deoptimize-computed-class-keys/_config.js | 3 +- .../known-super-prop/_config.js | 3 +- .../unknown-super-prop/_config.js | 1 - .../known-super-prop/_config.js | 3 +- .../unknown-super-prop/_config.js | 1 - .../class-fields/_config.js | 3 +- test/load-config-file/index.js | 152 +++++++++++++++--- .../samples/cjs-as-esm/package.json | 3 + .../{basic => cjs-as-esm}/rollup.config.js | 0 .../samples/cjs-via-ext}/package.json | 0 .../samples/cjs-via-ext/rollup.config.cjs | 7 + .../samples/cjs-via-pkg/package.json | 3 + .../samples/cjs-via-pkg/rollup.config.js | 7 + .../samples/esm-as-cjs/package.json | 3 + .../samples/esm-as-cjs/rollup.config.js | 7 + .../samples/esm-via-ext/package.json | 3 + .../samples/esm-via-ext/rollup.config.mjs | 7 + .../samples/esm-via-pkg/package.json | 3 + .../samples/esm-via-pkg/rollup.config.js | 7 + .../samples/esm-with-error/package.json | 3 + .../samples/esm-with-error/rollup.config.js | 1 + test/misc/optionList.js | 2 +- typings/declarations.d.ts | 8 - 115 files changed, 400 insertions(+), 222 deletions(-) create mode 100644 test/cli/node_modules/esm-dep/index.js create mode 100644 test/cli/node_modules/esm-dep/package.json rename test/cli/{samples/plugin/advanced-esm => }/node_modules/rollup-plugin-esm-test/index.mjs (100%) rename test/cli/{samples/plugin/advanced-esm => }/node_modules/rollup-plugin-esm-test/package.json (50%) create mode 100644 test/cli/node_modules_rename_me/esm-dep/index.js create mode 100644 test/cli/node_modules_rename_me/esm-dep/package.json create mode 100644 test/cli/node_modules_rename_me/rollup-plugin-esm-test/index.mjs create mode 100644 test/cli/node_modules_rename_me/rollup-plugin-esm-test/package.json rename test/cli/samples/config-async-function/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/config-cwd-case-insensitive-es6/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/config-external-function/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/config-external/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/config-function-modify-command/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/config-function/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/config-multiple-getfilename/{rollup.config.js => rollup.config.mjs} (100%) delete mode 100644 test/cli/samples/config-no-module/_config.js delete mode 100644 test/cli/samples/config-no-module/rollup.config.js delete mode 100644 test/cli/samples/config-no-module/sub/main.js rename test/cli/samples/config-no-output/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/config-override/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/config-promise/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/emit-file-multiple-dirs/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/format-aliases/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/generated-code-preset-override/{rollup.config.js => rollup.config.mjs} (100%) create mode 100644 test/cli/samples/import-esm-package/_config.js create mode 100644 test/cli/samples/import-esm-package/_expected/main.js create mode 100644 test/cli/samples/import-esm-package/main.js create mode 100644 test/cli/samples/import-esm-package/rollup.config.js rename test/cli/samples/multiple-configs/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/multiple-targets-different-plugins/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/multiple-targets-shared-config/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/multiple-targets/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/plugin/advanced-esm/{rollup.config.js => rollup.config.mjs} (79%) rename test/cli/samples/plugin/advanced/{rollup.config.js => rollup.config.mjs} (79%) rename test/cli/samples/plugin/named-export/{rollup.config.js => rollup.config.mjs} (79%) rename test/cli/samples/silent-onwarn/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/stdin/config-file/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/stdin/no-stdin-config-file/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/treeshake-preset-override/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/watch/clearScreen/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/watch/close-error/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/watch/close-on-generate-error/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/watch/no-clearScreen/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/watch/no-watch-by-default/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/watch/no-watched-config/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/watch/watch-event-hooks-error/{rollup.config.js => rollup.config.mjs} (100%) rename test/cli/samples/watch/watch-event-hooks/{rollup.config.js => rollup.config.mjs} (100%) create mode 100644 test/load-config-file/samples/cjs-as-esm/package.json rename test/load-config-file/samples/{basic => cjs-as-esm}/rollup.config.js (100%) rename test/{cli/samples/config-no-module/sub => load-config-file/samples/cjs-via-ext}/package.json (100%) create mode 100644 test/load-config-file/samples/cjs-via-ext/rollup.config.cjs create mode 100644 test/load-config-file/samples/cjs-via-pkg/package.json create mode 100644 test/load-config-file/samples/cjs-via-pkg/rollup.config.js create mode 100644 test/load-config-file/samples/esm-as-cjs/package.json create mode 100644 test/load-config-file/samples/esm-as-cjs/rollup.config.js create mode 100644 test/load-config-file/samples/esm-via-ext/package.json create mode 100644 test/load-config-file/samples/esm-via-ext/rollup.config.mjs create mode 100644 test/load-config-file/samples/esm-via-pkg/package.json create mode 100644 test/load-config-file/samples/esm-via-pkg/rollup.config.js create mode 100644 test/load-config-file/samples/esm-with-error/package.json create mode 100644 test/load-config-file/samples/esm-with-error/rollup.config.js diff --git a/LICENSE.md b/LICENSE.md index f3e20d39822..f173e24c97e 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -240,35 +240,6 @@ Repository: jonschlinkert/fill-range --------------------------------------- -## get-package-type -License: MIT -By: Corey Farrell -Repository: git+https://github.com/cfware/get-package-type.git - -> MIT License -> -> Copyright (c) 2020 CFWare, LLC -> -> Permission is hereby granted, free of charge, to any person obtaining a copy -> of this software and associated documentation files (the "Software"), to deal -> in the Software without restriction, including without limitation the rights -> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -> copies of the Software, and to permit persons to whom the Software is -> furnished to do so, subject to the following conditions: -> -> The above copyright notice and this permission notice shall be included in all -> copies or substantial portions of the Software. -> -> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -> SOFTWARE. - ---------------------------------------- - ## glob-parent License: ISC By: Gulp Team, Elan Shanker, Blaine Bublitz diff --git a/build-plugins/clean-before-write.ts b/build-plugins/clean-before-write.ts index fc9109e7119..4239b8dafe8 100644 --- a/build-plugins/clean-before-write.ts +++ b/build-plugins/clean-before-write.ts @@ -1,4 +1,4 @@ -import { remove } from 'fs-extra'; +import fs from 'fs-extra'; import type { Plugin } from 'rollup'; export default function cleanBeforeWrite(dir: string): Plugin { @@ -7,7 +7,7 @@ export default function cleanBeforeWrite(dir: string): Plugin { generateBundle(_options, _bundle, isWrite) { if (isWrite) { // Only remove before first write, but make all writes wait on the removal - removePromise ||= remove(dir); + removePromise ||= fs.remove(dir); return removePromise; } }, diff --git a/build-plugins/copy-types.ts b/build-plugins/copy-types.ts index fbf97d841a9..84d55a8f842 100644 --- a/build-plugins/copy-types.ts +++ b/build-plugins/copy-types.ts @@ -1,5 +1,5 @@ import { resolve } from 'node:path'; -import { readFile } from 'fs-extra'; +import fs from 'fs-extra'; import type { Plugin } from 'rollup'; export default function copyTypes(fileName: string): Plugin { @@ -8,7 +8,7 @@ export default function copyTypes(fileName: string): Plugin { if (isWrite) { this.emitFile({ fileName, - source: await readFile(resolve('src/rollup/types.d.ts'), 'utf8'), + source: await fs.readFile(resolve('src/rollup/types.d.ts'), 'utf8'), type: 'asset' }); } diff --git a/build-plugins/esm-dynamic-import.ts b/build-plugins/esm-dynamic-import.ts index c776d489997..073852d18fd 100644 --- a/build-plugins/esm-dynamic-import.ts +++ b/build-plugins/esm-dynamic-import.ts @@ -1,12 +1,14 @@ import type { Plugin } from 'rollup'; +const expectedImports = 3; + export default function esmDynamicImport(): Plugin { let importsFound = 0; return { generateBundle() { - if (importsFound !== 2) { + if (importsFound !== expectedImports) { throw new Error( - 'Could not find 2 dynamic import in "loadConfigFile.ts" and "commandPlugin.ts", were the files renamed or modified?' + `Could not find ${expectedImports} dynamic imports in "loadConfigFile.ts" and "commandPlugin.ts", found ${importsFound}.` ); } }, diff --git a/build-plugins/get-banner.ts b/build-plugins/get-banner.ts index 5f6823e90b4..5a329b2a0a6 100644 --- a/build-plugins/get-banner.ts +++ b/build-plugins/get-banner.ts @@ -1,11 +1,11 @@ import { exec } from 'node:child_process'; +import { promises as fs } from 'node:fs'; import { env } from 'node:process'; import { promisify } from 'node:util'; -import { version } from '../package.json'; const execPromise = promisify(exec); -function generateBanner(commitHash: string): string { +function generateBanner(commitHash: string, version: string): string { const date = new Date( env.SOURCE_DATE_EPOCH ? 1000 * +env.SOURCE_DATE_EPOCH : Date.now() ).toUTCString(); @@ -24,7 +24,8 @@ function generateBanner(commitHash: string): string { let getBannerPromise: Promise | null = null; export default async function getBanner(): Promise { - return (getBannerPromise ||= execPromise('git rev-parse HEAD').then(({ stdout }) => - generateBanner(stdout.trim()) - )); + return (getBannerPromise ||= Promise.all([ + execPromise('git rev-parse HEAD'), + fs.readFile(new URL('../package.json', import.meta.url), 'utf8') + ]).then(([{ stdout }, pkg]) => generateBanner(stdout.trim(), JSON.parse(pkg).version))); } diff --git a/cli/run/loadConfigFile.ts b/cli/run/loadConfigFile.ts index 945888a96dc..986e1c0823e 100644 --- a/cli/run/loadConfigFile.ts +++ b/cli/run/loadConfigFile.ts @@ -1,10 +1,17 @@ -import { extname, isAbsolute } from 'node:path'; +import { promises as fs } from 'node:fs'; +import { dirname, isAbsolute, join } from 'node:path'; +import process from 'node:process'; import { pathToFileURL } from 'node:url'; -import getPackageType from 'get-package-type'; import * as rollup from '../../src/node-entry'; import type { MergedRollupOptions } from '../../src/rollup/types'; import { bold } from '../../src/utils/colors'; -import { errMissingConfig, error, errTranspiledEsmConfig } from '../../src/utils/error'; +import { + errCannotBundleConfigAsEsm, + errCannotLoadConfigAsCjs, + errCannotLoadConfigAsEsm, + errMissingConfig, + error +} from '../../src/utils/error'; import { mergeOptions } from '../../src/utils/options/mergeOptions'; import type { GenericConfigObject } from '../../src/utils/options/options'; import relativeId from '../../src/utils/relativeId'; @@ -12,15 +19,14 @@ import { stderr } from '../logging'; import batchWarnings, { type BatchWarnings } from './batchWarnings'; import { addCommandPluginsToInputOptions, addPluginsFromCommandOption } from './commandPlugins'; -interface NodeModuleWithCompile extends NodeModule { - _compile(code: string, filename: string): any; -} - export async function loadConfigFile( fileName: string, commandOptions: any = {} ): Promise<{ options: MergedRollupOptions[]; warnings: BatchWarnings }> { - const configs = await loadConfigsFromFile(fileName, commandOptions); + const configs = await getConfigList( + getDefaultFromCjs(await getConfigFileExport(fileName, commandOptions)), + commandOptions + ); const warnings = batchWarnings(); try { const normalizedConfigs: MergedRollupOptions[] = []; @@ -36,29 +42,51 @@ export async function loadConfigFile( } } -async function loadConfigsFromFile( - fileName: string, - commandOptions: Record -): Promise { - const extension = extname(fileName); - - const configFileExport = - commandOptions.configPlugin || - // We always transpile the .js non-module case because many legacy code bases rely on this - (extension === '.js' && getPackageType.sync(fileName) !== 'module') - ? await getDefaultFromTranspiledConfigFile(fileName, commandOptions) - : getDefaultFromCjs((await import(pathToFileURL(fileName).href)).default); - - return getConfigList(configFileExport, commandOptions); +async function getConfigFileExport(fileName: string, commandOptions: Record) { + if (commandOptions.configPlugin || commandOptions.bundleConfigAsCjs) { + try { + return await loadTranspiledConfigFile(fileName, commandOptions); + } catch (err: any) { + if (err.message.includes('not defined in ES module scope')) { + return error(errCannotBundleConfigAsEsm(err)); + } + throw err; + } + } + let cannotLoadEsm = false; + const handleWarning = (warning: Error): void => { + if (warning.message.includes('To load an ES module')) { + cannotLoadEsm = true; + } + }; + process.on('warning', handleWarning); + try { + const fileUrl = pathToFileURL(fileName); + if (process.env.ROLLUP_WATCH) { + // We are adding the current date to allow reloads in watch mode + fileUrl.search = `?${Date.now()}`; + } + return (await import(fileUrl.href)).default; + } catch (err: any) { + if (cannotLoadEsm) { + return error(errCannotLoadConfigAsCjs(err)); + } + if (err.message.includes('not defined in ES module scope')) { + return error(errCannotLoadConfigAsEsm(err)); + } + throw err; + } finally { + process.off('warning', handleWarning); + } } function getDefaultFromCjs(namespace: GenericConfigObject): unknown { - return namespace.__esModule ? namespace.default : namespace; + return namespace.default || namespace; } -async function getDefaultFromTranspiledConfigFile( +async function loadTranspiledConfigFile( fileName: string, - commandOptions: Record + { bundleConfigAsCjs, configPlugin, silent }: Record ): Promise { const warnings = batchWarnings(); const inputOptions = { @@ -69,9 +97,9 @@ async function getDefaultFromTranspiledConfigFile( plugins: [], treeshake: false }; - await addPluginsFromCommandOption(commandOptions.configPlugin, inputOptions); + await addPluginsFromCommandOption(configPlugin, inputOptions); const bundle = await rollup.rollup(inputOptions); - if (!commandOptions.silent && warnings.count > 0) { + if (!silent && warnings.count > 0) { stderr(bold(`loaded ${relativeId(fileName)} with warnings`)); warnings.flush(); } @@ -79,7 +107,7 @@ async function getDefaultFromTranspiledConfigFile( output: [{ code }] } = await bundle.generate({ exports: 'named', - format: 'cjs', + format: bundleConfigAsCjs ? 'cjs' : 'es', plugins: [ { name: 'transpile-import-meta', @@ -94,32 +122,22 @@ async function getDefaultFromTranspiledConfigFile( } ] }); - return loadConfigFromBundledFile(fileName, code); + return loadConfigFromWrittenFile( + join(dirname(fileName), `rollup.config-${Date.now()}.${bundleConfigAsCjs ? 'cjs' : 'mjs'}`), + code + ); } -function loadConfigFromBundledFile(fileName: string, bundledCode: string): unknown { - const resolvedFileName = require.resolve(fileName); - const extension = extname(resolvedFileName); - const defaultLoader = require.extensions[extension]; - require.extensions[extension] = (module: NodeModule, requiredFileName: string) => { - if (requiredFileName === resolvedFileName) { - (module as NodeModuleWithCompile)._compile(bundledCode, requiredFileName); - } else { - if (defaultLoader) { - defaultLoader(module, requiredFileName); - } - } - }; - delete require.cache[resolvedFileName]; +async function loadConfigFromWrittenFile( + bundledFileName: string, + bundledCode: string +): Promise { + await fs.writeFile(bundledFileName, bundledCode); try { - const config = getDefaultFromCjs(require(fileName)); - require.extensions[extension] = defaultLoader; - return config; - } catch (err: any) { - if (err.code === 'ERR_REQUIRE_ESM') { - return error(errTranspiledEsmConfig(fileName)); - } - throw err; + return (await import(pathToFileURL(bundledFileName).href)).default; + } finally { + // Not awaiting here saves some ms while potentially hiding a non-critical error + fs.unlink(bundledFileName); } } diff --git a/docs/01-command-line-reference.md b/docs/01-command-line-reference.md index 15a25b34da3..8a909a48fc8 100755 --- a/docs/01-command-line-reference.md +++ b/docs/01-command-line-reference.md @@ -18,11 +18,9 @@ export default { }; ``` -Typically, it is called `rollup.config.js` or `rollup.config.mjs` and sits in the root directory of your project. If you use the `.mjs` extension or have `type: "module"` in your `package.json` file, Rollup will directly use Node to import it, which is now the recommended way to define Rollup configurations. Note that there are some [caveats when using native Node ES modules](guide/en/#caveats-when-using-native-node-es-modules); +Typically, it is called `rollup.config.js` or `rollup.config.mjs` and sits in the root directory of your project. Unless the [`--configPlugin`](guide/en/#--configplugin-plugin) or [`--bundleConfigAsCjs`](guide/en/#--bundleconfigascjs) options are used, Rollup will directly use Node to import the file. Note that there are some [caveats when using native Node ES modules](guide/en/#caveats-when-using-native-node-es-modules) as Rollup will observe [Node ESM semantics](https://nodejs.org/docs/latest-v14.x/api/packages.html#packages_determining_module_system). -Otherwise, Rollup will transpile and bundle this file and its relative dependencies to CommonJS before requiring it to ensure compatibility with legacy code bases that use ES module syntax without properly respecting [Node ESM semantics](https://nodejs.org/docs/latest-v14.x/api/packages.html#packages_determining_module_system). - -If you want to write your configuration as a CommonJS module using `require` and `module.exports`, you should change the file extension to `.cjs`, which will prevent Rollup from trying to transpile the CommonJS file. +If you want to write your configuration as a CommonJS module using `require` and `module.exports`, you should change the file extension to `.cjs`. You can also use other languages for your configuration files like TypeScript. To do that, install a corresponding Rollup plugin like `@rollup/plugin-typescript` and use the [`--configPlugin`](guide/en/#--configplugin-plugin) option: @@ -243,7 +241,7 @@ Besides `RollupOptions` and the `defineConfig` helper that encapsulates this typ - `Plugin`: A plugin object that provides a `name` and some hooks. All hooks are fully typed to aid in plugin development. - `PluginImpl`: A function that maps an options object to a plugin object. Most public Rollup plugins follow this pattern. -You can also directly write your config in TypeScript via the [`--configPlugin`](guide/en/#--configplugin-plugin) option. With TypeScript you can import the `RollupOptions` type directly: +You can also directly write your config in TypeScript via the [`--configPlugin`](guide/en/#--configplugin-plugin) option. With TypeScript, you can import the `RollupOptions` type directly: ```typescript import type { RollupOptions } from 'rollup'; @@ -478,7 +476,15 @@ Note for Typescript: make sure you have the Rollup config file in your `tsconfig "include": ["src/**/*", "rollup.config.ts"], ``` -This option supports the same syntax as the [`--plugin`](guide/en/#-p-plugin---plugin-plugin) option i.e., you can specify the option multiple times, you can omit the `@rollup/plugin-` prefix and just write `typescript` and you can specify plugin options via `={...}`. Using this option will make Rollup transpile your configuration file to CommonJS first before executing it. +This option supports the same syntax as the [`--plugin`](guide/en/#-p-plugin---plugin-plugin) option i.e., you can specify the option multiple times, you can omit the `@rollup/plugin-` prefix and just write `typescript` and you can specify plugin options via `={...}`. + +Using this option will make Rollup transpile your configuration file to an ES module first before executing it. To transpile to CommonJS instead, also pass the [`--bundleConfigAsCjs`](guide/en/#--bundleconfigascjs) option. + +#### `--bundleConfigAsCjs` + +This option will force your configuration to be transpiled to CommonJS. + +This allows you to use CommonJS idioms like `__dirname` or `require.resolve` in your configuration even if the configuration itself is written as an ES module. #### `-v`/`--version` diff --git a/package-lock.json b/package-lock.json index 2415d6497e3..6c510a86cc4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rollup", - "version": "3.0.0-2", + "version": "3.0.0-4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "rollup", - "version": "3.0.0-2", + "version": "3.0.0-4", "license": "MIT", "bin": { "rollup": "dist/bin/rollup" @@ -42,7 +42,6 @@ "eslint-plugin-prettier": "^4.2.1", "fixturify": "^2.1.1", "fs-extra": "^10.1.0", - "get-package-type": "^0.1.0", "github-api": "^3.4.0", "hash.js": "^1.1.7", "husky": "^8.0.1", @@ -76,7 +75,7 @@ "yargs-parser": "^21.0.1" }, "engines": { - "node": ">=14.0.0", + "node": ">=14.13.1", "npm": ">=8.0.0" }, "optionalDependencies": { diff --git a/package.json b/package.json index 70e6f3946c7..014b958e2e3 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,6 @@ "eslint-plugin-prettier": "^4.2.1", "fixturify": "^2.1.1", "fs-extra": "^10.1.0", - "get-package-type": "^0.1.0", "github-api": "^3.4.0", "hash.js": "^1.1.7", "husky": "^8.0.1", @@ -125,7 +124,7 @@ "dist/es/package.json" ], "engines": { - "node": ">=14.13.1", + "node": ">=14.18.0", "npm": ">=8.0.0" }, "exports": { diff --git a/src/rollup/types.d.ts b/src/rollup/types.d.ts index 7d9c4b669f9..b1a9fbc6d78 100644 --- a/src/rollup/types.d.ts +++ b/src/rollup/types.d.ts @@ -28,6 +28,7 @@ export interface RollupLog { pluginCode?: string; pos?: number; reexporter?: string; + stack?: string; url?: string; } diff --git a/src/utils/error.ts b/src/utils/error.ts index e20ecb63eac..b9d06647574 100644 --- a/src/utils/error.ts +++ b/src/utils/error.ts @@ -71,6 +71,7 @@ const ADDON_ERROR = 'ADDON_ERROR', ILLEGAL_REASSIGNMENT = 'ILLEGAL_REASSIGNMENT', INPUT_HOOK_IN_OUTPUT_PLUGIN = 'INPUT_HOOK_IN_OUTPUT_PLUGIN', INVALID_CHUNK = 'INVALID_CHUNK', + INVALID_CONFIG_MODULE_FORMAT = 'INVALID_CONFIG_MODULE_FORMAT', INVALID_EXPORT_OPTION = 'INVALID_EXPORT_OPTION', INVALID_EXTERNAL_ID = 'INVALID_EXTERNAL_ID', INVALID_OPTION = 'INVALID_OPTION', @@ -100,7 +101,6 @@ const ADDON_ERROR = 'ADDON_ERROR', SOURCEMAP_ERROR = 'SOURCEMAP_ERROR', SYNTHETIC_NAMED_EXPORTS_NEED_NAMESPACE_EXPORT = 'SYNTHETIC_NAMED_EXPORTS_NEED_NAMESPACE_EXPORT', THIS_IS_UNDEFINED = 'THIS_IS_UNDEFINED', - TRANSPILED_ESM_CONFIG = 'TRANSPILED_ESM_CONFIG', UNEXPECTED_NAMED_IMPORT = 'UNEXPECTED_NAMED_IMPORT', UNKNOWN_OPTION = 'UNKNOWN_OPTION', UNRESOLVED_ENTRY = 'UNRESOLVED_ENTRY', @@ -365,6 +365,36 @@ export function errCannotAssignModuleToChunk( }; } +export function errCannotBundleConfigAsEsm(originalError: Error): RollupLog { + return { + cause: originalError, + code: INVALID_CONFIG_MODULE_FORMAT, + message: `Rollup transpiled your configuration to an ES module even though it appears to contain CommonJS elements. To resolve this, you can pass the "--bundleConfigAsCjs" flag to Rollup or change your configuration to only contain valid ESM code.\n\nOriginal error: ${originalError.message}`, + stack: originalError.stack, + url: 'https://rollupjs.org/guide/en/#--bundleconfigascjs' + }; +} + +export function errCannotLoadConfigAsCjs(originalError: Error): RollupLog { + return { + cause: originalError, + code: INVALID_CONFIG_MODULE_FORMAT, + message: `Node tried to load your configuration file as CommonJS even though it is likely an ES module. To resolve this, change the extension of your configuration to ".mjs", set "type": "module" in your package.json file or pass the "--bundleConfigAsCjs" flag.\n\nOriginal error: ${originalError.message}`, + stack: originalError.stack, + url: 'https://rollupjs.org/guide/en/#--bundleconfigascjs' + }; +} + +export function errCannotLoadConfigAsEsm(originalError: Error): RollupLog { + return { + cause: originalError, + code: INVALID_CONFIG_MODULE_FORMAT, + message: `Node tried to load your configuration as an ES module even though it is likely CommonJS. To resolve this, change the extension of your configuration to ".cjs" or pass the "--bundleConfigAsCjs" flag.\n\nOriginal error: ${originalError.message}`, + stack: originalError.stack, + url: 'https://rollupjs.org/guide/en/#--bundleconfigascjs' + }; +} + export function errInvalidExportOptionValue(optionValue: string): RollupLog { return { code: INVALID_EXPORT_OPTION, @@ -756,15 +786,6 @@ export function errThisIsUndefined(): RollupLog { }; } -export function errTranspiledEsmConfig(fileName: string): RollupLog { - return { - code: TRANSPILED_ESM_CONFIG, - message: `While loading the Rollup configuration from "${relativeId( - fileName - )}", Node tried to require an ES module from a CommonJS file, which is not supported. A common cause is if there is a package.json file with "type": "module" in the same folder. You can try to fix this by changing the extension of your configuration file to ".cjs" or ".mjs" depending on the content, which will prevent Rollup from trying to preprocess the file but rather hand it to Node directly.` - }; -} - export function errUnexpectedNamedImport( id: string, imported: string, diff --git a/src/utils/options/mergeOptions.ts b/src/utils/options/mergeOptions.ts index df7536d3cbf..b9903f7a13d 100644 --- a/src/utils/options/mergeOptions.ts +++ b/src/utils/options/mergeOptions.ts @@ -57,6 +57,7 @@ export function mergeOptions( Object.keys(inputOptions).concat( Object.keys(outputOptions[0]).filter(option => option !== 'sourcemapPathTransform'), Object.keys(commandAliases), + 'bundleConfigAsCjs', 'config', 'environment', 'plugin', diff --git a/test/cli/node_modules/esm-dep/index.js b/test/cli/node_modules/esm-dep/index.js new file mode 100644 index 00000000000..61b7e747ee3 --- /dev/null +++ b/test/cli/node_modules/esm-dep/index.js @@ -0,0 +1 @@ +export default 'esm-default'; diff --git a/test/cli/node_modules/esm-dep/package.json b/test/cli/node_modules/esm-dep/package.json new file mode 100644 index 00000000000..feb093e15ad --- /dev/null +++ b/test/cli/node_modules/esm-dep/package.json @@ -0,0 +1,4 @@ +{ + "main": "index.js", + "type": "module" +} diff --git a/test/cli/samples/plugin/advanced-esm/node_modules/rollup-plugin-esm-test/index.mjs b/test/cli/node_modules/rollup-plugin-esm-test/index.mjs similarity index 100% rename from test/cli/samples/plugin/advanced-esm/node_modules/rollup-plugin-esm-test/index.mjs rename to test/cli/node_modules/rollup-plugin-esm-test/index.mjs diff --git a/test/cli/samples/plugin/advanced-esm/node_modules/rollup-plugin-esm-test/package.json b/test/cli/node_modules/rollup-plugin-esm-test/package.json similarity index 50% rename from test/cli/samples/plugin/advanced-esm/node_modules/rollup-plugin-esm-test/package.json rename to test/cli/node_modules/rollup-plugin-esm-test/package.json index 5db8a5c8cd5..7084d6ebcc0 100644 --- a/test/cli/samples/plugin/advanced-esm/node_modules/rollup-plugin-esm-test/package.json +++ b/test/cli/node_modules/rollup-plugin-esm-test/package.json @@ -1,4 +1,4 @@ { "type": "module", - "main": "./index.mjs" + "main": "index.mjs" } diff --git a/test/cli/node_modules_rename_me/esm-dep/index.js b/test/cli/node_modules_rename_me/esm-dep/index.js new file mode 100644 index 00000000000..61b7e747ee3 --- /dev/null +++ b/test/cli/node_modules_rename_me/esm-dep/index.js @@ -0,0 +1 @@ +export default 'esm-default'; diff --git a/test/cli/node_modules_rename_me/esm-dep/package.json b/test/cli/node_modules_rename_me/esm-dep/package.json new file mode 100644 index 00000000000..feb093e15ad --- /dev/null +++ b/test/cli/node_modules_rename_me/esm-dep/package.json @@ -0,0 +1,4 @@ +{ + "main": "index.js", + "type": "module" +} diff --git a/test/cli/node_modules_rename_me/rollup-plugin-esm-test/index.mjs b/test/cli/node_modules_rename_me/rollup-plugin-esm-test/index.mjs new file mode 100644 index 00000000000..14daca5000a --- /dev/null +++ b/test/cli/node_modules_rename_me/rollup-plugin-esm-test/index.mjs @@ -0,0 +1,9 @@ +export function esmTest() { + return { + transform(code, id) { + if (id.includes("\0")) return null; + const name = JSON.stringify(id.replace(/^.*\/advanced-esm\//, "esm-test: ")); + return `console.log(${name});\n${code}`; + } + }; +} diff --git a/test/cli/node_modules_rename_me/rollup-plugin-esm-test/package.json b/test/cli/node_modules_rename_me/rollup-plugin-esm-test/package.json new file mode 100644 index 00000000000..7084d6ebcc0 --- /dev/null +++ b/test/cli/node_modules_rename_me/rollup-plugin-esm-test/package.json @@ -0,0 +1,4 @@ +{ + "type": "module", + "main": "index.mjs" +} diff --git a/test/cli/samples/config-async-function/rollup.config.js b/test/cli/samples/config-async-function/rollup.config.mjs similarity index 100% rename from test/cli/samples/config-async-function/rollup.config.js rename to test/cli/samples/config-async-function/rollup.config.mjs diff --git a/test/cli/samples/config-cwd-case-insensitive-es6/rollup.config.js b/test/cli/samples/config-cwd-case-insensitive-es6/rollup.config.mjs similarity index 100% rename from test/cli/samples/config-cwd-case-insensitive-es6/rollup.config.js rename to test/cli/samples/config-cwd-case-insensitive-es6/rollup.config.mjs diff --git a/test/cli/samples/config-defineConfig-mjs/_config.js b/test/cli/samples/config-defineConfig-mjs/_config.js index bd51b3ca622..5a33e72eea3 100644 --- a/test/cli/samples/config-defineConfig-mjs/_config.js +++ b/test/cli/samples/config-defineConfig-mjs/_config.js @@ -1,6 +1,5 @@ module.exports = { description: 'uses mjs config file which return config wrapped by defineConfig', command: 'rollup --config rollup.config.mjs', - minNodeVersion: 13, execute: true }; diff --git a/test/cli/samples/config-es6/_config.js b/test/cli/samples/config-es6/_config.js index 0db10ef3b26..1ed454a1ad9 100644 --- a/test/cli/samples/config-es6/_config.js +++ b/test/cli/samples/config-es6/_config.js @@ -1,5 +1,5 @@ module.exports = { description: 'uses ES6 module config file', - command: 'rollup --config rollup.config.js', + command: 'rollup --config rollup.config.js --bundleConfigAsCjs', execute: true }; diff --git a/test/cli/samples/config-external-function/rollup.config.js b/test/cli/samples/config-external-function/rollup.config.mjs similarity index 100% rename from test/cli/samples/config-external-function/rollup.config.js rename to test/cli/samples/config-external-function/rollup.config.mjs diff --git a/test/cli/samples/config-external/rollup.config.js b/test/cli/samples/config-external/rollup.config.mjs similarity index 100% rename from test/cli/samples/config-external/rollup.config.js rename to test/cli/samples/config-external/rollup.config.mjs diff --git a/test/cli/samples/config-function-modify-command/_config.js b/test/cli/samples/config-function-modify-command/_config.js index c14498e84da..e80816ba3cb 100644 --- a/test/cli/samples/config-function-modify-command/_config.js +++ b/test/cli/samples/config-function-modify-command/_config.js @@ -1,5 +1,5 @@ module.exports = { description: 'allows cleaning up and modifying the command args in the config file', - command: 'rollup --config rollup.config.js --some-option="foo" --another-option=42', + command: 'rollup --config rollup.config.mjs --some-option="foo" --another-option=42', execute: true }; diff --git a/test/cli/samples/config-function-modify-command/main.js b/test/cli/samples/config-function-modify-command/main.js index aadfbd9aaf0..bbbb2db8f28 100644 --- a/test/cli/samples/config-function-modify-command/main.js +++ b/test/cli/samples/config-function-modify-command/main.js @@ -1,7 +1,7 @@ assert.deepEqual(COMMAND_OPTIONS, { _: [], - config: 'rollup.config.js', - c: 'rollup.config.js', + config: 'rollup.config.mjs', + c: 'rollup.config.mjs', 'some-option': 'foo', 'another-option': 42 }); diff --git a/test/cli/samples/config-function-modify-command/rollup.config.js b/test/cli/samples/config-function-modify-command/rollup.config.mjs similarity index 100% rename from test/cli/samples/config-function-modify-command/rollup.config.js rename to test/cli/samples/config-function-modify-command/rollup.config.mjs diff --git a/test/cli/samples/config-function/_config.js b/test/cli/samples/config-function/_config.js index 162c7bd13b3..ad5009c9802 100644 --- a/test/cli/samples/config-function/_config.js +++ b/test/cli/samples/config-function/_config.js @@ -1,6 +1,6 @@ module.exports = { description: 'if the config file returns a function then this will be called with the command args', - command: 'rollup --config rollup.config.js --silent', + command: 'rollup --config rollup.config.mjs --silent', execute: true }; diff --git a/test/cli/samples/config-function/main.js b/test/cli/samples/config-function/main.js index ec5d5d2e316..9117e22968b 100644 --- a/test/cli/samples/config-function/main.js +++ b/test/cli/samples/config-function/main.js @@ -1,6 +1,6 @@ assert.deepEqual(COMMAND_OPTIONS, { _: [], - config: 'rollup.config.js', - c: 'rollup.config.js', + config: 'rollup.config.mjs', + c: 'rollup.config.mjs', silent: true }); diff --git a/test/cli/samples/config-function/rollup.config.js b/test/cli/samples/config-function/rollup.config.mjs similarity index 100% rename from test/cli/samples/config-function/rollup.config.js rename to test/cli/samples/config-function/rollup.config.mjs diff --git a/test/cli/samples/config-import-meta/_config.js b/test/cli/samples/config-import-meta/_config.js index 241b4c526db..50b766ab53e 100644 --- a/test/cli/samples/config-import-meta/_config.js +++ b/test/cli/samples/config-import-meta/_config.js @@ -1,4 +1,4 @@ module.exports = { description: 'uses correct import.meta.url in config files', - command: 'rollup -c' + command: 'rollup -c --bundleConfigAsCjs' }; diff --git a/test/cli/samples/config-json/_config.js b/test/cli/samples/config-json/_config.js index 64763fb55cf..0c6fb91feae 100644 --- a/test/cli/samples/config-json/_config.js +++ b/test/cli/samples/config-json/_config.js @@ -1,5 +1,5 @@ module.exports = { description: 'allows config file to import json', - command: 'rollup --config rollup.config.js', + command: 'rollup --config rollup.config.js --bundleConfigAsCjs', execute: true }; diff --git a/test/cli/samples/config-mjs-plugins/_config.js b/test/cli/samples/config-mjs-plugins/_config.js index e12031215b1..a6f62f01ce3 100644 --- a/test/cli/samples/config-mjs-plugins/_config.js +++ b/test/cli/samples/config-mjs-plugins/_config.js @@ -1,5 +1,4 @@ module.exports = { description: 'supports native esm as well as CJS plugins when using .mjs in Node 13+', - minNodeVersion: 13, command: 'rollup -c' }; diff --git a/test/cli/samples/config-multiple-getfilename/rollup.config.js b/test/cli/samples/config-multiple-getfilename/rollup.config.mjs similarity index 100% rename from test/cli/samples/config-multiple-getfilename/rollup.config.js rename to test/cli/samples/config-multiple-getfilename/rollup.config.mjs diff --git a/test/cli/samples/config-multiple-source-maps/_config.js b/test/cli/samples/config-multiple-source-maps/_config.js index a91d466ccdc..1de74ea00b9 100644 --- a/test/cli/samples/config-multiple-source-maps/_config.js +++ b/test/cli/samples/config-multiple-source-maps/_config.js @@ -1,4 +1,4 @@ module.exports = { description: 'correctly generates sourcemaps for multiple outputs', - command: 'rollup -c' + command: 'rollup -c --bundleConfigAsCjs' }; diff --git a/test/cli/samples/config-no-module/_config.js b/test/cli/samples/config-no-module/_config.js deleted file mode 100644 index 21411297daa..00000000000 --- a/test/cli/samples/config-no-module/_config.js +++ /dev/null @@ -1,16 +0,0 @@ -const { assertIncludes } = require('../../../utils.js'); - -module.exports = { - description: 'provides a helpful error message if a transpiled config is interpreted as "module"', - minNodeVersion: 13, - command: 'rollup -c', - error: () => true, - stderr: stderr => - assertIncludes( - stderr, - '[!] RollupError: While loading the Rollup configuration from "rollup.config.js", Node tried to require an ES module from a CommonJS ' + - 'file, which is not supported. A common cause is if there is a package.json file with "type": "module" in the same folder. You can ' + - 'try to fix this by changing the extension of your configuration file to ".cjs" or ".mjs" depending on the content, which will ' + - 'prevent Rollup from trying to preprocess the file but rather hand it to Node directly.' - ) -}; diff --git a/test/cli/samples/config-no-module/rollup.config.js b/test/cli/samples/config-no-module/rollup.config.js deleted file mode 100644 index c9356224f7f..00000000000 --- a/test/cli/samples/config-no-module/rollup.config.js +++ /dev/null @@ -1,7 +0,0 @@ -import { shebang } from 'rollup-plugin-thatworks'; - -export default { - input: './sub/main.js', - output: { format: 'cjs' }, - plugins: [shebang()] -}; diff --git a/test/cli/samples/config-no-module/sub/main.js b/test/cli/samples/config-no-module/sub/main.js deleted file mode 100644 index 7a4e8a723a4..00000000000 --- a/test/cli/samples/config-no-module/sub/main.js +++ /dev/null @@ -1 +0,0 @@ -export default 42; diff --git a/test/cli/samples/config-no-output/rollup.config.js b/test/cli/samples/config-no-output/rollup.config.mjs similarity index 100% rename from test/cli/samples/config-no-output/rollup.config.js rename to test/cli/samples/config-no-output/rollup.config.mjs diff --git a/test/cli/samples/config-override/rollup.config.js b/test/cli/samples/config-override/rollup.config.mjs similarity index 100% rename from test/cli/samples/config-override/rollup.config.js rename to test/cli/samples/config-override/rollup.config.mjs diff --git a/test/cli/samples/config-plugin-entry/_config.js b/test/cli/samples/config-plugin-entry/_config.js index 87345ed15e9..3f8b027cede 100644 --- a/test/cli/samples/config-plugin-entry/_config.js +++ b/test/cli/samples/config-plugin-entry/_config.js @@ -1,4 +1,4 @@ module.exports = { description: 'allows plugins to set options.entry', - command: 'rollup -c' + command: 'rollup -c --bundleConfigAsCjs' }; diff --git a/test/cli/samples/config-promise-mjs/_config.js b/test/cli/samples/config-promise-mjs/_config.js index 7cfdef3e2d7..d605500053e 100644 --- a/test/cli/samples/config-promise-mjs/_config.js +++ b/test/cli/samples/config-promise-mjs/_config.js @@ -1,6 +1,5 @@ module.exports = { description: 'uses mjs config file which returns a Promise', - minNodeVersion: 13, command: 'rollup --config rollup.config.mjs', execute: true }; diff --git a/test/cli/samples/config-promise/_config.js b/test/cli/samples/config-promise/_config.js index 395579ed8ee..848c006f2f7 100644 --- a/test/cli/samples/config-promise/_config.js +++ b/test/cli/samples/config-promise/_config.js @@ -1,5 +1,5 @@ module.exports = { description: 'uses config file which returns a Promise', - command: 'rollup --config rollup.config.js', + command: 'rollup --config rollup.config.mjs', execute: true }; diff --git a/test/cli/samples/config-promise/rollup.config.js b/test/cli/samples/config-promise/rollup.config.mjs similarity index 100% rename from test/cli/samples/config-promise/rollup.config.js rename to test/cli/samples/config-promise/rollup.config.mjs diff --git a/test/cli/samples/config-true/_config.js b/test/cli/samples/config-true/_config.js index 95252f58d24..ca48ad0c303 100644 --- a/test/cli/samples/config-true/_config.js +++ b/test/cli/samples/config-true/_config.js @@ -1,5 +1,5 @@ module.exports = { description: 'defaults to rollup.config.js', - command: 'rollup -c', + command: 'rollup -c --bundleConfigAsCjs', execute: true }; diff --git a/test/cli/samples/config-type-module/_config.js b/test/cli/samples/config-type-module/_config.js index 5d1b2a54a2f..362bbf54e45 100644 --- a/test/cli/samples/config-type-module/_config.js +++ b/test/cli/samples/config-type-module/_config.js @@ -7,7 +7,7 @@ module.exports = { stderr: stderr => { assertIncludes( stderr, - '[!] ReferenceError: module is not defined in ES module scope\n' + + 'ReferenceError: module is not defined in ES module scope\n' + "This file is being treated as an ES module because it has a '.js' file extension and" ); assertIncludes( diff --git a/test/cli/samples/config-warnings/_config.js b/test/cli/samples/config-warnings/_config.js index e7177b4ca90..f807bb3c129 100644 --- a/test/cli/samples/config-warnings/_config.js +++ b/test/cli/samples/config-warnings/_config.js @@ -2,7 +2,7 @@ const { assertIncludes } = require('../../../utils.js'); module.exports = { description: 'displays warnings when a config is loaded', - command: 'rollup -c', + command: 'rollup -c --bundleConfigAsCjs', stderr: stderr => assertIncludes( stderr, diff --git a/test/cli/samples/custom-frame/_config.js b/test/cli/samples/custom-frame/_config.js index b1e9539ef22..67fbd348427 100644 --- a/test/cli/samples/custom-frame/_config.js +++ b/test/cli/samples/custom-frame/_config.js @@ -11,6 +11,6 @@ module.exports = { 'main.js\ncustom code frame\nError: My error.\n' + ' at Object.' ); - assertIncludes(stderr, 'rollup.config.js:11:17'); + assertIncludes(stderr, 'rollup.config.js:9:17'); } }; diff --git a/test/cli/samples/emit-file-multiple-dirs/rollup.config.js b/test/cli/samples/emit-file-multiple-dirs/rollup.config.mjs similarity index 100% rename from test/cli/samples/emit-file-multiple-dirs/rollup.config.js rename to test/cli/samples/emit-file-multiple-dirs/rollup.config.mjs diff --git a/test/cli/samples/format-aliases/rollup.config.js b/test/cli/samples/format-aliases/rollup.config.mjs similarity index 100% rename from test/cli/samples/format-aliases/rollup.config.js rename to test/cli/samples/format-aliases/rollup.config.mjs diff --git a/test/cli/samples/generated-code-preset-override/rollup.config.js b/test/cli/samples/generated-code-preset-override/rollup.config.mjs similarity index 100% rename from test/cli/samples/generated-code-preset-override/rollup.config.js rename to test/cli/samples/generated-code-preset-override/rollup.config.mjs diff --git a/test/cli/samples/import-esm-package/_config.js b/test/cli/samples/import-esm-package/_config.js new file mode 100644 index 00000000000..23d127d1d67 --- /dev/null +++ b/test/cli/samples/import-esm-package/_config.js @@ -0,0 +1,5 @@ +module.exports = { + description: 'allows to import ESM dependencies from transpiled config files', + skipIfWindows: true, + command: "rollup --config --configPlugin '{transform:c => c}'" +}; diff --git a/test/cli/samples/import-esm-package/_expected/main.js b/test/cli/samples/import-esm-package/_expected/main.js new file mode 100644 index 00000000000..9a8209b3ccd --- /dev/null +++ b/test/cli/samples/import-esm-package/_expected/main.js @@ -0,0 +1,2 @@ +/* esm-default */ +assert.ok(true); diff --git a/test/cli/samples/import-esm-package/main.js b/test/cli/samples/import-esm-package/main.js new file mode 100644 index 00000000000..cc1d88a24fa --- /dev/null +++ b/test/cli/samples/import-esm-package/main.js @@ -0,0 +1 @@ +assert.ok(true); diff --git a/test/cli/samples/import-esm-package/rollup.config.js b/test/cli/samples/import-esm-package/rollup.config.js new file mode 100644 index 00000000000..0a38f897471 --- /dev/null +++ b/test/cli/samples/import-esm-package/rollup.config.js @@ -0,0 +1,10 @@ +import esmDep from 'esm-dep'; + +export default { + input: 'main.js', + output: { + banner: `/* ${esmDep} */`, + format: 'es', + dir: '_actual' + } +}; diff --git a/test/cli/samples/multiple-configs/rollup.config.js b/test/cli/samples/multiple-configs/rollup.config.mjs similarity index 100% rename from test/cli/samples/multiple-configs/rollup.config.js rename to test/cli/samples/multiple-configs/rollup.config.mjs diff --git a/test/cli/samples/multiple-targets-different-plugins/rollup.config.js b/test/cli/samples/multiple-targets-different-plugins/rollup.config.mjs similarity index 100% rename from test/cli/samples/multiple-targets-different-plugins/rollup.config.js rename to test/cli/samples/multiple-targets-different-plugins/rollup.config.mjs diff --git a/test/cli/samples/multiple-targets-shared-config/rollup.config.js b/test/cli/samples/multiple-targets-shared-config/rollup.config.mjs similarity index 100% rename from test/cli/samples/multiple-targets-shared-config/rollup.config.js rename to test/cli/samples/multiple-targets-shared-config/rollup.config.mjs diff --git a/test/cli/samples/multiple-targets/rollup.config.js b/test/cli/samples/multiple-targets/rollup.config.mjs similarity index 100% rename from test/cli/samples/multiple-targets/rollup.config.js rename to test/cli/samples/multiple-targets/rollup.config.mjs diff --git a/test/cli/samples/plugin/absolute-esm/_config.js b/test/cli/samples/plugin/absolute-esm/_config.js index d74fb84c0cf..84c53557120 100644 --- a/test/cli/samples/plugin/absolute-esm/_config.js +++ b/test/cli/samples/plugin/absolute-esm/_config.js @@ -2,6 +2,5 @@ const { sep } = require('path'); module.exports = { description: 'ESM CLI --plugin /absolute/path', - minNodeVersion: 12, command: `rollup main.js -p "${__dirname}${sep}my-esm-plugin.mjs={comment: 'Absolute ESM'}"` }; diff --git a/test/cli/samples/plugin/absolute/_config.js b/test/cli/samples/plugin/absolute/_config.js index 3ed9c5e813d..02a3a86a2c6 100644 --- a/test/cli/samples/plugin/absolute/_config.js +++ b/test/cli/samples/plugin/absolute/_config.js @@ -2,6 +2,5 @@ const { sep } = require('path'); module.exports = { description: 'CLI --plugin /absolute/path', - minNodeVersion: 12, command: `rollup main.js -p "${__dirname}${sep}my-plugin.js={VALUE: 'absolute', ZZZ: 1}"` }; diff --git a/test/cli/samples/plugin/advanced-esm/_config.js b/test/cli/samples/plugin/advanced-esm/_config.js index 9dfaf7526cd..ee7545ea184 100644 --- a/test/cli/samples/plugin/advanced-esm/_config.js +++ b/test/cli/samples/plugin/advanced-esm/_config.js @@ -1,10 +1,9 @@ module.exports = { description: 'load an ESM-only rollup plugin from node_modules as well as CJS plugins', - minNodeVersion: 12, skipIfWindows: true, // The NodeJS resolution rules for ESM modules are more restrictive than CJS. // Must copy the ESM plugin into the main node_modules in order to use and test it. - command: `rm -rf ../../../../../node_modules/rollup-plugin-esm-test && cp -rp node_modules/rollup-plugin-esm-test ../../../../../node_modules/ && rollup -c -p node-resolve,commonjs,esm-test -p "terser={mangle: false, output: {beautify: true, indent_level: 2}}"` + command: `rm -rf ../../../../../node_modules/rollup-plugin-esm-test && cp -rp ../../../node_modules_rename_me/rollup-plugin-esm-test ../../../../../node_modules/ && rollup -c -p node-resolve,commonjs,esm-test -p "terser={mangle: false, output: {beautify: true, indent_level: 2}}"` }; diff --git a/test/cli/samples/plugin/advanced-esm/rollup.config.js b/test/cli/samples/plugin/advanced-esm/rollup.config.mjs similarity index 79% rename from test/cli/samples/plugin/advanced-esm/rollup.config.js rename to test/cli/samples/plugin/advanced-esm/rollup.config.mjs index fa98304fac1..7e9855a13ff 100644 --- a/test/cli/samples/plugin/advanced-esm/rollup.config.js +++ b/test/cli/samples/plugin/advanced-esm/rollup.config.mjs @@ -1,4 +1,4 @@ -const buble = require('@rollup/plugin-buble'); +import buble from '@rollup/plugin-buble'; export default { input: 'main.js', diff --git a/test/cli/samples/plugin/advanced/_config.js b/test/cli/samples/plugin/advanced/_config.js index 8028fd603e7..fa474579270 100644 --- a/test/cli/samples/plugin/advanced/_config.js +++ b/test/cli/samples/plugin/advanced/_config.js @@ -1,5 +1,4 @@ module.exports = { description: 'advanced CLI --plugin functionality with rollup config', - skipIfWindows: true, command: `rollup -c -p node-resolve,commonjs -p "terser={output: {beautify: true, indent_level: 2}}"` }; diff --git a/test/cli/samples/plugin/advanced/rollup.config.js b/test/cli/samples/plugin/advanced/rollup.config.mjs similarity index 79% rename from test/cli/samples/plugin/advanced/rollup.config.js rename to test/cli/samples/plugin/advanced/rollup.config.mjs index fa98304fac1..7e9855a13ff 100644 --- a/test/cli/samples/plugin/advanced/rollup.config.js +++ b/test/cli/samples/plugin/advanced/rollup.config.mjs @@ -1,4 +1,4 @@ -const buble = require('@rollup/plugin-buble'); +import buble from '@rollup/plugin-buble'; export default { input: 'main.js', diff --git a/test/cli/samples/plugin/named-export/_config.js b/test/cli/samples/plugin/named-export/_config.js index 92a84aeb1db..d7dd5aaea1b 100644 --- a/test/cli/samples/plugin/named-export/_config.js +++ b/test/cli/samples/plugin/named-export/_config.js @@ -1,5 +1,4 @@ module.exports = { description: 'supports stripping "rollup-config" prefix to find named plugin export', - skipIfWindows: true, command: `rollup -c -p rollup-plugin-terser` }; diff --git a/test/cli/samples/plugin/named-export/rollup.config.js b/test/cli/samples/plugin/named-export/rollup.config.mjs similarity index 79% rename from test/cli/samples/plugin/named-export/rollup.config.js rename to test/cli/samples/plugin/named-export/rollup.config.mjs index fa98304fac1..a3f91c5d9c8 100644 --- a/test/cli/samples/plugin/named-export/rollup.config.js +++ b/test/cli/samples/plugin/named-export/rollup.config.mjs @@ -1,4 +1,4 @@ -const buble = require('@rollup/plugin-buble'); +import buble from "@rollup/plugin-buble"; export default { input: 'main.js', diff --git a/test/cli/samples/plugin/relative-esm/_config.js b/test/cli/samples/plugin/relative-esm/_config.js index 2c0e40c1215..3792a107f3e 100644 --- a/test/cli/samples/plugin/relative-esm/_config.js +++ b/test/cli/samples/plugin/relative-esm/_config.js @@ -1,6 +1,5 @@ module.exports = { description: 'ESM CLI --plugin ../relative/path', - minNodeVersion: 12, skipIfWindows: true, command: `echo 'console.log(1 ? 2 : 3);' | rollup -p "../absolute-esm/my-esm-plugin.mjs={comment: 'Relative ESM'}"` }; diff --git a/test/cli/samples/silent-onwarn/rollup.config.js b/test/cli/samples/silent-onwarn/rollup.config.mjs similarity index 100% rename from test/cli/samples/silent-onwarn/rollup.config.js rename to test/cli/samples/silent-onwarn/rollup.config.mjs diff --git a/test/cli/samples/stdin/config-file/rollup.config.js b/test/cli/samples/stdin/config-file/rollup.config.mjs similarity index 100% rename from test/cli/samples/stdin/config-file/rollup.config.js rename to test/cli/samples/stdin/config-file/rollup.config.mjs diff --git a/test/cli/samples/stdin/no-stdin-config-file/rollup.config.js b/test/cli/samples/stdin/no-stdin-config-file/rollup.config.mjs similarity index 100% rename from test/cli/samples/stdin/no-stdin-config-file/rollup.config.js rename to test/cli/samples/stdin/no-stdin-config-file/rollup.config.mjs diff --git a/test/cli/samples/symlinked-config/_config.js b/test/cli/samples/symlinked-config/_config.js index 3d221fb433c..ca76fa8746f 100644 --- a/test/cli/samples/symlinked-config/_config.js +++ b/test/cli/samples/symlinked-config/_config.js @@ -1,5 +1,5 @@ module.exports = { description: 'loads a symlinked config file', - command: 'rollup -c', + command: 'rollup -c --bundleConfigAsCjs', execute: true }; diff --git a/test/cli/samples/symlinked-named-config/_config.js b/test/cli/samples/symlinked-named-config/_config.js index 59f830679b8..31b3debd42f 100644 --- a/test/cli/samples/symlinked-named-config/_config.js +++ b/test/cli/samples/symlinked-named-config/_config.js @@ -1,5 +1,5 @@ module.exports = { description: 'loads a symlinked config file with the given name', - command: 'rollup --config my.rollup.config.js', + command: 'rollup --config my.rollup.config.js --bundleConfigAsCjs', execute: true }; diff --git a/test/cli/samples/treeshake-preset-override/rollup.config.js b/test/cli/samples/treeshake-preset-override/rollup.config.mjs similarity index 100% rename from test/cli/samples/treeshake-preset-override/rollup.config.js rename to test/cli/samples/treeshake-preset-override/rollup.config.mjs diff --git a/test/cli/samples/unfulfilled-hook-actions-error/_config.js b/test/cli/samples/unfulfilled-hook-actions-error/_config.js index 39bea541f9f..097e6a68d40 100644 --- a/test/cli/samples/unfulfilled-hook-actions-error/_config.js +++ b/test/cli/samples/unfulfilled-hook-actions-error/_config.js @@ -3,7 +3,6 @@ const { assertIncludes, assertDoesNotInclude } = require('../../../utils.js'); module.exports = { description: 'does not show unfulfilled hook actions if there are errors', - minNodeVersion: 13, command: 'node build.mjs', after(err) { // exit code check has to be here as error(err) is only called upon failure diff --git a/test/cli/samples/watch/bundle-error/_config.js b/test/cli/samples/watch/bundle-error/_config.js index 25046a7f5f1..0d29e59bc32 100644 --- a/test/cli/samples/watch/bundle-error/_config.js +++ b/test/cli/samples/watch/bundle-error/_config.js @@ -6,7 +6,7 @@ let mainFile; module.exports = { description: 'recovers from errors during bundling', - command: 'rollup -cw', + command: 'rollup -cw --bundleConfigAsCjs', before() { mainFile = path.resolve(__dirname, 'main.js'); writeFileSync(mainFile, '<=>'); diff --git a/test/cli/samples/watch/clearScreen/rollup.config.js b/test/cli/samples/watch/clearScreen/rollup.config.mjs similarity index 100% rename from test/cli/samples/watch/clearScreen/rollup.config.js rename to test/cli/samples/watch/clearScreen/rollup.config.mjs diff --git a/test/cli/samples/watch/close-error/rollup.config.js b/test/cli/samples/watch/close-error/rollup.config.mjs similarity index 100% rename from test/cli/samples/watch/close-error/rollup.config.js rename to test/cli/samples/watch/close-error/rollup.config.mjs diff --git a/test/cli/samples/watch/close-on-generate-error/rollup.config.js b/test/cli/samples/watch/close-on-generate-error/rollup.config.mjs similarity index 100% rename from test/cli/samples/watch/close-on-generate-error/rollup.config.js rename to test/cli/samples/watch/close-on-generate-error/rollup.config.mjs diff --git a/test/cli/samples/watch/no-clearScreen/rollup.config.js b/test/cli/samples/watch/no-clearScreen/rollup.config.mjs similarity index 100% rename from test/cli/samples/watch/no-clearScreen/rollup.config.js rename to test/cli/samples/watch/no-clearScreen/rollup.config.mjs diff --git a/test/cli/samples/watch/no-watch-by-default/rollup.config.js b/test/cli/samples/watch/no-watch-by-default/rollup.config.mjs similarity index 100% rename from test/cli/samples/watch/no-watch-by-default/rollup.config.js rename to test/cli/samples/watch/no-watch-by-default/rollup.config.mjs diff --git a/test/cli/samples/watch/no-watched-config/rollup.config.js b/test/cli/samples/watch/no-watched-config/rollup.config.mjs similarity index 100% rename from test/cli/samples/watch/no-watched-config/rollup.config.js rename to test/cli/samples/watch/no-watched-config/rollup.config.mjs diff --git a/test/cli/samples/watch/watch-config-early-update/_config.js b/test/cli/samples/watch/watch-config-early-update/_config.js index 25e41959eb3..2c6dbf049be 100644 --- a/test/cli/samples/watch/watch-config-early-update/_config.js +++ b/test/cli/samples/watch/watch-config-early-update/_config.js @@ -1,8 +1,8 @@ const { mkdirSync, unlinkSync } = require('fs'); const path = require('path'); -const { writeAndSync, writeAndRetry } = require('../../../../utils'); +const { wait, writeAndSync, writeAndRetry } = require('../../../../utils'); -const configFile = path.join(__dirname, 'rollup.config.js'); +const configFile = path.join(__dirname, 'rollup.config.mjs'); let stopUpdate; module.exports = { @@ -49,9 +49,10 @@ module.exports = { }, abortOnStderr(data) { if (data === 'initial\n') { - stopUpdate = writeAndRetry( - configFile, - ` + wait(200).then(() => { + stopUpdate = writeAndRetry( + configFile, + ` console.error('updated'); export default { input: 'main.js', @@ -60,7 +61,8 @@ module.exports = { format: "es" } };` - ); + ); + }); return false; } if (data.includes(`created _actual/output2.js`)) { diff --git a/test/cli/samples/watch/watch-config-error/_config.js b/test/cli/samples/watch/watch-config-error/_config.js index 3ebb004420d..3792bebe27c 100644 --- a/test/cli/samples/watch/watch-config-error/_config.js +++ b/test/cli/samples/watch/watch-config-error/_config.js @@ -8,7 +8,7 @@ module.exports = { description: 'keeps watching the config file in case the config is changed to an invalid state', command: 'rollup -cw', before() { - configFile = path.resolve(__dirname, 'rollup.config.js'); + configFile = path.resolve(__dirname, 'rollup.config.mjs'); writeFileSync( configFile, ` diff --git a/test/cli/samples/watch/watch-config-initial-error/_config.js b/test/cli/samples/watch/watch-config-initial-error/_config.js index 4b6cd1c093c..c8ade42f2cc 100644 --- a/test/cli/samples/watch/watch-config-initial-error/_config.js +++ b/test/cli/samples/watch/watch-config-initial-error/_config.js @@ -8,7 +8,7 @@ module.exports = { description: 'keeps watching the config file in case the initial file contains an error', command: 'rollup -cw', before() { - configFile = path.join(__dirname, 'rollup.config.js'); + configFile = path.join(__dirname, 'rollup.config.mjs'); writeFileSync(configFile, 'throw new Error("Config contains initial errors");'); }, after() { diff --git a/test/cli/samples/watch/watch-config-no-update/_config.js b/test/cli/samples/watch/watch-config-no-update/_config.js index d952ed72e21..e5fa7ff72a6 100644 --- a/test/cli/samples/watch/watch-config-no-update/_config.js +++ b/test/cli/samples/watch/watch-config-no-update/_config.js @@ -16,7 +16,7 @@ module.exports = { description: 'does not rebuild if the config file is updated without change', command: 'rollup -cw', before() { - configFile = path.resolve(__dirname, 'rollup.config.js'); + configFile = path.resolve(__dirname, 'rollup.config.mjs'); writeFileSync(configFile, configContent); }, after() { diff --git a/test/cli/samples/watch/watch-event-hooks-error/rollup.config.js b/test/cli/samples/watch/watch-event-hooks-error/rollup.config.mjs similarity index 100% rename from test/cli/samples/watch/watch-event-hooks-error/rollup.config.js rename to test/cli/samples/watch/watch-event-hooks-error/rollup.config.mjs diff --git a/test/cli/samples/watch/watch-event-hooks/rollup.config.js b/test/cli/samples/watch/watch-event-hooks/rollup.config.mjs similarity index 100% rename from test/cli/samples/watch/watch-event-hooks/rollup.config.js rename to test/cli/samples/watch/watch-event-hooks/rollup.config.mjs diff --git a/test/function/samples/class-method-returns/_config.js b/test/function/samples/class-method-returns/_config.js index 8f20eb5fa6b..b2fc183b770 100644 --- a/test/function/samples/class-method-returns/_config.js +++ b/test/function/samples/class-method-returns/_config.js @@ -1,4 +1,3 @@ module.exports = { - description: 'deoptimizes return values of class methods', - minNodeVersion: 12 + description: 'deoptimizes return values of class methods' }; diff --git a/test/function/samples/class-prop-returns/_config.js b/test/function/samples/class-prop-returns/_config.js index bd4c18af8b1..94abb7c42c0 100644 --- a/test/function/samples/class-prop-returns/_config.js +++ b/test/function/samples/class-prop-returns/_config.js @@ -2,7 +2,6 @@ const assert = require('assert'); module.exports = { description: 'does not remove calls to props without value', - minNodeVersion: 12, exports({ callProp, callStaticProp }) { let hasError = false; try { diff --git a/test/function/samples/deoptimize-computed-class-keys/_config.js b/test/function/samples/deoptimize-computed-class-keys/_config.js index 53e617bd7fe..dfe1e1e59b7 100644 --- a/test/function/samples/deoptimize-computed-class-keys/_config.js +++ b/test/function/samples/deoptimize-computed-class-keys/_config.js @@ -1,4 +1,3 @@ module.exports = { - description: 'deoptimizes computed class property keys', - minNodeVersion: 12 + description: 'deoptimizes computed class property keys' }; diff --git a/test/function/samples/modify-this-via-getter/known-super-prop/_config.js b/test/function/samples/modify-this-via-getter/known-super-prop/_config.js index 52280f050d4..a5508ce20b8 100644 --- a/test/function/samples/modify-this-via-getter/known-super-prop/_config.js +++ b/test/function/samples/modify-this-via-getter/known-super-prop/_config.js @@ -1,4 +1,3 @@ module.exports = { - description: 'handles getters that modify "this" on prototypes for known properties', - minNodeVersion: 12 + description: 'handles getters that modify "this" on prototypes for known properties' }; diff --git a/test/function/samples/modify-this-via-getter/unknown-super-prop/_config.js b/test/function/samples/modify-this-via-getter/unknown-super-prop/_config.js index 7e4188cbd13..362170a081b 100644 --- a/test/function/samples/modify-this-via-getter/unknown-super-prop/_config.js +++ b/test/function/samples/modify-this-via-getter/unknown-super-prop/_config.js @@ -1,6 +1,5 @@ module.exports = { description: 'handles getters that modify "this" on prototypes for unknown properties', - minNodeVersion: 12, context: { require(id) { return { unknown: 'prop' }; diff --git a/test/function/samples/modify-this-via-setter/known-super-prop/_config.js b/test/function/samples/modify-this-via-setter/known-super-prop/_config.js index 1a2b7ea0df4..82c65bfeb09 100644 --- a/test/function/samples/modify-this-via-setter/known-super-prop/_config.js +++ b/test/function/samples/modify-this-via-setter/known-super-prop/_config.js @@ -1,4 +1,3 @@ module.exports = { - description: 'handles setters that modify "this" on prototypes for known properties', - minNodeVersion: 12 + description: 'handles setters that modify "this" on prototypes for known properties' }; diff --git a/test/function/samples/modify-this-via-setter/unknown-super-prop/_config.js b/test/function/samples/modify-this-via-setter/unknown-super-prop/_config.js index c68617f4906..5bd99dc35bf 100644 --- a/test/function/samples/modify-this-via-setter/unknown-super-prop/_config.js +++ b/test/function/samples/modify-this-via-setter/unknown-super-prop/_config.js @@ -1,6 +1,5 @@ module.exports = { description: 'handles setters that modify "this" on prototypes for unknown properties', - minNodeVersion: 12, context: { require(id) { return { unknown: 'prop' }; diff --git a/test/function/samples/parameter-defaults/class-fields/_config.js b/test/function/samples/parameter-defaults/class-fields/_config.js index 668035e0dce..88efb89a967 100644 --- a/test/function/samples/parameter-defaults/class-fields/_config.js +++ b/test/function/samples/parameter-defaults/class-fields/_config.js @@ -1,4 +1,3 @@ module.exports = { - description: 'keeps parameter defaults for class fields', - minNodeVersion: 12 + description: 'keeps parameter defaults for class fields' }; diff --git a/test/load-config-file/index.js b/test/load-config-file/index.js index 6797e9f63a7..b8937a7340f 100644 --- a/test/load-config-file/index.js +++ b/test/load-config-file/index.js @@ -1,30 +1,142 @@ const assert = require('node:assert'); const path = require('node:path'); const { loadConfigFile } = require('../../dist/loadConfigFile.js'); +const { compareError } = require('../utils'); describe('loadConfigFile', () => { - it('loads a config file', async () => { + const defaultConfigs = [ + { + external: [], + input: 'my-input', + output: [ + { + file: 'my-file', + format: 'es', + plugins: [] + } + ], + plugins: [ + { + name: 'stdin' + } + ] + } + ]; + + it('loads an ESM config file', async () => { + const { options, warnings } = await loadConfigFile( + path.resolve(__dirname, 'samples/esm-via-pkg/rollup.config.js') + ); + assert.strictEqual(warnings.count, 0); + // Remove undefined values and functions before checking + assert.deepStrictEqual(JSON.parse(JSON.stringify(options)), defaultConfigs); + }); + + it('loads an ESM config file with mjs extension', async () => { + const { options, warnings } = await loadConfigFile( + path.resolve(__dirname, 'samples/esm-via-ext/rollup.config.mjs') + ); + assert.strictEqual(warnings.count, 0); + // Remove undefined values and functions before checking + assert.deepStrictEqual(JSON.parse(JSON.stringify(options)), defaultConfigs); + }); + + it('loads a CommonJS config file', async () => { const { options, warnings } = await loadConfigFile( - path.resolve(__dirname, 'samples/basic/rollup.config.js') + path.resolve(__dirname, 'samples/cjs-via-pkg/rollup.config.js') ); assert.strictEqual(warnings.count, 0); - assert.deepStrictEqual(JSON.parse(JSON.stringify(options)), [ - { - external: [], - input: 'my-input', - output: [ - { - file: 'my-file', - format: 'es', - plugins: [] - } - ], - plugins: [ - { - name: 'stdin' - } - ] - } - ]); + // Remove undefined values and functions before checking + assert.deepStrictEqual(JSON.parse(JSON.stringify(options)), defaultConfigs); + }); + + it('loads a CommonJS config file with cjs extension', async () => { + const { options, warnings } = await loadConfigFile( + path.resolve(__dirname, 'samples/cjs-via-ext/rollup.config.cjs') + ); + assert.strictEqual(warnings.count, 0); + // Remove undefined values and functions before checking + assert.deepStrictEqual(JSON.parse(JSON.stringify(options)), defaultConfigs); + }); + + it('throws a helpful error when loading an ES module that should actually be CommonJS', async () => { + let caughtError; + try { + await loadConfigFile(path.resolve(__dirname, 'samples/cjs-as-esm/rollup.config.js')); + } catch (err) { + caughtError = err; + } + compareError(caughtError, { + cause: { + message: "Unexpected token 'export'" + }, + code: 'INVALID_CONFIG_MODULE_FORMAT', + message: + 'Node tried to load your configuration file as CommonJS even though it is likely an ES module. To resolve this, change the extension of your configuration to ".mjs", set "type": "module" in your package.json file or pass the "--bundleConfigAsCjs" flag.\n\nOriginal error: Unexpected token \'export\'', + url: 'https://rollupjs.org/guide/en/#--bundleconfigascjs' + }); + }); + + it('just throws the error if it is not accompanied by the proper warning', async () => { + let caughtError; + try { + const promise = loadConfigFile( + path.resolve(__dirname, 'samples/esm-with-error/rollup.config.js') + ); + process.emit('warning', { message: 'Another warning.' }); + await promise; + } catch (err) { + caughtError = err; + } + compareError(caughtError, { + message: 'Config broken.' + }); + }); + + it('throws a helpful error when loading a CommonJS module that should actually be ES', async () => { + let caughtError; + try { + await loadConfigFile(path.resolve(__dirname, 'samples/esm-as-cjs/rollup.config.js')); + } catch (err) { + caughtError = err; + } + assert.strictEqual( + caughtError.message.slice(0, 256), + 'Node tried to load your configuration as an ES module even though it is likely CommonJS. To resolve this, change the extension of your configuration to ".cjs" or pass the "--bundleConfigAsCjs" flag.\n\nOriginal error: module is not defined in ES module scope' + ); + }); + + it('throws a helpful error when loading a CJS module that should actually be ESM while bundling', async () => { + let caughtError; + try { + await loadConfigFile(path.resolve(__dirname, 'samples/esm-as-cjs/rollup.config.js'), { + configPlugin: '{transform: c => c}' + }); + } catch (err) { + caughtError = err; + } + compareError(caughtError, { + cause: { + message: 'module is not defined in ES module scope' + }, + code: 'INVALID_CONFIG_MODULE_FORMAT', + message: + 'Rollup transpiled your configuration to an ES module even though it appears to contain CommonJS elements. To resolve this, you can pass the "--bundleConfigAsCjs" flag to Rollup or change your configuration to only contain valid ESM code.\n\nOriginal error: module is not defined in ES module scope', + url: 'https://rollupjs.org/guide/en/#--bundleconfigascjs' + }); + }); + + it('just throws other errors while bundling', async () => { + let caughtError; + try { + await loadConfigFile(path.resolve(__dirname, 'samples/esm-with-error/rollup.config.js'), { + configPlugin: '{transform: c => c}' + }); + } catch (err) { + caughtError = err; + } + compareError(caughtError, { + message: 'Config broken.' + }); }); }); diff --git a/test/load-config-file/samples/cjs-as-esm/package.json b/test/load-config-file/samples/cjs-as-esm/package.json new file mode 100644 index 00000000000..a0df0c86778 --- /dev/null +++ b/test/load-config-file/samples/cjs-as-esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/test/load-config-file/samples/basic/rollup.config.js b/test/load-config-file/samples/cjs-as-esm/rollup.config.js similarity index 100% rename from test/load-config-file/samples/basic/rollup.config.js rename to test/load-config-file/samples/cjs-as-esm/rollup.config.js diff --git a/test/cli/samples/config-no-module/sub/package.json b/test/load-config-file/samples/cjs-via-ext/package.json similarity index 100% rename from test/cli/samples/config-no-module/sub/package.json rename to test/load-config-file/samples/cjs-via-ext/package.json diff --git a/test/load-config-file/samples/cjs-via-ext/rollup.config.cjs b/test/load-config-file/samples/cjs-via-ext/rollup.config.cjs new file mode 100644 index 00000000000..a32b9091003 --- /dev/null +++ b/test/load-config-file/samples/cjs-via-ext/rollup.config.cjs @@ -0,0 +1,7 @@ +module.exports = { + input: 'my-input', + output: { + file: 'my-file', + format: 'es' + } +}; diff --git a/test/load-config-file/samples/cjs-via-pkg/package.json b/test/load-config-file/samples/cjs-via-pkg/package.json new file mode 100644 index 00000000000..a0df0c86778 --- /dev/null +++ b/test/load-config-file/samples/cjs-via-pkg/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/test/load-config-file/samples/cjs-via-pkg/rollup.config.js b/test/load-config-file/samples/cjs-via-pkg/rollup.config.js new file mode 100644 index 00000000000..a32b9091003 --- /dev/null +++ b/test/load-config-file/samples/cjs-via-pkg/rollup.config.js @@ -0,0 +1,7 @@ +module.exports = { + input: 'my-input', + output: { + file: 'my-file', + format: 'es' + } +}; diff --git a/test/load-config-file/samples/esm-as-cjs/package.json b/test/load-config-file/samples/esm-as-cjs/package.json new file mode 100644 index 00000000000..bedb411a912 --- /dev/null +++ b/test/load-config-file/samples/esm-as-cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/test/load-config-file/samples/esm-as-cjs/rollup.config.js b/test/load-config-file/samples/esm-as-cjs/rollup.config.js new file mode 100644 index 00000000000..a32b9091003 --- /dev/null +++ b/test/load-config-file/samples/esm-as-cjs/rollup.config.js @@ -0,0 +1,7 @@ +module.exports = { + input: 'my-input', + output: { + file: 'my-file', + format: 'es' + } +}; diff --git a/test/load-config-file/samples/esm-via-ext/package.json b/test/load-config-file/samples/esm-via-ext/package.json new file mode 100644 index 00000000000..a0df0c86778 --- /dev/null +++ b/test/load-config-file/samples/esm-via-ext/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/test/load-config-file/samples/esm-via-ext/rollup.config.mjs b/test/load-config-file/samples/esm-via-ext/rollup.config.mjs new file mode 100644 index 00000000000..0ba62eed7c3 --- /dev/null +++ b/test/load-config-file/samples/esm-via-ext/rollup.config.mjs @@ -0,0 +1,7 @@ +export default { + input: 'my-input', + output: { + file: 'my-file', + format: 'es' + } +}; diff --git a/test/load-config-file/samples/esm-via-pkg/package.json b/test/load-config-file/samples/esm-via-pkg/package.json new file mode 100644 index 00000000000..bedb411a912 --- /dev/null +++ b/test/load-config-file/samples/esm-via-pkg/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/test/load-config-file/samples/esm-via-pkg/rollup.config.js b/test/load-config-file/samples/esm-via-pkg/rollup.config.js new file mode 100644 index 00000000000..0ba62eed7c3 --- /dev/null +++ b/test/load-config-file/samples/esm-via-pkg/rollup.config.js @@ -0,0 +1,7 @@ +export default { + input: 'my-input', + output: { + file: 'my-file', + format: 'es' + } +}; diff --git a/test/load-config-file/samples/esm-with-error/package.json b/test/load-config-file/samples/esm-with-error/package.json new file mode 100644 index 00000000000..bedb411a912 --- /dev/null +++ b/test/load-config-file/samples/esm-with-error/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/test/load-config-file/samples/esm-with-error/rollup.config.js b/test/load-config-file/samples/esm-with-error/rollup.config.js new file mode 100644 index 00000000000..36a7414d777 --- /dev/null +++ b/test/load-config-file/samples/esm-with-error/rollup.config.js @@ -0,0 +1 @@ +throw new Error('Config broken.'); diff --git a/test/misc/optionList.js b/test/misc/optionList.js index 56c9e595332..db722ff0ef5 100644 --- a/test/misc/optionList.js +++ b/test/misc/optionList.js @@ -1,6 +1,6 @@ exports.input = 'acorn, acornInjectPlugins, cache, context, experimentalCacheExpiry, external, inlineDynamicImports, input, makeAbsoluteExternalsRelative, manualChunks, maxParallelFileOps, maxParallelFileReads, moduleContext, onwarn, perf, plugins, preserveEntrySignatures, preserveModules, preserveSymlinks, shimMissingExports, strictDeprecations, treeshake, watch'; exports.flags = - 'acorn, acornInjectPlugins, amd, assetFileNames, banner, c, cache, chunkFileNames, compact, config, configPlugin, context, d, dir, dynamicImportFunction, e, entryFileNames, environment, esModule, experimentalCacheExpiry, exports, extend, external, externalLiveBindings, f, failAfterWarnings, file, footer, format, freeze, g, generatedCode, globals, h, hoistTransitiveImports, i, indent, inlineDynamicImports, input, interop, intro, m, makeAbsoluteExternalsRelative, manualChunks, maxParallelFileOps, maxParallelFileReads, minifyInternalExports, moduleContext, n, name, namespaceToStringTag, noConflict, o, onwarn, outro, p, paths, perf, plugin, plugins, preferConst, preserveEntrySignatures, preserveModules, preserveModulesRoot, preserveSymlinks, sanitizeFileName, shimMissingExports, silent, sourcemap, sourcemapBaseUrl, sourcemapExcludeSources, sourcemapFile, stdin, strict, strictDeprecations, systemNullSetters, treeshake, v, validate, w, waitForBundleInput, watch'; + 'acorn, acornInjectPlugins, amd, assetFileNames, banner, bundleConfigAsCjs, c, cache, chunkFileNames, compact, config, configPlugin, context, d, dir, dynamicImportFunction, e, entryFileNames, environment, esModule, experimentalCacheExpiry, exports, extend, external, externalLiveBindings, f, failAfterWarnings, file, footer, format, freeze, g, generatedCode, globals, h, hoistTransitiveImports, i, indent, inlineDynamicImports, input, interop, intro, m, makeAbsoluteExternalsRelative, manualChunks, maxParallelFileOps, maxParallelFileReads, minifyInternalExports, moduleContext, n, name, namespaceToStringTag, noConflict, o, onwarn, outro, p, paths, perf, plugin, plugins, preferConst, preserveEntrySignatures, preserveModules, preserveModulesRoot, preserveSymlinks, sanitizeFileName, shimMissingExports, silent, sourcemap, sourcemapBaseUrl, sourcemapExcludeSources, sourcemapFile, stdin, strict, strictDeprecations, systemNullSetters, treeshake, v, validate, w, waitForBundleInput, watch'; exports.output = 'amd, assetFileNames, banner, chunkFileNames, compact, dir, dynamicImportFunction, entryFileNames, esModule, exports, extend, externalLiveBindings, file, footer, format, freeze, generatedCode, globals, hoistTransitiveImports, indent, inlineDynamicImports, interop, intro, manualChunks, minifyInternalExports, name, namespaceToStringTag, noConflict, outro, paths, plugins, preferConst, preserveModules, preserveModulesRoot, sanitizeFileName, sourcemap, sourcemapBaseUrl, sourcemapExcludeSources, sourcemapFile, sourcemapPathTransform, strict, systemNullSetters, validate'; diff --git a/typings/declarations.d.ts b/typings/declarations.d.ts index 846464c182e..51f94dc1e2c 100644 --- a/typings/declarations.d.ts +++ b/typings/declarations.d.ts @@ -99,11 +99,3 @@ declare module 'is-reference' { value: Node; }; } - -declare module 'get-package-type' { - interface GetPackageType { - sync(fileName: string): 'module' | 'commonjs'; - } - const getPackageType: GetPackageType; - export default getPackageType; -}