Add unicorn plugin (#4666)

pull/4667/head
Lukas Taegert-Atkinson 1 year ago committed by GitHub
parent 4fdf8bd86f
commit 3cb7f1376f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -10,7 +10,8 @@ module.exports = {
'prettier',
'plugin:prettier/recommended',
'plugin:import/recommended',
'plugin:import/typescript'
'plugin:import/typescript',
'plugin:unicorn/recommended'
],
ignorePatterns: [
'node_modules',
@ -26,7 +27,9 @@ module.exports = {
{
files: ['*.js'],
rules: {
'@typescript-eslint/explicit-module-boundary-types': 'off'
'@typescript-eslint/explicit-module-boundary-types': 'off',
'unicorn/no-process-exit': 'off',
'unicorn/prefer-module': 'off'
}
},
{
@ -94,6 +97,18 @@ module.exports = {
ignoreMemberSort: false
}
],
'sort-keys': ['error', 'asc', { caseSensitive: false }]
'sort-keys': ['error', 'asc', { caseSensitive: false }],
'unicorn/filename-case': 'off',
'unicorn/no-array-callback-reference': 'off',
'unicorn/no-array-reduce': 'off',
'unicorn/no-await-expression-member': 'off',
'unicorn/no-nested-ternary': 'off',
'unicorn/no-null': 'off',
'unicorn/no-this-assignment': 'off',
'unicorn/no-useless-undefined': 'off',
'unicorn/prefer-code-point': 'off',
'unicorn/prefer-math-trunc': 'off',
'unicorn/prefer-number-properties': 'off',
'unicorn/prefer-top-level-await': 'off'
}
};

@ -1,4 +1,4 @@
import { errNoFileSystemInBrowser, error } from '../../src/utils/error';
import { error, errorNoFileSystemInBrowser } from '../../src/utils/error';
export const throwNoFileSystem = (method: string) => (): never =>
error(errNoFileSystemInBrowser(method));
error(errorNoFileSystemInBrowser(method));

@ -1,4 +1,4 @@
const ABSOLUTE_PATH_REGEX = /^(?:\/|(?:[A-Za-z]:)?[\\|/])/;
const ABSOLUTE_PATH_REGEX = /^(?:\/|(?:[A-Za-z]:)?[/\\|])/;
const RELATIVE_PATH_REGEX = /^\.?\.\//;
const ALL_BACKSLASHES_REGEX = /\\/g;
const ANY_SLASH_REGEX = /[/\\]/;
@ -24,10 +24,10 @@ export function dirname(path: string): string {
const match = /[/\\][^/\\]*$/.exec(path);
if (!match) return '.';
const dir = path.slice(0, -match[0].length);
const directory = path.slice(0, -match[0].length);
// If `dir` is the empty string, we're at root.
return dir ? dir : '/';
// If `directory` is the empty string, we're at root.
return directory || '/';
}
export function extname(path: string): string {

@ -1,13 +1,13 @@
import fs from 'fs-extra';
import type { Plugin } from 'rollup';
export default function cleanBeforeWrite(dir: string): Plugin {
export default function cleanBeforeWrite(directory: string): Plugin {
let removePromise: Promise<void> | null = null;
return {
generateBundle(_options, _bundle, isWrite) {
if (isWrite) {
// Only remove before first write, but make all writes wait on the removal
removePromise ||= fs.remove(dir);
removePromise ||= fs.remove(directory);
return removePromise;
}
},

@ -4,12 +4,12 @@ import type { PluginImpl } from 'rollup';
import license, { type Dependency, type Person } from 'rollup-plugin-license';
async function generateLicenseFile(
dir: string,
directory: string,
dependencies: readonly Dependency[]
): Promise<void> {
const coreLicense = await fs.readFile('LICENSE-CORE.md', 'utf8');
const licenses = new Set<string>();
const dependencyLicenseTexts = Array.from(dependencies)
const dependencyLicenseTexts = [...dependencies]
.filter(({ name }) => name !== '@rollup/browser')
.sort(({ name: nameA }, { name: nameB }) => (nameA! > nameB! ? 1 : -1))
.map(({ name, license, licenseText, author, maintainers, contributors, repository }) => {
@ -22,13 +22,13 @@ async function generateLicenseFile(
names.add(author.name);
}
// TODO there is an inconsistency in the rollup-plugin-license types
for (const person of contributors.concat(maintainers as unknown as Person[])) {
for (const person of [...contributors, ...(maintainers as unknown as Person[])]) {
if (person?.name) {
names.add(person.name);
}
}
if (names.size > 0) {
text += `By: ${Array.from(names).join(', ')}\n`;
text += `By: ${[...names].join(', ')}\n`;
}
if (repository) {
text += `Repository: ${(typeof repository === 'object' && repository.url) || repository}\n`;
@ -54,10 +54,10 @@ async function generateLicenseFile(
coreLicense +
`\n# Licenses of bundled dependencies\n` +
`The published Rollup artifact additionally contains code with the following licenses:\n` +
`${Array.from(licenses).join(', ')}\n\n` +
`${[...licenses].join(', ')}\n\n` +
`# Bundled dependencies:\n` +
dependencyLicenseTexts;
const licenseFile = join(dir, 'LICENSE.md');
const licenseFile = join(directory, 'LICENSE.md');
const existingLicenseText = await fs.readFile(licenseFile, 'utf8');
if (existingLicenseText !== licenseText) {
await fs.writeFile(licenseFile, licenseText);
@ -70,7 +70,7 @@ interface LicenseHandler {
writeLicense: PluginImpl;
}
export default function getLicenseHandler(dir: string): LicenseHandler {
export default function getLicenseHandler(directory: string): LicenseHandler {
const licenses = new Map<string, Dependency>();
function addLicenses(dependencies: readonly Dependency[]) {
for (const dependency of dependencies) {
@ -85,7 +85,7 @@ export default function getLicenseHandler(dir: string): LicenseHandler {
return {
name: 'write-license',
writeBundle() {
return generateLicenseFile(dir, Array.from(licenses.values()));
return generateLicenseFile(directory, [...licenses.values()]);
}
};
}

@ -27,5 +27,5 @@ export default async function getBanner(): Promise<string> {
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)));
]).then(([{ stdout }, package_]) => generateBanner(stdout.trim(), JSON.parse(package_).version)));
}

@ -16,6 +16,7 @@ if (command.help || (process.argv.length <= 2 && process.stdin.isTTY)) {
console.log(`rollup v${version}`);
} else {
try {
// eslint-disable-next-line unicorn/prefer-module
require('source-map-support').install();
} catch {
// do nothing

@ -4,35 +4,37 @@ import { bold, cyan, dim, red } from '../src/utils/colors';
import relativeId from '../src/utils/relativeId';
// log to stderr to keep `rollup main.js > bundle.js` from breaking
export const stderr = (...args: readonly unknown[]) => process.stderr.write(`${args.join('')}\n`);
export const stderr = (...parameters: readonly unknown[]) =>
process.stderr.write(`${parameters.join('')}\n`);
export function handleError(err: RollupError, recover = false): void {
const name = err.name || err.cause?.name;
export function handleError(error: RollupError, recover = false): void {
const name = error.name || error.cause?.name;
const nameSection = name ? `${name}: ` : '';
const pluginSection = err.plugin ? `(plugin ${err.plugin}) ` : '';
const message = `${pluginSection}${nameSection}${err.message}`;
const pluginSection = error.plugin ? `(plugin ${error.plugin}) ` : '';
const message = `${pluginSection}${nameSection}${error.message}`;
stderr(bold(red(`[!] ${bold(message.toString())}`)));
if (err.url) {
stderr(cyan(err.url));
if (error.url) {
stderr(cyan(error.url));
}
if (err.loc) {
stderr(`${relativeId((err.loc.file || err.id)!)} (${err.loc.line}:${err.loc.column})`);
} else if (err.id) {
stderr(relativeId(err.id));
if (error.loc) {
stderr(`${relativeId((error.loc.file || error.id)!)} (${error.loc.line}:${error.loc.column})`);
} else if (error.id) {
stderr(relativeId(error.id));
}
if (err.frame) {
stderr(dim(err.frame));
if (error.frame) {
stderr(dim(error.frame));
}
if (err.stack) {
stderr(dim(err.stack));
if (error.stack) {
stderr(dim(error.stack));
}
stderr('');
// eslint-disable-next-line unicorn/no-process-exit
if (!recover) process.exit(1);
}

@ -51,7 +51,7 @@ export default function batchWarnings(): BatchWarnings {
flush() {
if (count === 0) return;
const codes = Array.from(deferredWarnings.keys()).sort(
const codes = [...deferredWarnings.keys()].sort(
(a, b) => deferredWarnings.get(b)!.length - deferredWarnings.get(a)!.length
);
@ -245,8 +245,8 @@ const deferredHandlers: {
}
};
function title(str: string): void {
stderr(bold(yellow(`(!) ${str}`)));
function title(string_: string): void {
stderr(bold(yellow(`(!) ${string_}`)));
}
function info(url: string): void {
@ -258,12 +258,12 @@ interface Nested<T> {
key: string;
}
function nest<T extends Record<string, any>>(array: readonly T[], prop: string): Nested<T>[] {
function nest<T extends Record<string, any>>(array: readonly T[], property: string): Nested<T>[] {
const nested: Nested<T>[] = [];
const lookup = new Map<string, Nested<T>>();
for (const item of array) {
const key = item[prop];
const key = item[property];
getOrCreate(lookup, key, () => {
const items = {
items: [],

@ -3,7 +3,7 @@ import ms from 'pretty-ms';
import { rollup } from '../../src/node-entry';
import type { MergedRollupOptions } from '../../src/rollup/types';
import { bold, cyan, green } from '../../src/utils/colors';
import { errOnlyInlineSourcemapsForStdout } from '../../src/utils/error';
import { errorOnlyInlineSourcemapsForStdout } from '../../src/utils/error';
import relativeId from '../../src/utils/relativeId';
import { handleError, stderr } from '../logging';
import type { BatchWarnings } from './batchWarnings';
@ -22,7 +22,7 @@ export default async function build(
let inputFiles: string | undefined;
if (typeof inputOptions.input === 'string') {
inputFiles = inputOptions.input;
} else if (inputOptions.input instanceof Array) {
} else if (Array.isArray(inputOptions.input)) {
inputFiles = inputOptions.input.join(', ');
} else if (typeof inputOptions.input === 'object' && inputOptions.input !== null) {
inputFiles = Object.values(inputOptions.input).join(', ');
@ -34,7 +34,7 @@ export default async function build(
if (useStdout) {
const output = outputOptions[0];
if (output.sourcemap && output.sourcemap !== 'inline') {
handleError(errOnlyInlineSourcemapsForStdout());
handleError(errorOnlyInlineSourcemapsForStdout());
}
const { output: outputs } = await bundle.generate(output);
for (const file of outputs) {

@ -45,21 +45,21 @@ async function loadAndRegisterPlugin(
pluginText: string
): Promise<void> {
let plugin: any = null;
let pluginArg: any = undefined;
let pluginArgument: any = undefined;
if (pluginText[0] === '{') {
// -p "{transform(c,i){...}}"
plugin = new Function('return ' + pluginText);
} else {
const match = pluginText.match(/^([@.:/\\\w|^{}-]+)(=(.*))?$/);
const match = pluginText.match(/^([\w./:@\\^{|}-]+)(=(.*))?$/);
if (match) {
// -p plugin
// -p plugin=arg
pluginText = match[1];
pluginArg = new Function('return ' + match[3])();
pluginArgument = new Function('return ' + match[3])();
} else {
throw new Error(`Invalid --plugin argument format: ${JSON.stringify(pluginText)}`);
}
if (!/^\.|^rollup-plugin-|[@/\\]/.test(pluginText)) {
if (!/^\.|^rollup-plugin-|[/@\\]/.test(pluginText)) {
// Try using plugin prefix variations first if applicable.
// Prefix order is significant - left has higher precedence.
for (const prefix of ['@rollup/plugin-', 'rollup-plugin-']) {
@ -76,12 +76,12 @@ async function loadAndRegisterPlugin(
if (pluginText[0] == '.') pluginText = resolve(pluginText);
// Windows absolute paths must be specified as file:// protocol URL
// Note that we do not have coverage for Windows-only code paths
else if (pluginText.match(/^[A-Za-z]:\\/)) {
else if (/^[A-Za-z]:\\/.test(pluginText)) {
pluginText = pathToFileURL(resolve(pluginText)).href;
}
plugin = await requireOrImport(pluginText);
} catch (err: any) {
throw new Error(`Cannot load plugin "${pluginText}": ${err.message}.`);
} catch (error: any) {
throw new Error(`Cannot load plugin "${pluginText}": ${error.message}.`);
}
}
}
@ -97,12 +97,14 @@ async function loadAndRegisterPlugin(
)}" for Rollup to recognize it.`
);
}
inputOptions.plugins.push(typeof plugin === 'function' ? plugin.call(plugin, pluginArg) : plugin);
inputOptions.plugins.push(
typeof plugin === 'function' ? plugin.call(plugin, pluginArgument) : plugin
);
}
function getCamelizedPluginBaseName(pluginText: string): string {
return (pluginText.match(/(@rollup\/plugin-|rollup-plugin-)(.+)$/)?.[2] || pluginText)
.split(/[\\/]/)
.split(/[/\\]/)
.slice(-1)[0]
.split('.')[0]
.split('-')
@ -112,6 +114,7 @@ function getCamelizedPluginBaseName(pluginText: string): string {
async function requireOrImport(pluginPath: string): Promise<any> {
try {
// eslint-disable-next-line unicorn/prefer-module
return require(pluginPath);
} catch {
return import(pluginPath);

@ -1,7 +1,7 @@
import { promises as fs } from 'node:fs';
import { resolve } from 'node:path';
import { cwd } from 'node:process';
import { errMissingExternalConfig } from '../../src/utils/error';
import { errorMissingExternalConfig } from '../../src/utils/error';
import { handleError } from '../logging';
const DEFAULT_CONFIG_BASE = 'rollup.config';
@ -11,17 +11,19 @@ export async function getConfigPath(commandConfig: string | true): Promise<strin
return resolve(await findConfigFileNameInCwd());
}
if (commandConfig.slice(0, 5) === 'node:') {
const pkgName = commandConfig.slice(5);
const packageName = commandConfig.slice(5);
try {
return require.resolve(`rollup-config-${pkgName}`, { paths: [cwd()] });
// eslint-disable-next-line unicorn/prefer-module
return require.resolve(`rollup-config-${packageName}`, { paths: [cwd()] });
} catch {
try {
return require.resolve(pkgName, { paths: [cwd()] });
} catch (err: any) {
if (err.code === 'MODULE_NOT_FOUND') {
handleError(errMissingExternalConfig(commandConfig));
// eslint-disable-next-line unicorn/prefer-module
return require.resolve(packageName, { paths: [cwd()] });
} catch (error: any) {
if (error.code === 'MODULE_NOT_FOUND') {
handleError(errorMissingExternalConfig(commandConfig));
}
throw err;
throw error;
}
}
}
@ -29,10 +31,10 @@ export async function getConfigPath(commandConfig: string | true): Promise<strin
}
async function findConfigFileNameInCwd(): Promise<string> {
const filesInWorkingDir = new Set(await fs.readdir(cwd()));
const filesInWorkingDirectory = new Set(await fs.readdir(cwd()));
for (const extension of ['mjs', 'cjs', 'ts']) {
const fileName = `${DEFAULT_CONFIG_BASE}.${extension}`;
if (filesInWorkingDir.has(fileName)) return fileName;
if (filesInWorkingDirectory.has(fileName)) return fileName;
}
return `${DEFAULT_CONFIG_BASE}.js`;
}

@ -1,6 +1,6 @@
import { env } from 'node:process';
import type { MergedRollupOptions } from '../../src/rollup/types';
import { errDuplicateImportOptions, errFailAfterWarnings } from '../../src/utils/error';
import { errorDuplicateImportOptions, errorFailAfterWarnings } from '../../src/utils/error';
import { isWatchEnabled } from '../../src/utils/options/mergeOptions';
import { getAliasName } from '../../src/utils/relativeId';
import { loadFsEvents } from '../../src/watch/fsevents-importer';
@ -15,7 +15,7 @@ export default async function runRollup(command: Record<string, any>): Promise<v
let inputSource;
if (command._.length > 0) {
if (command.input) {
handleError(errDuplicateImportOptions());
handleError(errorDuplicateImportOptions());
}
inputSource = command._;
} else if (typeof command.input === 'string') {
@ -27,13 +27,13 @@ export default async function runRollup(command: Record<string, any>): Promise<v
if (inputSource && inputSource.length > 0) {
if (inputSource.some((input: string) => input.includes('='))) {
command.input = {};
inputSource.forEach((input: string) => {
for (const input of inputSource) {
const equalsIndex = input.indexOf('=');
const value = input.substring(equalsIndex + 1);
const key = input.substring(0, equalsIndex) || getAliasName(input);
const value = input.slice(Math.max(0, equalsIndex + 1));
const key = input.slice(0, Math.max(0, equalsIndex)) || getAliasName(input);
command.input[key] = value;
});
}
} else {
command.input = inputSource;
}
@ -44,12 +44,12 @@ export default async function runRollup(command: Record<string, any>): Promise<v
? command.environment
: [command.environment];
environment.forEach((arg: string) => {
arg.split(',').forEach((pair: string) => {
for (const argument of environment) {
for (const pair of argument.split(',')) {
const [key, ...value] = pair.split(':');
env[key] = value.length === 0 ? String(true) : value.join(':');
});
});
}
}
}
if (isWatchEnabled(command.watch)) {
@ -65,14 +65,14 @@ export default async function runRollup(command: Record<string, any>): Promise<v
}
if (command.failAfterWarnings && warnings.warningOccurred) {
warnings.flush();
handleError(errFailAfterWarnings());
handleError(errorFailAfterWarnings());
}
} catch (err: any) {
} catch (error: any) {
warnings.flush();
handleError(err);
handleError(error);
}
} catch (err: any) {
handleError(err);
} catch (error: any) {
handleError(error);
}
}
}

@ -6,11 +6,11 @@ import * as rollup from '../../src/node-entry';
import type { MergedRollupOptions } from '../../src/rollup/types';
import { bold } from '../../src/utils/colors';
import {
errCannotBundleConfigAsEsm,
errCannotLoadConfigAsCjs,
errCannotLoadConfigAsEsm,
errMissingConfig,
error
error,
errorCannotBundleConfigAsEsm,
errorCannotLoadConfigAsCjs,
errorCannotLoadConfigAsEsm,
errorMissingConfig
} from '../../src/utils/error';
import { mergeOptions } from '../../src/utils/options/mergeOptions';
import type { GenericConfigObject } from '../../src/utils/options/options';
@ -36,9 +36,9 @@ export async function loadConfigFile(
normalizedConfigs.push(options);
}
return { options: normalizedConfigs, warnings };
} catch (err) {
} catch (error_) {
warnings.flush();
throw err;
throw error_;
}
}
@ -46,11 +46,11 @@ async function getConfigFileExport(fileName: string, commandOptions: Record<stri
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));
} catch (error_: any) {
if (error_.message.includes('not defined in ES module scope')) {
return error(errorCannotBundleConfigAsEsm(error_));
}
throw err;
throw error_;
}
}
let cannotLoadEsm = false;
@ -67,14 +67,14 @@ async function getConfigFileExport(fileName: string, commandOptions: Record<stri
fileUrl.search = `?${Date.now()}`;
}
return (await import(fileUrl.href)).default;
} catch (err: any) {
} catch (error_: any) {
if (cannotLoadEsm) {
return error(errCannotLoadConfigAsCjs(err));
return error(errorCannotLoadConfigAsCjs(error_));
}
if (err.message.includes('not defined in ES module scope')) {
return error(errCannotLoadConfigAsEsm(err));
if (error_.message.includes('not defined in ES module scope')) {
return error(errorCannotLoadConfigAsEsm(error_));
}
throw err;
throw error_;
} finally {
process.off('warning', handleWarning);
}
@ -146,7 +146,7 @@ async function getConfigList(configFileExport: any, commandOptions: any): Promis
? configFileExport(commandOptions)
: configFileExport);
if (Object.keys(config).length === 0) {
return error(errMissingConfig());
return error(errorMissingConfig());
}
return Array.isArray(config) ? config : [config];
}

@ -5,8 +5,8 @@ export const stdinName = '-';
let stdinResult: Promise<string> | null = null;
export function stdinPlugin(arg: unknown): Plugin {
const suffix = typeof arg == 'string' && arg.length ? '.' + arg : '';
export function stdinPlugin(argument: unknown): Plugin {
const suffix = typeof argument == 'string' && argument.length > 0 ? '.' + argument : '';
return {
load(id) {
if (id === stdinName || id.startsWith(stdinName + '.')) {
@ -32,8 +32,8 @@ function readStdin(): Promise<string> {
const result = chunks.join('');
resolve(result);
})
.on('error', err => {
reject(err);
.on('error', error => {
reject(error);
});
});
}

@ -3,10 +3,10 @@ import type { SerializedTimings } from '../../src/rollup/types';
import { bold, underline } from '../../src/utils/colors';
export function printTimings(timings: SerializedTimings): void {
Object.entries(timings).forEach(([label, [time, memory, total]]) => {
for (const [label, [time, memory, total]] of Object.entries(timings)) {
const appliedColor =
label[0] === '#' ? (label[1] !== '#' ? underline : bold) : (text: string) => text;
const row = `${label}: ${time.toFixed(0)}ms, ${prettyBytes(memory)} / ${prettyBytes(total)}`;
console.info(appliedColor(row));
});
}
}

@ -61,8 +61,8 @@ export async function watch(command: Record<string, any>): Promise<void> {
await watcher.close();
}
start(options, warnings);
} catch (err: any) {
handleError(err, true);
} catch (error: any) {
handleError(error, true);
}
}
}
@ -77,19 +77,20 @@ export async function watch(command: Record<string, any>): Promise<void> {
function start(configs: MergedRollupOptions[], warnings: BatchWarnings): void {
try {
watcher = rollup.watch(configs as any);
} catch (err: any) {
return handleError(err);
} catch (error: any) {
return handleError(error);
}
watcher.on('event', event => {
switch (event.code) {
case 'ERROR':
case 'ERROR': {
warnings.flush();
handleError(event.error, true);
runWatchHook('onError');
break;
}
case 'START':
case 'START': {
if (!silent) {
if (!resetScreen) {
resetScreen = getResetScreen(configs, isTTY);
@ -99,8 +100,9 @@ export async function watch(command: Record<string, any>): Promise<void> {
runWatchHook('onStart');
break;
}
case 'BUNDLE_START':
case 'BUNDLE_START': {
if (!silent) {
let input = event.input;
if (typeof input !== 'string') {
@ -114,8 +116,9 @@ export async function watch(command: Record<string, any>): Promise<void> {
}
runWatchHook('onBundleStart');
break;
}
case 'BUNDLE_END':
case 'BUNDLE_END': {
warnings.flush();
if (!silent)
stderr(
@ -130,12 +133,14 @@ export async function watch(command: Record<string, any>): Promise<void> {
printTimings(event.result.getTimings());
}
break;
}
case 'END':
case 'END': {
runWatchHook('onEnd');
if (!silent && isTTY) {
stderr(`\n[${dateTime()}] waiting for changes...`);
}
}
}
if ('result' in event && event.result) {
@ -153,6 +158,7 @@ export async function watch(command: Record<string, any>): Promise<void> {
if (configWatcher) configWatcher.close();
if (code) {
// eslint-disable-next-line unicorn/no-process-exit
process.exit(code);
}
}

@ -10,7 +10,7 @@ function extractWatchHooks(
return command.watch
.filter(value => typeof value === 'object')
.reduce((acc, keyValueOption) => ({ ...acc, ...keyValueOption }), {});
.reduce((accumulator, keyValueOption) => ({ ...accumulator, ...keyValueOption }), {});
}
export function createWatchHooks(command: Record<string, any>): (hook: RollupWatchHooks) => void {
@ -28,8 +28,8 @@ export function createWatchHooks(command: Record<string, any>): (hook: RollupWat
// !! important - use stderr for all writes from execSync
const stdio = [process.stdin, process.stderr, process.stderr];
execSync(cmd, { stdio: command.silent ? 'ignore' : stdio });
} catch (e) {
stderr((e as Error).message);
} catch (error) {
stderr((error as Error).message);
}
}
};

542
package-lock.json generated

@ -1,12 +1,12 @@
{
"name": "rollup",
"version": "3.0.0",
"version": "3.1.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "rollup",
"version": "3.0.0",
"version": "3.1.0",
"license": "MIT",
"bin": {
"rollup": "dist/bin/rollup"
@ -42,6 +42,7 @@
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-unicorn": "^44.0.2",
"fixturify": "^2.1.1",
"fs-extra": "^10.1.0",
"github-api": "^3.4.0",
@ -1030,6 +1031,12 @@
"integrity": "sha512-Y6S38pFr04yb13qqHf8uk1nHE3lXgQ30WZbv1mLliV9pt0NjvqdWttLcrOYLnXbOafknVYRHZGoMSpR9UwfYow==",
"dev": true
},
"node_modules/@types/normalize-package-data": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
"integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
"dev": true
},
"node_modules/@types/resolve": {
"version": "1.20.2",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
@ -1786,6 +1793,24 @@
"fsevents": "~2.3.2"
}
},
"node_modules/ci-info": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz",
"integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==",
"dev": true
},
"node_modules/clean-regexp": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz",
"integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==",
"dev": true,
"dependencies": {
"escape-string-regexp": "^1.0.5"
},
"engines": {
"node": ">=4"
}
},
"node_modules/clean-stack": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
@ -2387,6 +2412,15 @@
"integrity": "sha512-VWU0/zXzVbeJNXvME/5EmLuEj2TauvoaTz6aFYK1Z92JCBlDlZ3Gu0tuGR42kpW1754ywTs+QB0g5TP0oj9Zaw==",
"dev": true
},
"node_modules/error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
"dev": true,
"dependencies": {
"is-arrayish": "^0.2.1"
}
},
"node_modules/es-abstract": {
"version": "1.20.4",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz",
@ -2677,6 +2711,37 @@
}
}
},
"node_modules/eslint-plugin-unicorn": {
"version": "44.0.2",
"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-44.0.2.tgz",
"integrity": "sha512-GLIDX1wmeEqpGaKcnMcqRvMVsoabeF0Ton0EX4Th5u6Kmf7RM9WBl705AXFEsns56ESkEs0uyelLuUTvz9Tr0w==",
"dev": true,
"dependencies": {
"@babel/helper-validator-identifier": "^7.19.1",
"ci-info": "^3.4.0",
"clean-regexp": "^1.0.0",
"eslint-utils": "^3.0.0",
"esquery": "^1.4.0",
"indent-string": "^4.0.0",
"is-builtin-module": "^3.2.0",
"lodash": "^4.17.21",
"pluralize": "^8.0.0",
"read-pkg-up": "^7.0.1",
"regexp-tree": "^0.1.24",
"safe-regex": "^2.1.1",
"semver": "^7.3.7",
"strip-indent": "^3.0.0"
},
"engines": {
"node": ">=14.18"
},
"funding": {
"url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1"
},
"peerDependencies": {
"eslint": ">=8.23.1"
}
},
"node_modules/eslint-scope": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
@ -3649,6 +3714,12 @@
"he": "bin/he"
}
},
"node_modules/hosted-git-info": {
"version": "2.8.9",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
"dev": true
},
"node_modules/html-escaper": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
@ -3858,6 +3929,12 @@
"node": ">= 0.10"
}
},
"node_modules/is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
"dev": true
},
"node_modules/is-bigint": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
@ -4394,6 +4471,12 @@
"node": ">=4"
}
},
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
"dev": true
},
"node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@ -4452,6 +4535,12 @@
"node": ">=10"
}
},
"node_modules/lines-and-columns": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true
},
"node_modules/lint-staged": {
"version": "13.0.3",
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.0.3.tgz",
@ -5043,6 +5132,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/min-indent": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/minimalistic-assert": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
@ -5298,6 +5396,27 @@
"integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==",
"dev": true
},
"node_modules/normalize-package-data": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
"integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
"dev": true,
"dependencies": {
"hosted-git-info": "^2.1.4",
"resolve": "^1.10.0",
"semver": "2 || 3 || 4 || 5",
"validate-npm-package-license": "^3.0.1"
}
},
"node_modules/normalize-package-data/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true,
"bin": {
"semver": "bin/semver"
}
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@ -5870,6 +5989,24 @@
"node": ">=6"
}
},
"node_modules/parse-json": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.0.0",
"error-ex": "^1.3.1",
"json-parse-even-better-errors": "^2.3.0",
"lines-and-columns": "^1.1.6"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/parse-ms": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-3.0.0.tgz",
@ -6018,6 +6155,15 @@
"node": ">=8"
}
},
"node_modules/pluralize": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz",
"integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@ -6131,6 +6277,108 @@
"safe-buffer": "^5.1.0"
}
},
"node_modules/read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
"integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
"dev": true,
"dependencies": {
"@types/normalize-package-data": "^2.4.0",
"normalize-package-data": "^2.5.0",
"parse-json": "^5.0.0",
"type-fest": "^0.6.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/read-pkg-up": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
"integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
"dev": true,
"dependencies": {
"find-up": "^4.1.0",
"read-pkg": "^5.2.0",
"type-fest": "^0.8.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/read-pkg-up/node_modules/find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
"dependencies": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/read-pkg-up/node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
"dependencies": {
"p-locate": "^4.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/read-pkg-up/node_modules/p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"dependencies": {
"p-try": "^2.0.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/read-pkg-up/node_modules/p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
"dependencies": {
"p-limit": "^2.2.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/read-pkg-up/node_modules/type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/read-pkg/node_modules/type-fest": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
"integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
@ -6187,6 +6435,15 @@
"node": ">=4"
}
},
"node_modules/regexp-tree": {
"version": "0.1.24",
"resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz",
"integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==",
"dev": true,
"bin": {
"regexp-tree": "bin/regexp-tree"
}
},
"node_modules/regexp.prototype.flags": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
@ -6579,6 +6836,15 @@
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
},
"node_modules/safe-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz",
"integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==",
"dev": true,
"dependencies": {
"regexp-tree": "~0.1.1"
}
},
"node_modules/safe-regex-test": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
@ -6847,6 +7113,16 @@
"spdx-ranges": "^2.0.0"
}
},
"node_modules/spdx-correct": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
"integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
"dev": true,
"dependencies": {
"spdx-expression-parse": "^3.0.0",
"spdx-license-ids": "^3.0.0"
}
},
"node_modules/spdx-exceptions": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
@ -7044,6 +7320,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/strip-indent": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
"integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
"dev": true,
"dependencies": {
"min-indent": "^1.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@ -7436,6 +7724,16 @@
"uuid": "dist/bin/uuid"
}
},
"node_modules/validate-npm-package-license": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
"integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
"dev": true,
"dependencies": {
"spdx-correct": "^3.0.0",
"spdx-expression-parse": "^3.0.0"
}
},
"node_modules/walk-sync": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-2.2.0.tgz",
@ -8449,6 +8747,12 @@
"integrity": "sha512-Y6S38pFr04yb13qqHf8uk1nHE3lXgQ30WZbv1mLliV9pt0NjvqdWttLcrOYLnXbOafknVYRHZGoMSpR9UwfYow==",
"dev": true
},
"@types/normalize-package-data": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
"integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
"dev": true
},
"@types/resolve": {
"version": "1.20.2",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
@ -8948,6 +9252,21 @@
"readdirp": "~3.6.0"
}
},
"ci-info": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz",
"integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==",
"dev": true
},
"clean-regexp": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz",
"integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==",
"dev": true,
"requires": {
"escape-string-regexp": "^1.0.5"
}
},
"clean-stack": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
@ -9390,6 +9709,15 @@
"integrity": "sha512-VWU0/zXzVbeJNXvME/5EmLuEj2TauvoaTz6aFYK1Z92JCBlDlZ3Gu0tuGR42kpW1754ywTs+QB0g5TP0oj9Zaw==",
"dev": true
},
"error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
"dev": true,
"requires": {
"is-arrayish": "^0.2.1"
}
},
"es-abstract": {
"version": "1.20.4",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz",
@ -9704,6 +10032,28 @@
"prettier-linter-helpers": "^1.0.0"
}
},
"eslint-plugin-unicorn": {
"version": "44.0.2",
"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-44.0.2.tgz",
"integrity": "sha512-GLIDX1wmeEqpGaKcnMcqRvMVsoabeF0Ton0EX4Th5u6Kmf7RM9WBl705AXFEsns56ESkEs0uyelLuUTvz9Tr0w==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.19.1",
"ci-info": "^3.4.0",
"clean-regexp": "^1.0.0",
"eslint-utils": "^3.0.0",
"esquery": "^1.4.0",
"indent-string": "^4.0.0",
"is-builtin-module": "^3.2.0",
"lodash": "^4.17.21",
"pluralize": "^8.0.0",
"read-pkg-up": "^7.0.1",
"regexp-tree": "^0.1.24",
"safe-regex": "^2.1.1",
"semver": "^7.3.7",
"strip-indent": "^3.0.0"
}
},
"eslint-scope": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
@ -10329,6 +10679,12 @@
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true
},
"hosted-git-info": {
"version": "2.8.9",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
"dev": true
},
"html-escaper": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
@ -10469,6 +10825,12 @@
"integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
"dev": true
},
"is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
"dev": true
},
"is-bigint": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
@ -10853,6 +11215,12 @@
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
"dev": true
},
"json-parse-even-better-errors": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
"dev": true
},
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@ -10897,6 +11265,12 @@
"integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==",
"dev": true
},
"lines-and-columns": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true
},
"lint-staged": {
"version": "13.0.3",
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.0.3.tgz",
@ -11320,6 +11694,12 @@
"integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
"dev": true
},
"min-indent": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
"dev": true
},
"minimalistic-assert": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
@ -11514,6 +11894,26 @@
"integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==",
"dev": true
},
"normalize-package-data": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
"integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
"dev": true,
"requires": {
"hosted-git-info": "^2.1.4",
"resolve": "^1.10.0",
"semver": "2 || 3 || 4 || 5",
"validate-npm-package-license": "^3.0.1"
},
"dependencies": {
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true
}
}
},
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@ -11927,6 +12327,18 @@
"callsites": "^3.0.0"
}
},
"parse-json": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"error-ex": "^1.3.1",
"json-parse-even-better-errors": "^2.3.0",
"lines-and-columns": "^1.1.6"
}
},
"parse-ms": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-3.0.0.tgz",
@ -12029,6 +12441,12 @@
}
}
},
"pluralize": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz",
"integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==",
"dev": true
},
"prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@ -12095,6 +12513,82 @@
"safe-buffer": "^5.1.0"
}
},
"read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
"integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
"dev": true,
"requires": {
"@types/normalize-package-data": "^2.4.0",
"normalize-package-data": "^2.5.0",
"parse-json": "^5.0.0",
"type-fest": "^0.6.0"
},
"dependencies": {
"type-fest": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
"integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
"dev": true
}
}
},
"read-pkg-up": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
"integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
"dev": true,
"requires": {
"find-up": "^4.1.0",
"read-pkg": "^5.2.0",
"type-fest": "^0.8.1"
},
"dependencies": {
"find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
"requires": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
}
},
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
"requires": {
"p-locate": "^4.1.0"
}
},
"p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
}
},
"p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
"requires": {
"p-limit": "^2.2.0"
}
},
"type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"dev": true
}
}
},
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
@ -12139,6 +12633,12 @@
"regenerate": "^1.4.0"
}
},
"regexp-tree": {
"version": "0.1.24",
"resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz",
"integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==",
"dev": true
},
"regexp.prototype.flags": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
@ -12428,6 +12928,15 @@
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
},
"safe-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz",
"integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==",
"dev": true,
"requires": {
"regexp-tree": "~0.1.1"
}
},
"safe-regex-test": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
@ -12639,6 +13148,16 @@
"spdx-ranges": "^2.0.0"
}
},
"spdx-correct": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
"integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
"dev": true,
"requires": {
"spdx-expression-parse": "^3.0.0",
"spdx-license-ids": "^3.0.0"
}
},
"spdx-exceptions": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
@ -12787,6 +13306,15 @@
"integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
"dev": true
},
"strip-indent": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
"integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
"dev": true,
"requires": {
"min-indent": "^1.0.0"
}
},
"strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@ -13074,6 +13602,16 @@
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"dev": true
},
"validate-npm-package-license": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
"integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
"dev": true,
"requires": {
"spdx-correct": "^3.0.0",
"spdx-expression-parse": "^3.0.0"
}
},
"walk-sync": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-2.2.0.tgz",

@ -87,6 +87,7 @@
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-unicorn": "^44.0.2",
"fixturify": "^2.1.1",
"fs-extra": "^10.1.0",
"github-api": "^3.4.0",

@ -24,6 +24,7 @@ const onwarn: WarningHandlerWithDefault = warning => {
'Building Rollup produced warnings that need to be resolved. ' +
'Please keep in mind that the browser build may never have external dependencies!'
);
// eslint-disable-next-line unicorn/error-message
throw Object.assign(new Error(), warning);
};

@ -1,11 +1,11 @@
import { promises as fs } from 'node:fs';
import { resolve } from 'node:path';
export async function findConfigFileName(targetDir) {
const filesInWorkingDir = new Set(await fs.readdir(targetDir));
export async function findConfigFileName(targetDirectory) {
const filesInWorkingDirectory = new Set(await fs.readdir(targetDirectory));
for (const extension of ['mjs', 'cjs', 'ts', 'js']) {
const fileName = `rollup.config.${extension}`;
if (filesInWorkingDir.has(fileName)) return resolve(targetDir, fileName);
if (filesInWorkingDirectory.has(fileName)) return resolve(targetDirectory, fileName);
}
throw new Error('The repository needs to have a file "rollup.config.js" at the top level.');
}

@ -1,12 +1,12 @@
import { spawn } from 'node:child_process';
import { bold, cyan, green } from './colors.js';
export function runWithEcho(command, args, options) {
export function runWithEcho(command, parameters, options) {
return new Promise((resolve, reject) => {
const cmdString = formatCommand(command, args);
const cmdString = formatCommand(command, parameters);
console.error(bold(`\n${cyan`Run>`} ${cmdString}`));
const childProcess = spawn(command, args, options);
const childProcess = spawn(command, parameters, options);
childProcess.stdout.pipe(process.stdout);
childProcess.stderr.pipe(process.stderr);
@ -22,9 +22,9 @@ export function runWithEcho(command, args, options) {
});
}
export function runAndGetStdout(command, args) {
export function runAndGetStdout(command, parameters) {
return new Promise((resolve, reject) => {
const childProcess = spawn(command, args);
const childProcess = spawn(command, parameters);
let stdout = '';
childProcess.stderr.pipe(process.stderr);
@ -32,7 +32,7 @@ export function runAndGetStdout(command, args) {
childProcess.on('close', code => {
if (code) {
reject(new Error(`"${formatCommand(command, args)}" exited with code ${code}.`));
reject(new Error(`"${formatCommand(command, parameters)}" exited with code ${code}.`));
} else {
resolve(stdout.trim());
}
@ -40,6 +40,6 @@ export function runAndGetStdout(command, args) {
});
}
function formatCommand(command, args) {
return [command, ...args].join(' ');
function formatCommand(command, parameters) {
return [command, ...parameters].join(' ');
}

@ -7,7 +7,7 @@ import { findConfigFileName } from './find-config.js';
import { runWithEcho } from './helpers.js';
const TARGET_DIR = fileURLToPath(new URL('../perf', import.meta.url).href);
const VALID_REPO = /^([^/\s#]+\/[^/\s#]+)(#([^/\s#]+))?$/;
const VALID_REPO = /^([^\s#/]+\/[^\s#/]+)(#([^\s#/]+))?$/;
const repoWithBranch = argv[2];
if (argv.length !== 3 || !VALID_REPO.test(repoWithBranch)) {
@ -23,15 +23,15 @@ fs.removeSync(TARGET_DIR);
const [, repo, , branch] = VALID_REPO.exec(repoWithBranch);
const gitArgs = ['clone', '--depth', 1, '--progress'];
const gitArguments = ['clone', '--depth', 1, '--progress'];
if (branch) {
console.error(`Cloning branch "${branch}" of "${repo}"...`);
gitArgs.push('--branch', branch);
gitArguments.push('--branch', branch);
} else {
console.error(`Cloning "${repo}"...`);
}
gitArgs.push(`https://github.com/${repo}.git`, TARGET_DIR);
await runWithEcho('git', gitArgs);
gitArguments.push(`https://github.com/${repo}.git`, TARGET_DIR);
await runWithEcho('git', gitArguments);
await findConfigFileName(TARGET_DIR);
chdir(TARGET_DIR);
await runWithEcho('npm', ['install']);

@ -10,15 +10,15 @@ import { loadConfigFile } from '../dist/loadConfigFile.js';
import { rollup } from '../dist/rollup.js';
import { findConfigFileName } from './find-config.js';
const initialDir = cwd();
const targetDir = fileURLToPath(new URL('../perf', import.meta.url).href);
const initialDirectory = cwd();
const targetDirectory = fileURLToPath(new URL('../perf', import.meta.url).href);
const perfFile = fileURLToPath(new URL('../perf/rollup.perf.json', import.meta.url).href);
const { bold, underline, cyan, red, green } = createColors();
const MIN_ABSOLUTE_TIME_DEVIATION = 10;
const RELATIVE_DEVIATION_FOR_COLORING = 5;
chdir(targetDir);
const configFile = await findConfigFileName(targetDir);
chdir(targetDirectory);
const configFile = await findConfigFileName(targetDirectory);
const configs = await loadConfigFile(
configFile,
configFile.endsWith('.ts') ? { configPlugin: 'typescript' } : {}
@ -64,7 +64,7 @@ function getSingleAverage(times, runs, discarded) {
function getAverage(accumulatedMeasurements, runs, discarded) {
const average = {};
Object.keys(accumulatedMeasurements).forEach(label => {
for (const label of Object.keys(accumulatedMeasurements)) {
average[label] = {
memory: getSingleAverage(
accumulatedMeasurements[label].map(timing => timing[2]),
@ -77,15 +77,15 @@ function getAverage(accumulatedMeasurements, runs, discarded) {
discarded
)
};
});
}
return average;
}
async function calculatePrintAndPersistTimings(config, existingTimings) {
const timings = await buildAndGetTimings(config);
Object.keys(timings).forEach(label => {
for (const label of Object.keys(timings)) {
timings[label] = [timings[label]];
});
}
for (let currentRun = 1; currentRun < numberOfRunsToAverage; currentRun++) {
const numberOfLinesToClear = printMeasurements(
getAverage(timings, currentRun, numberOfDiscardedResults),
@ -95,13 +95,13 @@ async function calculatePrintAndPersistTimings(config, existingTimings) {
console.info(`Completed run ${currentRun}.`);
const currentTimings = await buildAndGetTimings(config);
clearLines(numberOfLinesToClear);
Object.keys(timings).forEach(label => {
for (const label of Object.keys(timings)) {
if (!currentTimings.hasOwnProperty(label)) {
delete timings[label];
} else {
timings[label].push(currentTimings[label]);
}
});
}
}
const averageTimings = getAverage(timings, numberOfRunsToAverage, numberOfDiscardedResults);
printMeasurements(averageTimings, existingTimings);
@ -114,9 +114,9 @@ async function buildAndGetTimings(config) {
config.output = config.output[0];
}
gc();
chdir(targetDir);
chdir(targetDirectory);
const bundle = await rollup(config);
chdir(initialDir);
chdir(initialDirectory);
await bundle.generate(config.output);
return bundle.getTimings();
}
@ -124,8 +124,8 @@ async function buildAndGetTimings(config) {
function printMeasurements(average, existingAverage, filter = /.*/) {
const printedLabels = Object.keys(average).filter(label => filter.test(label));
console.info('');
printedLabels.forEach(label => {
let color = text => text;
for (const label of printedLabels) {
let color = identity;
if (label[0] === '#') {
color = bold;
if (label[1] !== '#') {
@ -143,7 +143,7 @@ function printMeasurements(average, existingAverage, filter = /.*/) {
)}`
)
);
});
}
return printedLabels.length + 2;
}
@ -158,7 +158,7 @@ function getExistingTimings() {
bold(`Comparing with ${cyan(perfFile)}. Delete this file to create a new base line.`)
);
return timings;
} catch (e) {
} catch {
return {};
}
}
@ -167,14 +167,14 @@ function persistTimings(timings) {
try {
writeFileSync(perfFile, JSON.stringify(timings, null, 2), 'utf8');
console.info(bold(`Saving performance information to new reference file ${cyan(perfFile)}.`));
} catch (e) {
} catch {
console.error(bold(`Could not persist performance information in ${cyan(perfFile)}.`));
exit(1);
}
}
function getFormattedTime(currentTime, persistedTime = currentTime) {
let color = text => text,
let color = identity,
formattedTime = `${currentTime.toFixed(0)}ms`;
const absoluteDeviation = Math.abs(currentTime - persistedTime);
if (absoluteDeviation > MIN_ABSOLUTE_TIME_DEVIATION) {
@ -191,7 +191,7 @@ function getFormattedTime(currentTime, persistedTime = currentTime) {
}
function getFormattedMemory(currentMemory, persistedMemory = currentMemory) {
let color = text => text,
let color = identity,
formattedMemory = prettyBytes(currentMemory);
const absoluteDeviation = Math.abs(currentMemory - persistedMemory);
const sign = currentMemory >= persistedMemory ? '+' : '-';
@ -202,3 +202,5 @@ function getFormattedMemory(currentMemory, persistedMemory = currentMemory) {
}
return color(formattedMemory);
}
const identity = x => x;

@ -1,6 +1,6 @@
#!/usr/bin/env node
import { readFile, writeFile } from 'fs/promises';
import { readFile, writeFile } from 'node:fs/promises';
import { chdir, exit } from 'node:process';
import { fileURLToPath } from 'node:url';
import GitHub from 'github-api';
@ -24,7 +24,7 @@ const [gh, currentBranch] = await Promise.all([
runAndGetStdout('git', ['branch', '--show-current']),
runWithEcho('git', ['pull', '--ff-only'])
]);
const [pkg, browserPkg, repo, issues, changelog] = await Promise.all([
const [package_, browserPackage, repo, issues, changelog] = await Promise.all([
readJson(MAIN_PKG),
readJson(BROWSER_PKG),
gh.getRepo('rollup', 'rollup'),
@ -33,7 +33,7 @@ const [pkg, browserPkg, repo, issues, changelog] = await Promise.all([
]);
const isMainBranch = currentBranch === MAIN_BRANCH;
const [newVersion, includedPRs] = await Promise.all([
getNewVersion(pkg, isMainBranch),
getNewVersion(package_, isMainBranch),
getIncludedPRs(changelog, repo)
]);
@ -42,15 +42,15 @@ try {
if (isMainBranch) {
await addStubChangelogEntry(newVersion, repo, changelog, includedPRs);
}
await updatePackages(pkg, browserPkg, newVersion);
await updatePackages(package_, browserPackage, newVersion);
await installDependenciesBuildAndTest();
changelogEntry = isMainBranch ? await waitForChangelogUpdate(newVersion) : '';
gitTag = `v${newVersion}`;
await commitChanges(newVersion, gitTag, isMainBranch);
} catch (err) {
console.error(`Error during release, rolling back changes: ${err.message}`);
} catch (error) {
console.error(`Error during release, rolling back changes: ${error.message}`);
await runWithEcho('git', ['reset', '--hard']);
throw err;
throw error;
}
await releasePackages(newVersion);
@ -65,15 +65,15 @@ async function getGithubApi() {
try {
const token = (await readFile(GITHUB_TOKEN, 'utf8')).trim();
return new GitHub({ token });
} catch (err) {
if (err.code === 'ENOENT') {
} catch (error) {
if (error.code === 'ENOENT') {
console.error(
`Could not find GitHub token file. Please create "${GITHUB_TOKEN}" containing a token with the following permissions:
- public_repo`
);
exit(1);
} else {
throw err;
throw error;
}
}
}
@ -83,8 +83,8 @@ async function readJson(file) {
return JSON.parse(content);
}
async function getNewVersion(pkg, isMainBranch) {
const { version } = pkg;
async function getNewVersion(package_, isMainBranch) {
const { version } = package_;
const availableIncrements = isMainBranch
? ['patch', 'minor']
: semverPreRelease(version)
@ -135,7 +135,7 @@ breaking changes in the release while the tests are running.`)
function getFirstChangelogEntry(changelog) {
const match = changelog.match(
/(?<text>## (?<currentVersion>\d+\.\d+\.\d+)[\s\S]*?)\n+## (?<previousVersion>\d+\.\d+\.\d+)/
/(?<text>## (?<currentVersion>\d+\.\d+\.\d+)[\S\s]*?)\n+## (?<previousVersion>\d+\.\d+\.\d+)/
);
if (!match) {
throw new Error('Could not detect any changelog entry.');
@ -165,8 +165,8 @@ async function getIncludedPRs(changelog, repo) {
return Promise.all(
prs.map(async ({ pr, text }) => {
const { data } = await repo.getPullRequest(pr);
const bodyWithoutComments = data.body.replace(/<!--[\s\S]*?-->/g, '');
const closedIssuesRegexp = /([Ff]ix(es|ed)?|([Cc]lose|[Rr]esolve)[sd]?) #(\d+)/g;
const bodyWithoutComments = data.body.replace(/<!--[\S\s]*?-->/g, '');
const closedIssuesRegexp = /([Ff]ix(es|ed)?|([Cc]lose|[Rr]esolve)[ds]?) #(\d+)/g;
const closed = [];
while ((match = closedIssuesRegexp.exec(bodyWithoutComments))) {
closed.push(match[4]);
@ -268,15 +268,15 @@ async function waitForChangelogUpdate(version) {
return changelogEntry;
}
function updatePackages(pkg, browserPkg, newVersion) {
function updatePackages(package_, browserPackage, newVersion) {
return Promise.all([
writeFile(MAIN_PKG, getPkgStringWithVersion(pkg, newVersion)),
writeFile(BROWSER_PKG, getPkgStringWithVersion(browserPkg, newVersion))
writeFile(MAIN_PKG, getPackageStringWithVersion(package_, newVersion)),
writeFile(BROWSER_PKG, getPackageStringWithVersion(browserPackage, newVersion))
]);
}
function getPkgStringWithVersion(pkg, version) {
return JSON.stringify({ ...pkg, version }, null, 2) + '\n';
function getPackageStringWithVersion(package_, version) {
return JSON.stringify({ ...package_, version }, null, 2) + '\n';
}
async function commitChanges(newVersion, gitTag, isMainBranch) {
@ -286,17 +286,17 @@ async function commitChanges(newVersion, gitTag, isMainBranch) {
}
function releasePackages(newVersion) {
const releaseEnv = { ...process.env, ROLLUP_RELEASE: 'releasing' };
const releaseEnvironment = { ...process.env, ROLLUP_RELEASE: 'releasing' };
const releaseTag = semverPreRelease(newVersion) ? ['--tag', 'beta'] : [];
const args = ['publish', '--access', 'public', ...releaseTag];
const parameters = ['publish', '--access', 'public', ...releaseTag];
return Promise.all([
runWithEcho('npm', args, {
runWithEcho('npm', parameters, {
cwd: new URL('..', import.meta.url),
env: releaseEnv
env: releaseEnvironment
}),
runWithEcho('npm', args, {
runWithEcho('npm', parameters, {
cwd: new URL('../browser', import.meta.url),
env: releaseEnv
env: releaseEnvironment
})
]);
}

@ -1,14 +1,14 @@
import { readFile } from 'node:fs/promises';
const pkg = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8'));
const chokidarPkg = JSON.parse(
const package_ = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8'));
const chokidarPackage = JSON.parse(
await readFile(new URL('../node_modules/chokidar/package.json', import.meta.url), 'utf8')
);
const chokidarFsevents =
chokidarPkg.dependencies.fsevents || chokidarPkg.optionalDependencies.fsevents;
const pkgFsevents = pkg.optionalDependencies.fsevents;
if (chokidarFsevents !== pkgFsevents) {
chokidarPackage.dependencies.fsevents || chokidarPackage.optionalDependencies.fsevents;
const packageFsevents = package_.optionalDependencies.fsevents;
if (chokidarFsevents !== packageFsevents) {
throw new Error(
`The dependency "fsevents" should exist with the same version range "${chokidarFsevents}" as it has for chokidar but it has "${pkgFsevents}".`
`The dependency "fsevents" should exist with the same version range "${chokidarFsevents}" as it has for chokidar but it has "${packageFsevents}".`
);
}

@ -8,12 +8,12 @@ import fs from 'fs-extra';
const basePath = resolve(dirname(fileURLToPath(import.meta.url)), '../test');
const formPath = join(basePath, 'form/samples');
const formDirsToHandle = readdirSync(formPath);
for (const dir of formDirsToHandle) {
const testPath = join(formPath, dir);
const formDirectoriesToHandle = readdirSync(formPath);
for (const directory of formDirectoriesToHandle) {
const testPath = join(formPath, directory);
const testFiles = readdirSync(testPath);
if (!testFiles.includes('_config.js')) {
formDirsToHandle.push(...testFiles.map(filename => join(dir, filename)));
formDirectoriesToHandle.push(...testFiles.map(filename => join(directory, filename)));
} else if (testFiles.includes('_actual')) {
const expectedPath = join(testPath, '_expected');
fs.removeSync(expectedPath);
@ -26,12 +26,12 @@ for (const dir of formDirsToHandle) {
}
const chunkingPath = join(basePath, 'chunking-form/samples');
const chunkingDirsToHandle = readdirSync(chunkingPath);
for (const dir of chunkingDirsToHandle) {
const testPath = join(chunkingPath, dir);
const chunkingDirectoriesToHandle = readdirSync(chunkingPath);
for (const directory of chunkingDirectoriesToHandle) {
const testPath = join(chunkingPath, directory);
const testFiles = readdirSync(testPath);
if (!testFiles.includes('_config.js')) {
chunkingDirsToHandle.push(...testFiles.map(filename => join(dir, filename)));
chunkingDirectoriesToHandle.push(...testFiles.map(filename => join(directory, filename)));
} else if (testFiles.includes('_actual')) {
const expectedPath = join(testPath, '_expected');
fs.removeSync(expectedPath);

@ -14,10 +14,10 @@ import type { PluginDriver } from './utils/PluginDriver';
import { getChunkAssignments } from './utils/chunkAssignment';
import commondir from './utils/commondir';
import {
errCannotAssignModuleToChunk,
errChunkInvalid,
errInvalidOption,
error
error,
errorCannotAssignModuleToChunk,
errorChunkInvalid,
errorInvalidOption
} from './utils/error';
import { sortByExecutionOrder } from './utils/executionOrder';
import { getGenerateCodeSnippets } from './utils/generateCodeSnippets';
@ -74,9 +74,9 @@ export default class Bundle {
this.outputOptions,
this.inputOptions.onwarn
);
} catch (err: any) {
await this.pluginDriver.hookParallel('renderError', [err]);
throw err;
} catch (error_: any) {
await this.pluginDriver.hookParallel('renderError', [error_]);
throw error_;
}
timeStart('generate bundle', 2);
@ -112,6 +112,7 @@ export default class Bundle {
}
private assignManualChunks(getManualChunk: GetManualChunk): Map<Module, string> {
// eslint-disable-next-line unicorn/prefer-module
const manualChunkAliasesWithEntry: [alias: string, module: Module][] = [];
const manualChunksApi = {
getModuleIds: () => this.graph.modulesById.keys(),
@ -144,8 +145,8 @@ export default class Bundle {
allowHashBang: true,
ecmaVersion: 'latest'
});
} catch (err: any) {
this.inputOptions.onwarn(errChunkInvalid(file, err));
} catch (error_: any) {
this.inputOptions.onwarn(errorChunkInvalid(file, error_));
}
}
}
@ -214,7 +215,7 @@ function validateOptionsForMultiChunkOutput(
) {
if (outputOptions.format === 'umd' || outputOptions.format === 'iife')
return error(
errInvalidOption(
errorInvalidOption(
'output.format',
'outputformat',
'UMD and IIFE output formats are not supported for code-splitting builds',
@ -223,7 +224,7 @@ function validateOptionsForMultiChunkOutput(
);
if (typeof outputOptions.file === 'string')
return error(
errInvalidOption(
errorInvalidOption(
'output.file',
'outputdir',
'when building multiple chunks, the "output.dir" option must be used, not "output.file". To inline dynamic imports, set the "inlineDynamicImports" option'
@ -231,7 +232,7 @@ function validateOptionsForMultiChunkOutput(
);
if (outputOptions.sourcemapFile)
return error(
errInvalidOption(
errorInvalidOption(
'output.sourcemapFile',
'outputsourcemapfile',
'"output.sourcemapFile" is only supported for single-file builds'
@ -239,7 +240,7 @@ function validateOptionsForMultiChunkOutput(
);
if (!outputOptions.amd.autoId && outputOptions.amd.id)
onWarn(
errInvalidOption(
errorInvalidOption(
'output.amd.id',
'outputamd',
'this option is only properly supported for single-file builds. Use "output.amd.autoId" and "output.amd.basePath" instead'
@ -294,7 +295,7 @@ function addModuleToManualChunk(
): void {
const existingAlias = manualChunkAliasByEntry.get(module);
if (typeof existingAlias === 'string' && existingAlias !== alias) {
return error(errCannotAssignModuleToChunk(module.id, alias, existingAlias));
return error(errorCannotAssignModuleToChunk(module.id, alias, existingAlias));
}
manualChunkAliasByEntry.set(module, alias);
}

@ -29,12 +29,12 @@ import type { PluginDriver } from './utils/PluginDriver';
import { createAddons } from './utils/addons';
import { deconflictChunk, type DependenciesToBeDeconflicted } from './utils/deconflictChunk';
import {
errCyclicCrossChunkReexport,
errEmptyChunk,
errMissingGlobalName,
error,
errUnexpectedNamedImport,
errUnexpectedNamespaceReexport
errorCyclicCrossChunkReexport,
errorEmptyChunk,
errorMissingGlobalName,
errorUnexpectedNamedImport,
errorUnexpectedNamespaceReexport
} from './utils/error';
import { escapeId } from './utils/escapeId';
import { assignExportsToMangledNames, assignExportsToNames } from './utils/exportNames';
@ -128,7 +128,16 @@ interface FacadeName {
type RenderedDependencies = Map<Chunk | ExternalChunk, ChunkDependency>;
const NON_ASSET_EXTENSIONS = ['.js', '.jsx', '.ts', '.tsx', '.mjs', '.mts', '.cjs', '.cts'];
const NON_ASSET_EXTENSIONS = new Set([
'.js',
'.jsx',
'.ts',
'.tsx',
'.mjs',
'.mts',
'.cjs',
'.cts'
]);
function getGlobalName(
chunk: ExternalChunk,
@ -142,7 +151,7 @@ function getGlobalName(
}
if (hasExports) {
warn(errMissingGlobalName(chunk.id, chunk.variableName));
warn(errorMissingGlobalName(chunk.id, chunk.variableName));
return chunk.variableName;
}
}
@ -353,6 +362,7 @@ export default class Chunk {
}
}
for (const module of entryModules) {
// eslint-disable-next-line unicorn/prefer-spread
const requiredFacades: FacadeName[] = Array.from(
new Set(
module.chunkNames.filter(({ isUserDefined }) => isUserDefined).map(({ name }) => name)
@ -365,6 +375,7 @@ export default class Chunk {
if (requiredFacades.length === 0 && module.isUserDefinedEntryPoint) {
requiredFacades.push({});
}
// eslint-disable-next-line unicorn/prefer-spread
requiredFacades.push(...Array.from(module.chunkFileNames, fileName => ({ fileName })));
if (requiredFacades.length === 0) {
requiredFacades.push({});
@ -373,7 +384,7 @@ export default class Chunk {
const needsStrictFacade =
module.preserveSignature === 'strict' ||
(module.preserveSignature === 'exports-only' &&
module.getExportNamesByVariable().size !== 0);
module.getExportNamesByVariable().size > 0);
if (
!needsStrictFacade ||
this.outputOptions.preserveModules ||
@ -468,7 +479,7 @@ export default class Chunk {
}
getExportNames(): string[] {
return (this.sortedExportNames ??= Array.from(this.exportsByName.keys()).sort());
return (this.sortedExportNames ??= [...this.exportsByName.keys()].sort());
}
getFileName(): string {
@ -527,16 +538,17 @@ export default class Chunk {
if (this.renderedChunkInfo) {
return this.renderedChunkInfo;
}
const resolveFileName = (dependency: Chunk | ExternalChunk): string => dependency.getFileName();
return (this.renderedChunkInfo = {
...this.getPreRenderedChunkInfo(),
dynamicImports: this.getDynamicDependencies().map(resolveFileName),
fileName: this.getFileName(),
// eslint-disable-next-line unicorn/prefer-spread
implicitlyLoadedBefore: Array.from(this.implicitlyLoadedBefore, resolveFileName),
importedBindings: getImportedBindingsPerDependency(
this.getRenderedDependencies(),
resolveFileName
),
// eslint-disable-next-line unicorn/prefer-spread
imports: Array.from(this.dependencies, resolveFileName),
modules: this.renderedModules,
referencedFiles: this.getReferencedFiles()
@ -589,7 +601,7 @@ export default class Chunk {
const renderedDependencies = [...this.getRenderedDependencies().values()];
const renderedExports = exportMode === 'none' ? [] : this.getChunkExportDeclarations(format);
let hasExports = renderedExports.length !== 0;
let hasExports = renderedExports.length > 0;
let hasDefaultExport = false;
for (const { reexports } of renderedDependencies) {
if (reexports?.length) {
@ -647,9 +659,9 @@ export default class Chunk {
}
private addImplicitlyLoadedBeforeFromModule(baseModule: Module): void {
const { implicitlyLoadedBefore } = this;
const { chunkByModule, implicitlyLoadedBefore } = this;
for (const module of baseModule.implicitlyLoadedBefore) {
const chunk = this.chunkByModule.get(module);
const chunk = chunkByModule.get(module);
if (chunk && chunk !== this) {
implicitlyLoadedBefore.add(chunk);
}
@ -694,7 +706,7 @@ export default class Chunk {
const exportingChunk = this.chunkByModule.get(alternativeReexportModule);
if (exportingChunk && exportingChunk !== exportChunk) {
this.inputOptions.onwarn(
errCyclicCrossChunkReexport(
errorCyclicCrossChunkReexport(
variableModule.getExportNamesByVariable().get(variable)![0],
variableModule.id,
alternativeReexportModule.id,
@ -731,7 +743,7 @@ export default class Chunk {
}
}
}
if (includedReexports.length) {
if (includedReexports.length > 0) {
this.includedReexportsByModule.set(module, includedReexports);
}
}
@ -811,10 +823,11 @@ export default class Chunk {
if (defaultInteropHelpersByInteropType[interop(module.id)]) {
deconflictedDefault.add(chunk);
}
} else if (variable.name === '*') {
if (namespaceInteropHelpersByInteropType[interop(module.id)]) {
deconflictedNamespace.add(chunk);
}
} else if (
variable.name === '*' &&
namespaceInteropHelpersByInteropType[interop(module.id)]
) {
deconflictedNamespace.add(chunk);
}
}
} else {
@ -894,7 +907,7 @@ export default class Chunk {
dependency = this.externalChunkByModule.get(module)!;
imported = variable.name;
if (imported !== 'default' && imported !== '*' && interop(module.id) === 'defaultOnly') {
return error(errUnexpectedNamedImport(module.id, imported, false));
return error(errorUnexpectedNamedImport(module.id, imported, false));
}
} else {
dependency = this.chunkByModule.get(module)!;
@ -946,14 +959,14 @@ export default class Chunk {
if (this.preRenderedChunkInfo) {
return this.preRenderedChunkInfo;
}
const { facadeModule } = this;
const { dynamicEntryModules, facadeModule, implicitEntryModules, orderedModules } = this;
return (this.preRenderedChunkInfo = {
exports: this.getExportNames(),
facadeModuleId: facadeModule && facadeModule.id,
isDynamicEntry: this.dynamicEntryModules.length > 0,
isDynamicEntry: dynamicEntryModules.length > 0,
isEntry: !!facadeModule?.info.isEntry,
isImplicitEntry: this.implicitEntryModules.length > 0,
moduleIds: this.orderedModules.map(({ id }) => id),
isImplicitEntry: implicitEntryModules.length > 0,
moduleIds: orderedModules.map(({ id }) => id),
name: this.getChunkName(),
type: 'chunk'
});
@ -964,13 +977,13 @@ export default class Chunk {
if (predefinedChunkName) return predefinedChunkName;
const { preserveModulesRoot, sanitizeFileName } = this.outputOptions;
const sanitizedId = sanitizeFileName(module.id.split(QUERY_HASH_REGEX, 1)[0]);
const extName = extname(sanitizedId);
const idWithoutExtension = NON_ASSET_EXTENSIONS.includes(extName)
? sanitizedId.slice(0, -extName.length)
const extensionName = extname(sanitizedId);
const idWithoutExtension = NON_ASSET_EXTENSIONS.has(extensionName)
? sanitizedId.slice(0, -extensionName.length)
: sanitizedId;
if (isAbsolute(idWithoutExtension)) {
return preserveModulesRoot && resolve(idWithoutExtension).startsWith(preserveModulesRoot)
? idWithoutExtension.slice(preserveModulesRoot.length).replace(/^[\\/]/, '')
? idWithoutExtension.slice(preserveModulesRoot.length).replace(/^[/\\]/, '')
: relative(this.inputBase, idWithoutExtension);
} else {
return `_virtual/${basename(idWithoutExtension)}`;
@ -985,9 +998,9 @@ export default class Chunk {
let imported: string;
let needsLiveBinding = false;
if (exportName[0] === '*') {
const id = exportName.substring(1);
const id = exportName.slice(1);
if (interop(id) === 'defaultOnly') {
this.inputOptions.onwarn(errUnexpectedNamespaceReexport(id));
this.inputOptions.onwarn(errorUnexpectedNamespaceReexport(id));
}
needsLiveBinding = externalLiveBindings;
dependency = this.externalChunkByModule.get(this.modulesById.get(id) as ExternalModule)!;
@ -1005,7 +1018,7 @@ export default class Chunk {
dependency = this.externalChunkByModule.get(module)!;
imported = variable.name;
if (imported !== 'default' && imported !== '*' && interop(module.id) === 'defaultOnly') {
return error(errUnexpectedNamedImport(module.id, imported, true));
return error(errorUnexpectedNamedImport(module.id, imported, true));
}
needsLiveBinding =
externalLiveBindings &&
@ -1086,6 +1099,7 @@ export default class Chunk {
// This method changes properties on the AST before rendering and must not be async
private renderModules(fileName: string) {
const {
accessedGlobalsByScope,
dependencies,
exportNamesByVariable,
includedNamespaces,
@ -1105,7 +1119,7 @@ export default class Chunk {
namespaceToStringTag,
preserveModules
} = outputOptions;
const { _, n } = snippets;
const { _, cnst, n } = snippets;
this.setDynamicImportResolutions(fileName);
this.setImportMetaResolutions(fileName);
this.setIdentifierRenderResolutions();
@ -1149,7 +1163,7 @@ export default class Chunk {
if (namespace.renderFirst()) hoistedSource += n + rendered;
else magicString.addSource(new MagicString(rendered));
}
const accessedGlobalVariables = this.accessedGlobalsByScope.get(module.scope);
const accessedGlobalVariables = accessedGlobalsByScope.get(module.scope);
if (accessedGlobalVariables) {
for (const name of accessedGlobalVariables) {
accessedGlobals.add(name);
@ -1170,15 +1184,14 @@ export default class Chunk {
if (hoistedSource) magicString.prepend(hoistedSource + n + n);
// eslint-disable-next-line unicorn/consistent-destructuring
if (this.needsExportsShim) {
magicString.prepend(
`${n}${snippets.cnst} ${MISSING_EXPORT_SHIM_VARIABLE}${_}=${_}void 0;${n}${n}`
);
magicString.prepend(`${n}${cnst} ${MISSING_EXPORT_SHIM_VARIABLE}${_}=${_}void 0;${n}${n}`);
}
const renderedSource = compact ? magicString : magicString.trim();
if (isEmpty && this.getExportNames().length === 0 && dependencies.size === 0) {
onwarn(errEmptyChunk(this.getChunkName()));
onwarn(errorEmptyChunk(this.getChunkName()));
}
return { accessedGlobals, indent, magicString, renderedSource, usedModules, usesTopLevelAwait };
}
@ -1204,12 +1217,12 @@ export default class Chunk {
);
}
} else {
const { resolution } = resolvedDynamicImport;
const { node, resolution } = resolvedDynamicImport;
const [resolutionString, assertions] = this.getDynamicImportStringAndAssertions(
resolution,
fileName
);
resolvedDynamicImport.node.setExternalResolution(
node.setExternalResolution(
'external',
resolution,
outputOptions,
@ -1225,7 +1238,8 @@ export default class Chunk {
}
private setIdentifierRenderResolutions() {
const { format, interop, namespaceToStringTag } = this.outputOptions;
const { format, interop, namespaceToStringTag, preserveModules, externalLiveBindings } =
this.outputOptions;
const syntheticExports = new Set<SyntheticNamedExportVariable>();
for (const exportName of this.getExportNames()) {
const exportVariable = this.exportsByName.get(exportName)!;
@ -1256,19 +1270,23 @@ export default class Chunk {
usedNames.add('Symbol');
}
switch (format) {
case 'system':
case 'system': {
usedNames.add('module').add('exports');
break;
case 'es':
}
case 'es': {
break;
case 'cjs':
}
case 'cjs': {
usedNames.add('module').add('require').add('__filename').add('__dirname');
}
// fallthrough
default:
default: {
usedNames.add('exports');
for (const helper of HELPER_NAMES) {
usedNames.add(helper);
}
}
}
deconflictChunk(
@ -1282,8 +1300,8 @@ export default class Chunk {
usedNames,
format,
interop,
this.outputOptions.preserveModules,
this.outputOptions.externalLiveBindings,
preserveModules,
externalLiveBindings,
this.chunkByModule,
this.externalChunkByModule,
syntheticExports,
@ -1297,9 +1315,10 @@ export default class Chunk {
const {
accessedGlobalsByScope,
includedNamespaces,
orderedModules,
outputOptions: { format, preserveModules }
} = this;
for (const module of this.orderedModules) {
for (const module of orderedModules) {
for (const importMeta of module.importMetas) {
importMeta.setResolution(format, accessedGlobalsByScope, fileName);
}
@ -1313,12 +1332,10 @@ export default class Chunk {
const moduleImports = new Set(module.includedImports);
// when we are not preserving modules, we need to make all namespace variables available for
// rendering the namespace object
if (!this.outputOptions.preserveModules) {
if (this.includedNamespaces.has(module)) {
const memberVariables = module.namespace.getMemberVariables();
for (const variable of Object.values(memberVariables)) {
moduleImports.add(variable);
}
if (!this.outputOptions.preserveModules && this.includedNamespaces.has(module)) {
const memberVariables = module.namespace.getMemberVariables();
for (const variable of Object.values(memberVariables)) {
moduleImports.add(variable);
}
}
for (let variable of moduleImports) {
@ -1395,4 +1412,6 @@ function getImportedBindingsPerDependency(
return importedBindingsPerDependency;
}
const QUERY_HASH_REGEX = /[?#]/;
const QUERY_HASH_REGEX = /[#?]/;
const resolveFileName = (dependency: Chunk | ExternalChunk): string => dependency.getFileName();

@ -66,7 +66,7 @@ function formatAssertions(
const assertionEntries: [key: string, value: string][] = Object.entries(assertions).map(
([key, value]) => [key, `'${value}'`]
);
if (assertionEntries.length) {
if (assertionEntries.length > 0) {
return getObject(assertionEntries, { lineBreakIndent: null });
}
return null;

@ -1,7 +1,7 @@
import ExternalVariable from './ast/variables/ExternalVariable';
import type { CustomPluginOptions, ModuleInfo, NormalizedInputOptions } from './rollup/types';
import { EMPTY_ARRAY } from './utils/blank';
import { errUnusedExternalImports, warnDeprecation } from './utils/error';
import { errorUnusedExternalImports, warnDeprecation } from './utils/error';
import { makeLegal } from './utils/identifierHelpers';
export default class ExternalModule {
@ -26,7 +26,7 @@ export default class ExternalModule {
public readonly renormalizeRenderPath: boolean,
assertions: Record<string, string>
) {
this.suggestedVariableName = makeLegal(id.split(/[\\/]/).pop()!);
this.suggestedVariableName = makeLegal(id.split(/[/\\]/).pop()!);
const { importers, dynamicImporters } = this;
const info: ModuleInfo = (this.info = {
@ -89,7 +89,7 @@ export default class ExternalModule {
}
warnUnusedImports(): void {
const unused = Array.from(this.declarations)
const unused = [...this.declarations]
.filter(
([name, declaration]) =>
name !== '*' && !declaration.included && !this.reexported && !declaration.referenced
@ -105,6 +105,6 @@ export default class ExternalModule {
}
}
const importersArray = [...importersSet];
this.options.onwarn(errUnusedExternalImports(this.id, unused, importersArray));
this.options.onwarn(errorUnusedExternalImports(this.id, unused, importersArray));
}
}

@ -17,10 +17,10 @@ import { PluginDriver } from './utils/PluginDriver';
import Queue from './utils/Queue';
import { BuildPhase } from './utils/buildPhase';
import {
errCircularDependency,
errImplicitDependantIsNotIncluded,
errMissingExport,
error
error,
errorCircularDependency,
errorImplicitDependantIsNotIncluded,
errorMissingExport
} from './utils/error';
import { analyseModuleExecution } from './utils/executionOrder';
import { addAnnotations } from './utils/pureComments';
@ -84,8 +84,8 @@ export default class Graph {
if (watcher) {
this.watchMode = true;
const handleChange = (...args: Parameters<WatchChangeHook>) =>
this.pluginDriver.hookParallel('watchChange', args);
const handleChange = (...parameters: Parameters<WatchChangeHook>) =>
this.pluginDriver.hookParallel('watchChange', parameters);
const handleClose = () => this.pluginDriver.hookParallel('closeWatcher', []);
watcher.onCurrentRun('change', handleChange);
watcher.onCurrentRun('close', handleClose);
@ -117,14 +117,13 @@ export default class Graph {
const onCommentOrig = options.onComment;
const comments: acorn.Comment[] = [];
if (onCommentOrig && typeof onCommentOrig == 'function') {
options.onComment = (block, text, start, end, ...args) => {
comments.push({ end, start, type: block ? 'Block' : 'Line', value: text });
return onCommentOrig.call(options, block, text, start, end, ...args);
};
} else {
options.onComment = comments;
}
options.onComment =
onCommentOrig && typeof onCommentOrig == 'function'
? (block, text, start, end, ...parameters) => {
comments.push({ end, start, type: block ? 'Block' : 'Line', value: text });
return onCommentOrig.call(options, block, text, start, end, ...parameters);
}
: comments;
const ast = this.acornParser.parse(code, {
...(this.options.acorn as unknown as acorn.Options),
@ -218,7 +217,7 @@ export default class Graph {
for (const module of this.implicitEntryModules) {
for (const dependant of module.implicitlyLoadedAfter) {
if (!(dependant.info.isEntry || dependant.isIncluded())) {
error(errImplicitDependantIsNotIncluded(dependant));
error(errorImplicitDependantIsNotIncluded(dependant));
}
}
}
@ -227,7 +226,7 @@ export default class Graph {
private sortModules(): void {
const { orderedModules, cyclePaths } = analyseModuleExecution(this.entryModules);
for (const cyclePath of cyclePaths) {
this.options.onwarn(errCircularDependency(cyclePath));
this.options.onwarn(errorCircularDependency(cyclePath));
}
this.modules = orderedModules;
for (const module of this.modules) {
@ -244,7 +243,7 @@ export default class Graph {
!importDescription.module.getVariableForExportName(importDescription.name)[0]
) {
module.warn(
errMissingExport(importDescription.name, module.id, importDescription.module.id),
errorMissingExport(importDescription.name, module.id, importDescription.module.id),
importDescription.start
);
}

@ -49,17 +49,17 @@ import { EMPTY_OBJECT } from './utils/blank';
import { BuildPhase } from './utils/buildPhase';
import {
augmentCodeLocation,
errAmbiguousExternalNamespaces,
errCircularReexport,
errInconsistentImportAssertions,
errInvalidFormatForTopLevelAwait,
errInvalidSourcemapForError,
errMissingExport,
errNamespaceConflict,
error,
errParseError,
errShimmedExport,
errSyntheticNamedExportsNeedNamespaceExport,
errorAmbiguousExternalNamespaces,
errorCircularReexport,
errorInconsistentImportAssertions,
errorInvalidFormatForTopLevelAwait,
errorInvalidSourcemapForError,
errorMissingExport,
errorNamespaceConflict,
errorParseError,
errorShimmedExport,
errorSyntheticNamedExportsNeedNamespaceExport,
warnDeprecation
} from './utils/error';
import { getId } from './utils/getId';
@ -104,7 +104,7 @@ export interface AstContext {
addImportMeta: (node: MetaProperty) => void;
code: string;
deoptimizationTracker: PathTracker;
error: (props: RollupLog, pos: number) => never;
error: (properties: RollupLog, pos: number) => never;
fileName: string;
getExports: () => string[];
getModuleExecIndex: () => number;
@ -148,7 +148,7 @@ function getVariableForExportNameRecursive(
const searchedModules = searchedNamesAndModules.get(name);
if (searchedModules) {
if (searchedModules.has(target)) {
return isExportAllSearch ? [null] : error(errCircularReexport(name, target.id));
return isExportAllSearch ? [null] : error(errorCircularReexport(name, target.id));
}
searchedModules.add(target);
} else {
@ -313,12 +313,15 @@ export default class Module {
},
id,
get implicitlyLoadedAfterOneOf() {
// eslint-disable-next-line unicorn/prefer-spread
return Array.from(implicitlyLoadedAfter, getId).sort();
},
get implicitlyLoadedBefore() {
// eslint-disable-next-line unicorn/prefer-spread
return Array.from(implicitlyLoadedBefore, getId).sort();
},
get importedIdResolutions() {
// eslint-disable-next-line unicorn/prefer-spread
return Array.from(
sourcesWithAssertions.keys(),
source => module.resolvedIds[source]
@ -327,6 +330,7 @@ export default class Module {
get importedIds() {
// We cannot use this.dependencies because this is needed before
// dependencies are populated
// eslint-disable-next-line unicorn/prefer-spread
return Array.from(
sourcesWithAssertions.keys(),
source => module.resolvedIds[source]?.id
@ -348,6 +352,7 @@ export default class Module {
syntheticNamedExports
};
// Hide the deprecated key so that it only warns when accessed explicitly
// eslint-disable-next-line unicorn/consistent-destructuring
Object.defineProperty(this.info, 'hasModuleSideEffects', {
enumerable: false
});
@ -355,18 +360,18 @@ export default class Module {
basename(): string {
const base = basename(this.id);
const ext = extname(this.id);
const extension = extname(this.id);
return makeLegal(ext ? base.slice(0, -ext.length) : base);
return makeLegal(extension ? base.slice(0, -extension.length) : base);
}
bindReferences(): void {
this.ast!.bind();
}
error(props: RollupError, pos: number): never {
this.addLocationToLogProps(props, pos);
return error(props);
error(properties: RollupError, pos: number): never {
this.addLocationToLogProps(properties, pos);
return error(properties);
}
getAllExportNames(): Set<string> {
@ -471,7 +476,7 @@ export default class Module {
}
getExports(): string[] {
return Array.from(this.exports.keys());
return [...this.exports.keys()];
}
getReexports(): string[] {
@ -518,7 +523,7 @@ export default class Module {
}
if (!this.syntheticNamespace) {
return error(
errSyntheticNamedExportsNeedNamespaceExport(this.id, this.info.syntheticNamedExports)
errorSyntheticNamedExportsNeedNamespaceExport(this.id, this.info.syntheticNamedExports)
);
}
return this.syntheticNamespace;
@ -560,7 +565,7 @@ export default class Module {
);
if (!variable) {
return this.error(
errMissingExport(reexportDeclaration.localName, this.id, reexportDeclaration.module.id),
errorMissingExport(reexportDeclaration.localName, this.id, reexportDeclaration.module.id),
reexportDeclaration.start
);
}
@ -622,11 +627,9 @@ export default class Module {
// we don't want to create shims when we are just
// probing export * modules for exports
if (!isExportAllSearch) {
if (this.options.shimMissingExports) {
this.shimMissingExport(name);
return [this.exportShimVariable];
}
if (!isExportAllSearch && this.options.shimMissingExports) {
this.shimMissingExport(name);
return [this.exportShimVariable];
}
return [null];
}
@ -707,7 +710,7 @@ export default class Module {
source.trim();
const { usesTopLevelAwait } = this.astContext;
if (usesTopLevelAwait && options.format !== 'es' && options.format !== 'system') {
return error(errInvalidFormatForTopLevelAwait(this.id, options.format));
return error(errorInvalidFormatForTopLevelAwait(this.id, options.format));
}
return { source, usesTopLevelAwait };
}
@ -801,6 +804,7 @@ export default class Module {
ast: this.ast!.esTreeNode,
code: this.info.code!,
customTransformCache: this.customTransformCache,
// eslint-disable-next-line unicorn/prefer-spread
dependencies: Array.from(this.dependencies, getId),
id: this.id,
meta: this.info.meta,
@ -850,7 +854,7 @@ export default class Module {
if (!declaration) {
return this.error(
errMissingExport(importDeclaration.name, this.id, otherModule.id),
errorMissingExport(importDeclaration.name, this.id, otherModule.id),
importDeclaration.start
);
}
@ -864,8 +868,8 @@ export default class Module {
tryParse(): acorn.Node {
try {
return this.graph.contextParse(this.info.code!);
} catch (err: any) {
return this.error(errParseError(err, this.id), err.pos);
} catch (error_: any) {
return this.error(errorParseError(error_, this.id), error_.pos);
}
}
@ -885,9 +889,9 @@ export default class Module {
}
}
warn(props: RollupWarning, pos: number): void {
this.addLocationToLogProps(props, pos);
this.options.onwarn(props);
warn(properties: RollupWarning, pos: number): void {
this.addLocationToLogProps(properties, pos);
this.options.onwarn(properties);
}
private addDynamicImport(node: ImportExpression) {
@ -993,9 +997,9 @@ export default class Module {
this.importMetas.push(node);
}
private addLocationToLogProps(props: RollupLog, pos: number): void {
props.id = this.id;
props.pos = pos;
private addLocationToLogProps(properties: RollupLog, pos: number): void {
properties.id = this.id;
properties.pos = pos;
let code = this.info.code;
const location = locate(code!, pos, { offsetLine: 1 });
if (location) {
@ -1003,10 +1007,10 @@ export default class Module {
try {
({ column, line } = getOriginalLocation(this.sourcemapChain, { column, line }));
code = this.originalCode;
} catch (err: any) {
this.options.onwarn(errInvalidSourcemapForError(err, this.id, column, line, pos));
} catch (error_: any) {
this.options.onwarn(errorInvalidSourcemapForError(error_, this.id, column, line, pos));
}
augmentCodeLocation(props, { column, line }, code!, this.id);
augmentCodeLocation(properties, { column, line }, code!, this.id);
}
}
@ -1062,7 +1066,7 @@ export default class Module {
if (existingAssertions) {
if (doAssertionsDiffer(existingAssertions, parsedAssertions)) {
this.warn(
errInconsistentImportAssertions(existingAssertions, parsedAssertions, source, this.id),
errorInconsistentImportAssertions(existingAssertions, parsedAssertions, source, this.id),
declaration.start
);
}
@ -1111,7 +1115,7 @@ export default class Module {
return [usedDeclaration];
}
this.options.onwarn(
errNamespaceConflict(
errorNamespaceConflict(
name,
this.id,
foundDeclarationList.map(([, module]) => module.id)
@ -1125,7 +1129,7 @@ export default class Module {
const usedDeclaration = foundDeclarationList[0];
if (foundDeclarationList.length > 1) {
this.options.onwarn(
errAmbiguousExternalNamespaces(
errorAmbiguousExternalNamespaces(
name,
this.id,
usedDeclaration.module.id,
@ -1202,7 +1206,7 @@ export default class Module {
}
private shimMissingExport(name: string): void {
this.options.onwarn(errShimmedExport(this.id, name));
this.options.onwarn(errorShimmedExport(this.id, name));
this.exports.set(name, MISSING_EXPORT_SHIM_DESCRIPTION);
}
}
@ -1233,4 +1237,5 @@ const copyNameToModulesMap = (
searchedNamesAndModules?: Map<string, Set<Module | ExternalModule>>
): Map<string, Set<Module | ExternalModule>> | undefined =>
searchedNamesAndModules &&
// eslint-disable-next-line unicorn/prefer-spread
new Map(Array.from(searchedNamesAndModules, ([name, modules]) => [name, new Set(modules)]));

@ -18,17 +18,17 @@ import type {
import type { PluginDriver } from './utils/PluginDriver';
import { EMPTY_OBJECT } from './utils/blank';
import {
errBadLoader,
errEntryCannotBeExternal,
errExternalSyntheticExports,
errImplicitDependantCannotBeExternal,
errInconsistentImportAssertions,
errInternalIdCannotBeExternal,
error,
errUnresolvedEntry,
errUnresolvedImplicitDependant,
errUnresolvedImport,
errUnresolvedImportTreatedAsExternal
errorBadLoader,
errorEntryCannotBeExternal,
errorExternalSyntheticExports,
errorImplicitDependantCannotBeExternal,
errorInconsistentImportAssertions,
errorInternalIdCannotBeExternal,
errorUnresolvedEntry,
errorUnresolvedImplicitDependant,
errorUnresolvedImport,
errorUnresolvedImportTreatedAsExternal
} from './utils/error';
import { promises as fs } from './utils/fs';
import { doAssertionsDiffer, getAssertionsFromImportExpression } from './utils/parseAssertions';
@ -119,8 +119,7 @@ export class ModuleLoader {
this.loadEntryModule(id, true, importer, null)
)
).then(entryModules => {
for (let index = 0; index < entryModules.length; index++) {
const entryModule = entryModules[index];
for (const [index, entryModule] of entryModules.entries()) {
entryModule.isUserDefinedEntryPoint =
entryModule.isUserDefinedEntryPoint || isUserDefined;
addChunkNamesToModule(
@ -262,19 +261,19 @@ export class ModuleLoader {
async () =>
(await this.pluginDriver.hookFirst('load', [id])) ?? (await fs.readFile(id, 'utf8'))
);
} catch (err: any) {
let msg = `Could not load ${id}`;
if (importer) msg += ` (imported by ${relativeId(importer)})`;
msg += `: ${err.message}`;
err.message = msg;
throw err;
} catch (error_: any) {
let message = `Could not load ${id}`;
if (importer) message += ` (imported by ${relativeId(importer)})`;
message += `: ${error_.message}`;
error_.message = message;
throw error_;
}
const sourceDescription =
typeof source === 'string'
? { code: source }
: source != null && typeof source === 'object' && typeof source.code === 'string'
? source
: error(errBadLoader(id));
: error(errorBadLoader(id));
const cachedModule = this.graph.cachedModules.get(id);
if (
cachedModule &&
@ -367,7 +366,12 @@ export class ModuleLoader {
if (existingModule instanceof Module) {
if (importer && doAssertionsDiffer(assertions, existingModule.info.assertions)) {
this.options.onwarn(
errInconsistentImportAssertions(existingModule.info.assertions, assertions, id, importer)
errorInconsistentImportAssertions(
existingModule.info.assertions,
assertions,
id,
importer
)
);
}
await this.handleExistingModule(existingModule, isEntry, isPreload);
@ -445,10 +449,10 @@ export class ModuleLoader {
);
this.modulesById.set(id, externalModule);
} else if (!(externalModule instanceof ExternalModule)) {
return error(errInternalIdCannotBeExternal(source, importer));
return error(errorInternalIdCannotBeExternal(source, importer));
} else if (doAssertionsDiffer(externalModule.info.assertions, assertions)) {
this.options.onwarn(
errInconsistentImportAssertions(
errorInconsistentImportAssertions(
externalModule.info.assertions,
assertions,
source,
@ -549,6 +553,7 @@ export class ModuleLoader {
}
private getResolveStaticDependencyPromises(module: Module): ResolveStaticDependencyPromise[] {
// eslint-disable-next-line unicorn/prefer-spread
return Array.from(
module.sourcesWithAssertions,
async ([source, assertions]) =>
@ -611,9 +616,9 @@ export class ModuleLoader {
): ResolvedId {
if (resolvedId === null) {
if (isRelative(source)) {
return error(errUnresolvedImport(source, importer));
return error(errorUnresolvedImport(source, importer));
}
this.options.onwarn(errUnresolvedImportTreatedAsExternal(source, importer));
this.options.onwarn(errorUnresolvedImportTreatedAsExternal(source, importer));
return {
assertions,
external: true,
@ -623,7 +628,7 @@ export class ModuleLoader {
syntheticNamedExports: false
};
} else if (resolvedId.external && resolvedId.syntheticNamedExports) {
this.options.onwarn(errExternalSyntheticExports(source, importer));
this.options.onwarn(errorExternalSyntheticExports(source, importer));
}
return resolvedId;
}
@ -648,8 +653,8 @@ export class ModuleLoader {
if (resolveIdResult == null) {
return error(
implicitlyLoadedBefore === null
? errUnresolvedEntry(unresolvedId)
: errUnresolvedImplicitDependant(unresolvedId, implicitlyLoadedBefore)
? errorUnresolvedEntry(unresolvedId)
: errorUnresolvedImplicitDependant(unresolvedId, implicitlyLoadedBefore)
);
}
if (
@ -658,8 +663,8 @@ export class ModuleLoader {
) {
return error(
implicitlyLoadedBefore === null
? errEntryCannotBeExternal(unresolvedId)
: errImplicitDependantCannotBeExternal(unresolvedId, implicitlyLoadedBefore)
? errorEntryCannotBeExternal(unresolvedId)
: errorImplicitDependantCannotBeExternal(unresolvedId, implicitlyLoadedBefore)
);
}
return this.fetchModule(
@ -703,7 +708,7 @@ export class ModuleLoader {
if (existingResolution) {
if (doAssertionsDiffer(existingResolution.assertions, assertions)) {
this.options.onwarn(
errInconsistentImportAssertions(
errorInconsistentImportAssertions(
existingResolution.assertions,
assertions,
specifier,

@ -54,4 +54,4 @@ export type NodeInteraction =
| NodeInteractionAssigned
| NodeInteractionCalled;
export type NodeInteractionWithThisArg = NodeInteraction & { thisArg: ExpressionEntity };
export type NodeInteractionWithThisArgument = NodeInteraction & { thisArg: ExpressionEntity };

@ -3,7 +3,7 @@ import type { HasEffectsContext } from '../ExecutionContext';
import type {
NodeInteraction,
NodeInteractionCalled,
NodeInteractionWithThisArg
NodeInteractionWithThisArgument
} from '../NodeInteractions';
import {
type ObjectPath,
@ -29,7 +29,7 @@ export default class ArrayExpression extends NodeBase {
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
): void {
@ -71,11 +71,9 @@ export default class ArrayExpression extends NodeBase {
let hasSpread = false;
for (let index = 0; index < this.elements.length; index++) {
const element = this.elements[index];
if (element) {
if (hasSpread || element instanceof SpreadElement) {
hasSpread = true;
element.deoptimizePath(UNKNOWN_PATH);
}
if (element && (hasSpread || element instanceof SpreadElement)) {
hasSpread = true;
element.deoptimizePath(UNKNOWN_PATH);
}
}
this.context.requestTreeshakingPass();

@ -56,9 +56,9 @@ export default class ArrowFunctionExpression extends FunctionBase {
include(context: InclusionContext, includeChildrenRecursively: IncludeChildren): void {
super.include(context, includeChildrenRecursively);
for (const param of this.params) {
if (!(param instanceof Identifier)) {
param.include(context, includeChildrenRecursively);
for (const parameter of this.params) {
if (!(parameter instanceof Identifier)) {
parameter.include(context, includeChildrenRecursively);
}
}
}

@ -46,12 +46,12 @@ export default class AssignmentExpression extends NodeBase {
declare type: NodeType.tAssignmentExpression;
hasEffects(context: HasEffectsContext): boolean {
const { deoptimized, left, right } = this;
const { deoptimized, left, operator, right } = this;
if (!deoptimized) this.applyDeoptimizations();
// MemberExpressions do not access the property before assignments if the
// operator is '='.
return (
right.hasEffects(context) || left.hasEffectsAsAssignmentTarget(context, this.operator !== '=')
right.hasEffects(context) || left.hasEffectsAsAssignmentTarget(context, operator !== '=')
);
}

@ -90,10 +90,10 @@ export default class BinaryExpression extends NodeBase implements DeoptimizableE
const rightValue = this.right.getLiteralValueAtPath(EMPTY_PATH, recursionTracker, origin);
if (typeof rightValue === 'symbol') return UnknownValue;
const operatorFn = binaryOperators[this.operator];
if (!operatorFn) return UnknownValue;
const operatorFunction = binaryOperators[this.operator];
if (!operatorFunction) return UnknownValue;
return operatorFn(leftValue, rightValue);
return operatorFunction(leftValue, rightValue);
}
hasEffects(context: HasEffectsContext): boolean {

@ -58,7 +58,7 @@ export default class BlockStatement extends StatementBase {
}
render(code: MagicString, options: RenderOptions): void {
if (this.body.length) {
if (this.body.length > 0) {
renderStatementList(this.body, code, this.start + 1, this.end - 1, options);
} else {
super.render(code, options);

@ -1,12 +1,12 @@
import type MagicString from 'magic-string';
import type { NormalizedTreeshakingOptions } from '../../rollup/types';
import { BLANK } from '../../utils/blank';
import { errCannotCallNamespace, errEval } from '../../utils/error';
import { errorCannotCallNamespace, errorEval } from '../../utils/error';
import { renderCallArguments } from '../../utils/renderCallArguments';
import { type NodeRenderOptions, type RenderOptions } from '../../utils/renderHelpers';
import type { DeoptimizableEntity } from '../DeoptimizableEntity';
import type { HasEffectsContext, InclusionContext } from '../ExecutionContext';
import type { NodeInteractionWithThisArg } from '../NodeInteractions';
import type { NodeInteractionWithThisArgument } from '../NodeInteractions';
import { INTERACTION_CALLED } from '../NodeInteractions';
import {
EMPTY_PATH,
@ -35,11 +35,11 @@ export default class CallExpression extends CallExpressionBase implements Deopti
const variable = this.scope.findVariable(this.callee.name);
if (variable.isNamespace) {
this.context.warn(errCannotCallNamespace(this.callee.name), this.start);
this.context.warn(errorCannotCallNamespace(this.callee.name), this.start);
}
if (this.callee.name === 'eval') {
this.context.warn(errEval(this.context.module.id), this.start);
this.context.warn(errorEval(this.context.module.id), this.start);
}
}
this.interaction = {
@ -106,7 +106,7 @@ export default class CallExpression extends CallExpressionBase implements Deopti
this.deoptimized = true;
if (this.interaction.thisArg) {
this.callee.deoptimizeThisOnInteractionAtPath(
this.interaction as NodeInteractionWithThisArg,
this.interaction as NodeInteractionWithThisArgument,
EMPTY_PATH,
SHARED_RECURSION_TRACKER
);

@ -12,7 +12,7 @@ import type { HasEffectsContext, InclusionContext } from '../ExecutionContext';
import type {
NodeInteraction,
NodeInteractionCalled,
NodeInteractionWithThisArg
NodeInteractionWithThisArgument
} from '../NodeInteractions';
import type { ObjectPath, PathTracker } from '../utils/PathTracker';
import { EMPTY_PATH, SHARED_RECURSION_TRACKER, UNKNOWN_PATH } from '../utils/PathTracker';
@ -56,7 +56,7 @@ export default class ConditionalExpression extends NodeBase implements Deoptimiz
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
): void {
@ -144,14 +144,14 @@ export default class ConditionalExpression extends NodeBase implements Deoptimiz
includeCallArguments(
context: InclusionContext,
args: readonly (ExpressionEntity | SpreadElement)[]
parameters: readonly (ExpressionEntity | SpreadElement)[]
): void {
const usedBranch = this.getUsedBranch();
if (!usedBranch) {
this.consequent.includeCallArguments(context, args);
this.alternate.includeCallArguments(context, args);
this.consequent.includeCallArguments(context, parameters);
this.alternate.includeCallArguments(context, parameters);
} else {
usedBranch.includeCallArguments(context, args);
usedBranch.includeCallArguments(context, parameters);
}
}

@ -14,15 +14,13 @@ export default class DoWhileStatement extends StatementBase {
hasEffects(context: HasEffectsContext): boolean {
if (this.test.hasEffects(context)) return true;
const {
brokenFlow,
ignore: { breaks, continues }
} = context;
context.ignore.breaks = true;
context.ignore.continues = true;
const { brokenFlow, ignore } = context;
const { breaks, continues } = ignore;
ignore.breaks = true;
ignore.continues = true;
if (this.body.hasEffects(context)) return true;
context.ignore.breaks = breaks;
context.ignore.continues = continues;
ignore.breaks = breaks;
ignore.continues = continues;
context.brokenFlow = brokenFlow;
return false;
}

@ -1,5 +1,5 @@
import type MagicString from 'magic-string';
import { errModuleLevelDirective } from '../../utils/error';
import { errorModuleLevelDirective } from '../../utils/error';
import type { RenderOptions } from '../../utils/renderHelpers';
import type { InclusionContext } from '../ExecutionContext';
import * as NodeType from './NodeType';
@ -17,7 +17,7 @@ export default class ExpressionStatement extends StatementBase {
) {
this.context.warn(
// This is necessary, because either way (deleting or not) can lead to errors.
errModuleLevelDirective(this.directive, this.context.module.id),
errorModuleLevelDirective(this.directive, this.context.module.id),
this.start
);
}

@ -27,18 +27,16 @@ export default class ForInStatement extends StatementBase {
}
hasEffects(context: HasEffectsContext): boolean {
const { deoptimized, left, right } = this;
const { body, deoptimized, left, right } = this;
if (!deoptimized) this.applyDeoptimizations();
if (left.hasEffectsAsAssignmentTarget(context, false) || right.hasEffects(context)) return true;
const {
brokenFlow,
ignore: { breaks, continues }
} = context;
context.ignore.breaks = true;
context.ignore.continues = true;
if (this.body.hasEffects(context)) return true;
context.ignore.breaks = breaks;
context.ignore.continues = continues;
const { brokenFlow, ignore } = context;
const { breaks, continues } = ignore;
ignore.breaks = true;
ignore.continues = true;
if (body.hasEffects(context)) return true;
ignore.breaks = breaks;
ignore.continues = continues;
context.brokenFlow = brokenFlow;
return false;
}

@ -30,15 +30,13 @@ export default class ForStatement extends StatementBase {
this.update?.hasEffects(context)
)
return true;
const {
brokenFlow,
ignore: { breaks, continues }
} = context;
context.ignore.breaks = true;
context.ignore.continues = true;
const { brokenFlow, ignore } = context;
const { breaks, continues } = ignore;
ignore.breaks = true;
ignore.continues = true;
if (this.body.hasEffects(context)) return true;
context.ignore.breaks = breaks;
context.ignore.continues = continues;
ignore.breaks = breaks;
ignore.continues = continues;
context.brokenFlow = brokenFlow;
return false;
}

@ -2,14 +2,14 @@ import isReference, { type NodeWithFieldDefinition } from 'is-reference';
import type MagicString from 'magic-string';
import type { NormalizedTreeshakingOptions } from '../../rollup/types';
import { BLANK } from '../../utils/blank';
import { errIllegalImportReassignment } from '../../utils/error';
import { errorIllegalImportReassignment } from '../../utils/error';
import type { NodeRenderOptions, RenderOptions } from '../../utils/renderHelpers';
import type { DeoptimizableEntity } from '../DeoptimizableEntity';
import type { HasEffectsContext, InclusionContext } from '../ExecutionContext';
import type {
NodeInteraction,
NodeInteractionCalled,
NodeInteractionWithThisArg
NodeInteractionWithThisArgument
} from '../NodeInteractions';
import {
INTERACTION_ACCESSED,
@ -68,29 +68,34 @@ export default class Identifier extends NodeBase implements PatternNode {
let variable: LocalVariable;
const { treeshake } = this.context.options;
switch (kind) {
case 'var':
case 'var': {
variable = this.scope.addDeclaration(this, this.context, init, true);
if (treeshake && treeshake.correctVarValueBeforeDeclaration) {
// Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
variable.markInitializersForDeoptimization();
}
break;
case 'function':
}
case 'function': {
// in strict mode, functions are only hoisted within a scope but not across block scopes
variable = this.scope.addDeclaration(this, this.context, init, false);
break;
}
case 'let':
case 'const':
case 'class':
case 'class': {
variable = this.scope.addDeclaration(this, this.context, init, false);
break;
case 'parameter':
}
case 'parameter': {
variable = (this.scope as FunctionScope).addParameterDeclaration(this);
break;
}
/* istanbul ignore next */
default:
default: {
/* istanbul ignore next */
throw new Error(`Internal Error: Unexpected identifier kind ${kind}.`);
}
}
variable.kind = kind;
return [(this.variable = variable)];
@ -106,7 +111,7 @@ export default class Identifier extends NodeBase implements PatternNode {
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
): void {
@ -157,21 +162,24 @@ export default class Identifier extends NodeBase implements PatternNode {
context: HasEffectsContext
): boolean {
switch (interaction.type) {
case INTERACTION_ACCESSED:
case INTERACTION_ACCESSED: {
return (
this.variable !== null &&
this.getVariableRespectingTDZ()!.hasEffectsOnInteractionAtPath(path, interaction, context)
);
case INTERACTION_ASSIGNED:
}
case INTERACTION_ASSIGNED: {
return (
path.length > 0 ? this.getVariableRespectingTDZ() : this.variable
)!.hasEffectsOnInteractionAtPath(path, interaction, context);
case INTERACTION_CALLED:
}
case INTERACTION_CALLED: {
return this.getVariableRespectingTDZ()!.hasEffectsOnInteractionAtPath(
path,
interaction,
context
);
}
}
}
@ -187,9 +195,9 @@ export default class Identifier extends NodeBase implements PatternNode {
includeCallArguments(
context: InclusionContext,
args: readonly (ExpressionEntity | SpreadElement)[]
parameters: readonly (ExpressionEntity | SpreadElement)[]
): void {
this.variable!.includeCallArguments(context, args);
this.variable!.includeCallArguments(context, parameters);
}
isPossibleTDZ(): boolean {
@ -268,7 +276,7 @@ export default class Identifier extends NodeBase implements PatternNode {
private disallowImportReassignment(): never {
return this.context.error(
errIllegalImportReassignment(this.name, this.context.module.id),
errorIllegalImportReassignment(this.name, this.context.module.id),
this.start
);
}

@ -44,11 +44,13 @@ export default class IfStatement extends StatementBase implements DeoptimizableE
if (typeof testValue === 'symbol') {
const { brokenFlow } = context;
if (this.consequent.hasEffects(context)) return true;
// eslint-disable-next-line unicorn/consistent-destructuring
const consequentBrokenFlow = context.brokenFlow;
context.brokenFlow = brokenFlow;
if (this.alternate === null) return false;
if (this.alternate.hasEffects(context)) return true;
context.brokenFlow =
// eslint-disable-next-line unicorn/consistent-destructuring
context.brokenFlow < consequentBrokenFlow ? context.brokenFlow : consequentBrokenFlow;
return false;
}
@ -169,12 +171,14 @@ export default class IfStatement extends StatementBase implements DeoptimizableE
let consequentBrokenFlow = BROKEN_FLOW_NONE;
if (this.consequent.shouldBeIncluded(context)) {
this.consequent.include(context, false, { asSingleStatement: true });
// eslint-disable-next-line unicorn/consistent-destructuring
consequentBrokenFlow = context.brokenFlow;
context.brokenFlow = brokenFlow;
}
if (this.alternate?.shouldBeIncluded(context)) {
this.alternate.include(context, false, { asSingleStatement: true });
context.brokenFlow =
// eslint-disable-next-line unicorn/consistent-destructuring
context.brokenFlow < consequentBrokenFlow ? context.brokenFlow : consequentBrokenFlow;
}
}
@ -184,7 +188,7 @@ export default class IfStatement extends StatementBase implements DeoptimizableE
code: MagicString,
getPropertyAccess: (name: string) => string
) {
const hoistedVars = [
const hoistedVariables = [
...new Set(
hoistedDeclarations.map(identifier => {
const variable = identifier.variable!;
@ -194,10 +198,10 @@ export default class IfStatement extends StatementBase implements DeoptimizableE
]
.filter(Boolean)
.join(', ');
if (hoistedVars) {
if (hoistedVariables) {
const parentType = this.parent.type;
const needsBraces = parentType !== NodeType.Program && parentType !== NodeType.BlockStatement;
code.prependRight(this.start, `${needsBraces ? '{ ' : ''}var ${hoistedVars}; `);
code.prependRight(this.start, `${needsBraces ? '{ ' : ''}var ${hoistedVariables}; `);
if (needsBraces) {
code.appendLeft(this.end, ` }`);
}

@ -242,7 +242,7 @@ export default class ImportExpression extends NodeBase {
mechanism: { left, right }
};
}
case 'system':
case 'system': {
return {
helper: null,
mechanism: {
@ -250,7 +250,8 @@ export default class ImportExpression extends NodeBase {
right: ')'
}
};
case 'es':
}
case 'es': {
if (dynamicImportFunction) {
return {
helper: null,
@ -260,6 +261,7 @@ export default class ImportExpression extends NodeBase {
}
};
}
}
}
return { helper: null, mechanism: null };
}

@ -61,15 +61,18 @@ export default class Literal<T extends LiteralValue = LiteralValue> extends Node
context: HasEffectsContext
): boolean {
switch (interaction.type) {
case INTERACTION_ACCESSED:
case INTERACTION_ACCESSED: {
return path.length > (this.value === null ? 0 : 1);
case INTERACTION_ASSIGNED:
}
case INTERACTION_ASSIGNED: {
return true;
case INTERACTION_CALLED:
}
case INTERACTION_CALLED: {
return (
path.length !== 1 ||
hasMemberEffectWhenCalled(this.members, path[0], interaction, context)
);
}
}
}

@ -13,7 +13,7 @@ import type { HasEffectsContext, InclusionContext } from '../ExecutionContext';
import type {
NodeInteraction,
NodeInteractionCalled,
NodeInteractionWithThisArg
NodeInteractionWithThisArgument
} from '../NodeInteractions';
import {
EMPTY_PATH,
@ -69,7 +69,7 @@ export default class LogicalExpression extends NodeBase implements Deoptimizable
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
): void {

@ -2,7 +2,7 @@ import type MagicString from 'magic-string';
import type { AstContext } from '../../Module';
import type { NormalizedTreeshakingOptions } from '../../rollup/types';
import { BLANK } from '../../utils/blank';
import { errIllegalImportReassignment, errMissingExport } from '../../utils/error';
import { errorIllegalImportReassignment, errorMissingExport } from '../../utils/error';
import type { NodeRenderOptions, RenderOptions } from '../../utils/renderHelpers';
import type { DeoptimizableEntity } from '../DeoptimizableEntity';
import type { HasEffectsContext, InclusionContext } from '../ExecutionContext';
@ -11,7 +11,7 @@ import type {
NodeInteractionAccessed,
NodeInteractionAssigned,
NodeInteractionCalled,
NodeInteractionWithThisArg
NodeInteractionWithThisArgument
} from '../NodeInteractions';
import { INTERACTION_ACCESSED, INTERACTION_ASSIGNED } from '../NodeInteractions';
import {
@ -141,19 +141,17 @@ export default class MemberExpression extends NodeBase implements DeoptimizableE
if (path.length === 0) this.disallowNamespaceReassignment();
if (this.variable) {
this.variable.deoptimizePath(path);
} else if (!this.isUndefined) {
if (path.length < MAX_PATH_DEPTH) {
const propertyKey = this.getPropertyKey();
this.object.deoptimizePath([
propertyKey === UnknownKey ? UnknownNonAccessorKey : propertyKey,
...path
]);
}
} else if (!this.isUndefined && path.length < MAX_PATH_DEPTH) {
const propertyKey = this.getPropertyKey();
this.object.deoptimizePath([
propertyKey === UnknownKey ? UnknownNonAccessorKey : propertyKey,
...path
]);
}
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
): void {
@ -284,12 +282,12 @@ export default class MemberExpression extends NodeBase implements DeoptimizableE
includeCallArguments(
context: InclusionContext,
args: readonly (ExpressionEntity | SpreadElement)[]
parameters: readonly (ExpressionEntity | SpreadElement)[]
): void {
if (this.variable) {
this.variable.includeCallArguments(context, args);
this.variable.includeCallArguments(context, parameters);
} else {
super.includeCallArguments(context, args);
super.includeCallArguments(context, parameters);
}
}
@ -381,7 +379,7 @@ export default class MemberExpression extends NodeBase implements DeoptimizableE
this.context.includeVariableInModule(this.variable);
}
this.context.warn(
errIllegalImportReassignment(this.object.name, this.context.module.id),
errorIllegalImportReassignment(this.object.name, this.context.module.id),
this.start
);
}
@ -443,7 +441,7 @@ function resolveNamespaceVariables(
const variable = (baseVariable as NamespaceVariable).context.traceExport(exportName);
if (!variable) {
const fileName = (baseVariable as NamespaceVariable).context.fileName;
astContext.warn(errMissingExport(exportName, astContext.module.id, fileName), path[0].pos);
astContext.warn(errorMissingExport(exportName, astContext.module.id, fileName), path[0].pos);
return 'undefined';
}
return resolveNamespaceVariables(variable, path.slice(1), astContext);

@ -27,7 +27,7 @@ export default class MetaProperty extends NodeBase {
getReferencedFileName(outputPluginDriver: PluginDriver): string | null {
const { metaProperty } = this;
if (metaProperty?.startsWith(FILE_PREFIX)) {
return outputPluginDriver.getFileName(metaProperty.substring(FILE_PREFIX.length));
return outputPluginDriver.getFileName(metaProperty.slice(FILE_PREFIX.length));
}
return null;
}
@ -51,29 +51,32 @@ export default class MetaProperty extends NodeBase {
? parent.propertyKey
: null);
if (metaProperty?.startsWith(FILE_PREFIX)) {
this.referenceId = metaProperty.substring(FILE_PREFIX.length);
this.referenceId = metaProperty.slice(FILE_PREFIX.length);
}
}
}
}
render(code: MagicString, { format, pluginDriver, snippets }: RenderOptions): void {
const { metaProperty, parent, referenceId } = this;
const chunkId = this.preliminaryChunkId!;
const {
context: {
module: { id: moduleId }
},
metaProperty,
parent,
preliminaryChunkId,
referenceId,
start,
end
} = this;
const chunkId = preliminaryChunkId!;
if (referenceId) {
const fileName = pluginDriver.getFileName(referenceId);
const relativePath = normalize(relative(dirname(chunkId), fileName));
const replacement =
pluginDriver.hookFirstSync('resolveFileUrl', [
{
chunkId,
fileName,
format,
moduleId: this.context.module.id,
referenceId,
relativePath
}
{ chunkId, fileName, format, moduleId, referenceId, relativePath }
]) || relativeUrlMechanisms[format](relativePath);
code.overwrite(
@ -88,17 +91,13 @@ export default class MetaProperty extends NodeBase {
const replacement =
pluginDriver.hookFirstSync('resolveImportMeta', [
metaProperty,
{
chunkId,
format,
moduleId: this.context.module.id
}
{ chunkId, format, moduleId }
]) || importMetaMechanisms[format]?.(metaProperty, { chunkId, snippets });
if (typeof replacement === 'string') {
if (parent instanceof MemberExpression) {
code.overwrite(parent.start, parent.end, replacement, { contentOnly: true });
} else {
code.overwrite(this.start, this.end, replacement, { contentOnly: true });
code.overwrite(start, end, replacement, { contentOnly: true });
}
}
}
@ -147,11 +146,11 @@ const getRelativeUrlFromDocument = (relativePath: string, umd = false) =>
const getGenericImportMetaMechanism =
(getUrl: (chunkId: string) => string) =>
(prop: string | null, { chunkId }: { chunkId: string }) => {
(property: string | null, { chunkId }: { chunkId: string }) => {
const urlMechanism = getUrl(chunkId);
return prop === null
return property === null
? `({ url: ${urlMechanism} })`
: prop === 'url'
: property === 'url'
? urlMechanism
: 'undefined';
};
@ -183,7 +182,7 @@ const relativeUrlMechanisms: Record<InternalModuleFormat, (relativePath: string)
const importMetaMechanisms: Record<
string,
(prop: string | null, options: { chunkId: string; snippets: GenerateCodeSnippets }) => string
(property: string | null, options: { chunkId: string; snippets: GenerateCodeSnippets }) => string
> = {
amd: getGenericImportMetaMechanism(() => getResolveUrl(`module.uri, document.baseURI`)),
cjs: getGenericImportMetaMechanism(
@ -194,8 +193,8 @@ const importMetaMechanisms: Record<
)} : ${getUrlFromDocument(chunkId)})`
),
iife: getGenericImportMetaMechanism(chunkId => getUrlFromDocument(chunkId)),
system: (prop, { snippets: { getPropertyAccess } }) =>
prop === null ? `module.meta` : `module.meta${getPropertyAccess(prop)}`,
system: (property, { snippets: { getPropertyAccess } }) =>
property === null ? `module.meta` : `module.meta${getPropertyAccess(property)}`,
umd: getGenericImportMetaMechanism(
chunkId =>
`(typeof document === 'undefined' && typeof location === 'undefined' ? ${getResolveUrl(

@ -6,7 +6,7 @@ import type { HasEffectsContext } from '../ExecutionContext';
import type {
NodeInteraction,
NodeInteractionCalled,
NodeInteractionWithThisArg
NodeInteractionWithThisArgument
} from '../NodeInteractions';
import {
EMPTY_PATH,
@ -39,7 +39,7 @@ export default class ObjectExpression extends NodeBase implements DeoptimizableE
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
): void {

@ -32,7 +32,7 @@ export default class Program extends NodeBase {
}
render(code: MagicString, options: RenderOptions): void {
if (this.body.length) {
if (this.body.length > 0) {
renderStatementList(this.body, code, this.start, this.end, options);
} else {
super.render(code, options);

@ -3,7 +3,7 @@ import type { HasEffectsContext } from '../ExecutionContext';
import type {
NodeInteraction,
NodeInteractionCalled,
NodeInteractionWithThisArg
NodeInteractionWithThisArgument
} from '../NodeInteractions';
import type { ObjectPath, PathTracker } from '../utils/PathTracker';
import type * as NodeType from './NodeType';
@ -28,7 +28,7 @@ export default class PropertyDefinition extends NodeBase {
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
): void {

@ -9,7 +9,7 @@ import {
import { treeshakeNode } from '../../utils/treeshakeNode';
import type { DeoptimizableEntity } from '../DeoptimizableEntity';
import type { HasEffectsContext, InclusionContext } from '../ExecutionContext';
import type { NodeInteraction, NodeInteractionWithThisArg } from '../NodeInteractions';
import type { NodeInteraction, NodeInteractionWithThisArgument } from '../NodeInteractions';
import type { ObjectPath, PathTracker } from '../utils/PathTracker';
import ExpressionStatement from './ExpressionStatement';
import type * as NodeType from './NodeType';
@ -25,7 +25,7 @@ export default class SequenceExpression extends NodeBase {
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
): void {

@ -1,6 +1,6 @@
import type { NormalizedTreeshakingOptions } from '../../rollup/types';
import type { HasEffectsContext } from '../ExecutionContext';
import type { NodeInteractionWithThisArg } from '../NodeInteractions';
import type { NodeInteractionWithThisArgument } from '../NodeInteractions';
import { NODE_INTERACTION_UNKNOWN_ACCESS } from '../NodeInteractions';
import { type ObjectPath, type PathTracker, UNKNOWN_PATH, UnknownKey } from '../utils/PathTracker';
import type * as NodeType from './NodeType';
@ -11,7 +11,7 @@ export default class SpreadElement extends NodeBase {
declare type: NodeType.tSpreadElement;
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
): void {

@ -30,7 +30,7 @@ export default class StaticBlock extends StatementBase {
}
render(code: MagicString, options: RenderOptions): void {
if (this.body.length) {
if (this.body.length > 0) {
renderStatementList(this.body, code, this.start + 1, this.end - 1, options);
} else {
super.render(code, options);

@ -1,4 +1,4 @@
import type { NodeInteractionWithThisArg } from '../NodeInteractions';
import type { NodeInteractionWithThisArgument } from '../NodeInteractions';
import type { ObjectPath, PathTracker } from '../utils/PathTracker';
import type Variable from '../variables/Variable';
import type * as NodeType from './NodeType';
@ -17,7 +17,7 @@ export default class Super extends NodeBase {
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
) {

@ -39,7 +39,7 @@ export default class SwitchCase extends NodeBase {
}
render(code: MagicString, options: RenderOptions, nodeRenderOptions?: NodeRenderOptions): void {
if (this.consequent.length) {
if (this.consequent.length > 0) {
this.test && this.test.render(code, options);
const testEnd = this.test
? this.test.end

@ -25,21 +25,20 @@ export default class SwitchStatement extends StatementBase {
hasEffects(context: HasEffectsContext): boolean {
if (this.discriminant.hasEffects(context)) return true;
const {
brokenFlow,
ignore: { breaks }
} = context;
const { brokenFlow, ignore } = context;
const { breaks } = ignore;
let minBrokenFlow = Infinity;
context.ignore.breaks = true;
ignore.breaks = true;
for (const switchCase of this.cases) {
if (switchCase.hasEffects(context)) return true;
// eslint-disable-next-line unicorn/consistent-destructuring
minBrokenFlow = context.brokenFlow < minBrokenFlow ? context.brokenFlow : minBrokenFlow;
context.brokenFlow = brokenFlow;
}
if (this.defaultCase !== null && !(minBrokenFlow === BROKEN_FLOW_BREAK_CONTINUE)) {
context.brokenFlow = minBrokenFlow;
}
context.ignore.breaks = breaks;
ignore.breaks = breaks;
return false;
}
@ -63,6 +62,7 @@ export default class SwitchStatement extends StatementBase {
}
if (isCaseIncluded) {
switchCase.include(context, includeChildrenRecursively);
// eslint-disable-next-line unicorn/consistent-destructuring
minBrokenFlow = minBrokenFlow < context.brokenFlow ? minBrokenFlow : context.brokenFlow;
context.brokenFlow = brokenFlow;
} else {

@ -1,8 +1,8 @@
import type MagicString from 'magic-string';
import { errCannotCallNamespace } from '../../utils/error';
import { errorCannotCallNamespace } from '../../utils/error';
import { type RenderOptions } from '../../utils/renderHelpers';
import type { HasEffectsContext, InclusionContext } from '../ExecutionContext';
import type { NodeInteractionWithThisArg } from '../NodeInteractions';
import type { NodeInteractionWithThisArgument } from '../NodeInteractions';
import { INTERACTION_CALLED } from '../NodeInteractions';
import type { PathTracker } from '../utils/PathTracker';
import { EMPTY_PATH, SHARED_RECURSION_TRACKER, UNKNOWN_PATH } from '../utils/PathTracker';
@ -28,7 +28,7 @@ export default class TaggedTemplateExpression extends CallExpressionBase {
const variable = this.scope.findVariable(name);
if (variable.isNamespace) {
this.context.warn(errCannotCallNamespace(name), this.start);
this.context.warn(errorCannotCallNamespace(name), this.start);
}
}
}
@ -81,7 +81,7 @@ export default class TaggedTemplateExpression extends CallExpressionBase {
this.deoptimized = true;
if (this.interaction.thisArg) {
this.tag.deoptimizeThisOnInteractionAtPath(
this.interaction as NodeInteractionWithThisArg,
this.interaction as NodeInteractionWithThisArgument,
EMPTY_PATH,
SHARED_RECURSION_TRACKER
);

@ -1,7 +1,7 @@
import type MagicString from 'magic-string';
import { errThisIsUndefined } from '../../utils/error';
import { errorThisIsUndefined } from '../../utils/error';
import type { HasEffectsContext } from '../ExecutionContext';
import type { NodeInteraction, NodeInteractionWithThisArg } from '../NodeInteractions';
import type { NodeInteraction, NodeInteractionWithThisArgument } from '../NodeInteractions';
import { INTERACTION_ACCESSED } from '../NodeInteractions';
import ModuleScope from '../scopes/ModuleScope';
import type { ObjectPath, PathTracker } from '../utils/PathTracker';
@ -23,7 +23,7 @@ export default class ThisExpression extends NodeBase {
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
): void {
@ -57,7 +57,7 @@ export default class ThisExpression extends NodeBase {
this.alias =
this.scope.findLexicalBoundary() instanceof ModuleScope ? this.context.moduleContext : null;
if (this.alias === 'undefined') {
this.context.warn(errThisIsUndefined(), this.start);
this.context.warn(errorThisIsUndefined(), this.start);
}
}

@ -25,7 +25,7 @@ export default class TryStatement extends StatementBase {
include(context: InclusionContext, includeChildrenRecursively: IncludeChildren): void {
const tryCatchDeoptimization = (this.context.options.treeshake as NormalizedTreeshakingOptions)
?.tryCatchDeoptimization;
const { brokenFlow } = context;
const { brokenFlow, includedLabels } = context;
if (!this.directlyIncluded || !tryCatchDeoptimization) {
this.included = true;
this.directlyIncluded = true;
@ -33,13 +33,13 @@ export default class TryStatement extends StatementBase {
context,
tryCatchDeoptimization ? INCLUDE_PARAMETERS : includeChildrenRecursively
);
if (context.includedLabels.size > 0) {
this.includedLabelsAfterBlock = [...context.includedLabels];
if (includedLabels.size > 0) {
this.includedLabelsAfterBlock = [...includedLabels];
}
context.brokenFlow = brokenFlow;
} else if (this.includedLabelsAfterBlock) {
for (const label of this.includedLabelsAfterBlock) {
context.includedLabels.add(label);
includedLabels.add(label);
}
}
if (this.handler !== null) {

@ -14,15 +14,13 @@ export default class WhileStatement extends StatementBase {
hasEffects(context: HasEffectsContext): boolean {
if (this.test.hasEffects(context)) return true;
const {
brokenFlow,
ignore: { breaks, continues }
} = context;
context.ignore.breaks = true;
context.ignore.continues = true;
const { brokenFlow, ignore } = context;
const { breaks, continues } = ignore;
ignore.breaks = true;
ignore.continues = true;
if (this.body.hasEffects(context)) return true;
context.ignore.breaks = breaks;
context.ignore.continues = continues;
ignore.breaks = breaks;
ignore.continues = continues;
context.brokenFlow = brokenFlow;
return false;
}

@ -3,7 +3,7 @@ import type { HasEffectsContext } from '../../ExecutionContext';
import type {
NodeInteraction,
NodeInteractionCalled,
NodeInteractionWithThisArg
NodeInteractionWithThisArgument
} from '../../NodeInteractions';
import { INTERACTION_ASSIGNED, INTERACTION_CALLED } from '../../NodeInteractions';
import { type ObjectPath, type PathTracker, UNKNOWN_PATH } from '../../utils/PathTracker';
@ -47,7 +47,7 @@ export default abstract class CallExpressionBase extends NodeBase implements Deo
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
): void {
@ -62,7 +62,7 @@ export default abstract class CallExpressionBase extends NodeBase implements Deo
this.expressionsToBeDeoptimized.add(interaction.thisArg);
returnExpression.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
},
undefined
null
);
}
}
@ -120,11 +120,13 @@ export default abstract class CallExpressionBase extends NodeBase implements Deo
): boolean {
const { type } = interaction;
if (type === INTERACTION_CALLED) {
const { args, withNew } = interaction;
if (
(interaction.withNew
? context.instantiated
: context.called
).trackEntityAtPathAndGetIfTracked(path, interaction.args, this)
(withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(
path,
args,
this
)
) {
return false;
}

@ -3,7 +3,7 @@ import type { HasEffectsContext, InclusionContext } from '../../ExecutionContext
import type {
NodeInteraction,
NodeInteractionCalled,
NodeInteractionWithThisArg
NodeInteractionWithThisArgument
} from '../../NodeInteractions';
import { INTERACTION_CALLED } from '../../NodeInteractions';
import ChildScope from '../../scopes/ChildScope';
@ -46,7 +46,7 @@ export default class ClassNode extends NodeBase implements DeoptimizableEntity {
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
): void {
@ -87,17 +87,13 @@ export default class ClassNode extends NodeBase implements DeoptimizableEntity {
interaction: NodeInteraction,
context: HasEffectsContext
): boolean {
if (interaction.type === INTERACTION_CALLED && path.length === 0) {
return (
!interaction.withNew ||
(this.classConstructor !== null
? this.classConstructor.hasEffectsOnInteractionAtPath(path, interaction, context)
: this.superClass?.hasEffectsOnInteractionAtPath(path, interaction, context)) ||
false
);
} else {
return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
}
return interaction.type === INTERACTION_CALLED && path.length === 0
? !interaction.withNew ||
(this.classConstructor !== null
? this.classConstructor.hasEffectsOnInteractionAtPath(path, interaction, context)
: this.superClass?.hasEffectsOnInteractionAtPath(path, interaction, context)) ||
false
: this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
}
include(context: InclusionContext, includeChildrenRecursively: IncludeChildren): void {

@ -4,7 +4,7 @@ import type { HasEffectsContext, InclusionContext } from '../../ExecutionContext
import type {
NodeInteraction,
NodeInteractionCalled,
NodeInteractionWithThisArg
NodeInteractionWithThisArgument
} from '../../NodeInteractions';
import type { ObjectPath, PathTracker, SymbolToStringTag } from '../../utils/PathTracker';
import { UNKNOWN_PATH } from '../../utils/PathTracker';
@ -34,7 +34,7 @@ export class ExpressionEntity implements WritableEntity {
deoptimizePath(_path: ObjectPath): void {}
deoptimizeThisOnInteractionAtPath(
{ thisArg }: NodeInteractionWithThisArg,
{ thisArg }: NodeInteractionWithThisArgument,
_path: ObjectPath,
_recursionTracker: PathTracker
): void {
@ -81,10 +81,10 @@ export class ExpressionEntity implements WritableEntity {
includeCallArguments(
context: InclusionContext,
args: readonly (ExpressionEntity | SpreadElement)[]
parameters: readonly (ExpressionEntity | SpreadElement)[]
): void {
for (const arg of args) {
arg.include(context, false);
for (const argument of parameters) {
argument.include(context, false);
}
}

@ -8,7 +8,7 @@ import {
import type {
NodeInteraction,
NodeInteractionCalled,
NodeInteractionWithThisArg
NodeInteractionWithThisArgument
} from '../../NodeInteractions';
import {
INTERACTION_CALLED,
@ -52,7 +52,7 @@ export default abstract class FunctionBase extends NodeBase {
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
): void {
@ -123,8 +123,8 @@ export default abstract class FunctionBase extends NodeBase {
return true;
}
}
for (const param of this.params) {
if (param.hasEffects(context)) return true;
for (const parameter of this.params) {
if (parameter.hasEffects(context)) return true;
}
return false;
}
@ -140,14 +140,14 @@ export default abstract class FunctionBase extends NodeBase {
includeCallArguments(
context: InclusionContext,
args: readonly (ExpressionEntity | SpreadElement)[]
parameters: readonly (ExpressionEntity | SpreadElement)[]
): void {
this.scope.includeCallArguments(context, args);
this.scope.includeCallArguments(context, parameters);
}
initialise(): void {
this.scope.addParameterVariables(
this.params.map(param => param.declare('parameter', UNKNOWN_EXPRESSION)),
this.params.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)),
this.params[this.params.length - 1] instanceof RestElement
);
if (this.body instanceof BlockStatement) {

@ -1,5 +1,5 @@
import { type HasEffectsContext, type InclusionContext } from '../../ExecutionContext';
import type { NodeInteraction, NodeInteractionWithThisArg } from '../../NodeInteractions';
import type { NodeInteraction, NodeInteractionWithThisArgument } from '../../NodeInteractions';
import { INTERACTION_CALLED } from '../../NodeInteractions';
import FunctionScope from '../../scopes/FunctionScope';
import type { PathTracker } from '../../utils/PathTracker';
@ -27,7 +27,7 @@ export default class FunctionNode extends FunctionBase {
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
): void {
@ -56,7 +56,7 @@ export default class FunctionNode extends FunctionBase {
? new ObjectEntity(Object.create(null), OBJECT_PROTOTYPE)
: UNKNOWN_EXPRESSION
);
const { brokenFlow, ignore } = context;
const { brokenFlow, ignore, replacedVariableInits } = context;
context.ignore = {
breaks: false,
continues: false,
@ -66,9 +66,9 @@ export default class FunctionNode extends FunctionBase {
if (this.body.hasEffects(context)) return true;
context.brokenFlow = brokenFlow;
if (thisInit) {
context.replacedVariableInits.set(this.scope.thisVariable, thisInit);
replacedVariableInits.set(this.scope.thisVariable, thisInit);
} else {
context.replacedVariableInits.delete(this.scope.thisVariable);
replacedVariableInits.delete(this.scope.thisVariable);
}
context.ignore = ignore;
}
@ -79,9 +79,9 @@ export default class FunctionNode extends FunctionBase {
super.include(context, includeChildrenRecursively);
this.id?.include();
const hasArguments = this.scope.argumentsVariable.included;
for (const param of this.params) {
if (!(param instanceof Identifier) || hasArguments) {
param.include(context, includeChildrenRecursively);
for (const parameter of this.params) {
if (!(parameter instanceof Identifier) || hasArguments) {
parameter.include(context, includeChildrenRecursively);
}
}
}

@ -3,7 +3,7 @@ import type { HasEffectsContext } from '../../ExecutionContext';
import type {
NodeInteraction,
NodeInteractionCalled,
NodeInteractionWithThisArg
NodeInteractionWithThisArgument
} from '../../NodeInteractions';
import {
INTERACTION_ACCESSED,
@ -44,7 +44,7 @@ export default class MethodBase extends NodeBase implements DeoptimizableEntity
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
): void {

@ -2,7 +2,7 @@ import type { HasEffectsContext } from '../../ExecutionContext';
import type {
NodeInteraction,
NodeInteractionCalled,
NodeInteractionWithThisArg
NodeInteractionWithThisArgument
} from '../../NodeInteractions';
import {
INTERACTION_ACCESSED,
@ -38,7 +38,7 @@ export class Method extends ExpressionEntity {
}
deoptimizeThisOnInteractionAtPath(
{ type, thisArg }: NodeInteractionWithThisArg,
{ type, thisArg }: NodeInteractionWithThisArgument,
path: ObjectPath
): void {
if (type === INTERACTION_CALLED && path.length === 0 && this.description.mutatesSelfAsArray) {
@ -71,9 +71,10 @@ export class Method extends ExpressionEntity {
return true;
}
if (type === INTERACTION_CALLED) {
const { args, thisArg } = interaction;
if (
this.description.mutatesSelfAsArray === true &&
interaction.thisArg?.hasEffectsOnInteractionAtPath(
thisArg?.hasEffectsOnInteractionAtPath(
UNKNOWN_INTEGER_PATH,
NODE_INTERACTION_UNKNOWN_ASSIGNMENT,
context
@ -82,9 +83,9 @@ export class Method extends ExpressionEntity {
return true;
}
if (this.description.callsArgs) {
for (const argIndex of this.description.callsArgs) {
for (const argumentIndex of this.description.callsArgs) {
if (
interaction.args[argIndex]?.hasEffectsOnInteractionAtPath(
args[argumentIndex]?.hasEffectsOnInteractionAtPath(
EMPTY_PATH,
NODE_INTERACTION_UNKNOWN_CALL,
context

@ -3,7 +3,7 @@ import type { HasEffectsContext } from '../../ExecutionContext';
import type {
NodeInteraction,
NodeInteractionCalled,
NodeInteractionWithThisArg
NodeInteractionWithThisArgument
} from '../../NodeInteractions';
import { INTERACTION_ACCESSED, INTERACTION_CALLED } from '../../NodeInteractions';
import type { ObjectPath, ObjectPathKey, PathTracker } from '../../utils/PathTracker';
@ -79,9 +79,10 @@ export class ObjectEntity extends ExpressionEntity {
if (isDeoptimized) {
return;
}
for (const properties of Object.values(this.propertiesAndGettersByKey).concat(
Object.values(this.settersByKey)
)) {
for (const properties of [
...Object.values(this.propertiesAndGettersByKey),
...Object.values(this.settersByKey)
]) {
for (const property of properties) {
property.deoptimizePath(UNKNOWN_PATH);
}
@ -139,9 +140,10 @@ export class ObjectEntity extends ExpressionEntity {
const subPath = path.length === 1 ? UNKNOWN_PATH : path.slice(1);
for (const property of typeof key === 'string'
? (this.propertiesAndGettersByKey[key] || this.unmatchablePropertiesAndGetters).concat(
this.settersByKey[key] || this.unmatchableSetters
)
? [
...(this.propertiesAndGettersByKey[key] || this.unmatchablePropertiesAndGetters),
...(this.settersByKey[key] || this.unmatchableSetters)
]
: this.allProperties) {
property.deoptimizePath(subPath);
}
@ -149,7 +151,7 @@ export class ObjectEntity extends ExpressionEntity {
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
): void {
@ -199,9 +201,10 @@ export class ObjectEntity extends ExpressionEntity {
}
}
} else {
for (const properties of Object.values(relevantPropertiesByKey).concat([
for (const properties of [
...Object.values(relevantPropertiesByKey),
relevantUnmatchableProperties
])) {
]) {
for (const property of properties) {
property.deoptimizeThisOnInteractionAtPath(interaction, subPath, recursionTracker);
}
@ -278,7 +281,7 @@ export class ObjectEntity extends ExpressionEntity {
context: HasEffectsContext
): boolean {
const [key, ...subPath] = path;
if (subPath.length || interaction.type === INTERACTION_CALLED) {
if (subPath.length > 0 || interaction.type === INTERACTION_CALLED) {
const expressionAtPath = this.getMemberExpression(key);
if (expressionAtPath) {
return expressionAtPath.hasEffectsOnInteractionAtPath(subPath, interaction, context);
@ -310,7 +313,7 @@ export class ObjectEntity extends ExpressionEntity {
}
}
} else {
for (const accessors of Object.values(accessorsByKey).concat([unmatchableAccessors])) {
for (const accessors of [...Object.values(accessorsByKey), unmatchableAccessors]) {
for (const accessor of accessors) {
if (accessor.hasEffectsOnInteractionAtPath(subPath, interaction, context)) return true;
}
@ -413,7 +416,7 @@ export class ObjectEntity extends ExpressionEntity {
if (
properties ||
this.unmatchablePropertiesAndGetters.length > 0 ||
(this.unknownIntegerProps.length && INTEGER_REG_EXP.test(key))
(this.unknownIntegerProps.length > 0 && INTEGER_REG_EXP.test(key))
) {
return UNKNOWN_EXPRESSION;
}

@ -3,7 +3,7 @@ import type { HasEffectsContext } from '../../ExecutionContext';
import type {
NodeInteraction,
NodeInteractionCalled,
NodeInteractionWithThisArg
NodeInteractionWithThisArgument
} from '../../NodeInteractions';
import type { ObjectPath, PathTracker } from '../../utils/PathTracker';
import { ExpressionEntity, type LiteralValueOrUnknown } from './Expression';
@ -18,7 +18,7 @@ export class ObjectMember extends ExpressionEntity {
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
): void {

@ -1,4 +1,4 @@
import type { NodeInteraction, NodeInteractionWithThisArg } from '../../NodeInteractions';
import type { NodeInteraction, NodeInteractionWithThisArgument } from '../../NodeInteractions';
import { INTERACTION_CALLED } from '../../NodeInteractions';
import type { ObjectPath, ObjectPathKey } from '../../utils/PathTracker';
import { UNKNOWN_PATH } from '../../utils/PathTracker';
@ -11,7 +11,8 @@ import {
} from './MethodTypes';
import { ObjectEntity, type PropertyMap } from './ObjectEntity';
const isInteger = (prop: ObjectPathKey): boolean => typeof prop === 'string' && /^\d+$/.test(prop);
const isInteger = (property: ObjectPathKey): boolean =>
typeof property === 'string' && /^\d+$/.test(property);
// This makes sure unknown properties are not handled as "undefined" but as
// "unknown" but without access side effects. An exception is done for numeric
@ -20,7 +21,7 @@ const isInteger = (prop: ObjectPathKey): boolean => typeof prop === 'string' &&
const OBJECT_PROTOTYPE_FALLBACK: ExpressionEntity =
new (class ObjectPrototypeFallbackExpression extends ExpressionEntity {
deoptimizeThisOnInteractionAtPath(
{ type, thisArg }: NodeInteractionWithThisArg,
{ type, thisArg }: NodeInteractionWithThisArgument,
path: ObjectPath
): void {
if (type === INTERACTION_CALLED && path.length === 1 && !isInteger(path[0])) {

@ -55,7 +55,7 @@ const MUTATES_ARG_WITHOUT_ACCESSOR: GlobalDescription = {
getLiteralValue: getTruthyLiteralValue,
hasEffectsWhenCalled({ args }, context) {
return (
!args.length ||
args.length === 0 ||
args[0].hasEffectsOnInteractionAtPath(
UNKNOWN_NON_ACCESSOR_PATH,
NODE_INTERACTION_UNKNOWN_ASSIGNMENT,

@ -23,13 +23,13 @@ export default class FunctionScope extends ReturnValueScope {
includeCallArguments(
context: InclusionContext,
args: readonly (ExpressionEntity | SpreadElement)[]
parameters: readonly (ExpressionEntity | SpreadElement)[]
): void {
super.includeCallArguments(context, args);
super.includeCallArguments(context, parameters);
if (this.argumentsVariable.included) {
for (const arg of args) {
if (!arg.included) {
arg.include(context, false);
for (const argument of parameters) {
if (!argument.included) {
argument.include(context, false);
}
}
}

@ -49,31 +49,31 @@ export default class ParameterScope extends ChildScope {
includeCallArguments(
context: InclusionContext,
args: readonly (ExpressionEntity | SpreadElement)[]
parameters: readonly (ExpressionEntity | SpreadElement)[]
): void {
let calledFromTryStatement = false;
let argIncluded = false;
const restParam = this.hasRest && this.parameters[this.parameters.length - 1];
for (const checkedArg of args) {
if (checkedArg instanceof SpreadElement) {
for (const arg of args) {
arg.include(context, false);
let argumentIncluded = false;
const restParameter = this.hasRest && this.parameters[this.parameters.length - 1];
for (const checkedArgument of parameters) {
if (checkedArgument instanceof SpreadElement) {
for (const argument of parameters) {
argument.include(context, false);
}
break;
}
}
for (let index = args.length - 1; index >= 0; index--) {
const paramVars = this.parameters[index] || restParam;
const arg = args[index];
if (paramVars) {
for (let index = parameters.length - 1; index >= 0; index--) {
const parameterVariables = this.parameters[index] || restParameter;
const argument = parameters[index];
if (parameterVariables) {
calledFromTryStatement = false;
if (paramVars.length === 0) {
if (parameterVariables.length === 0) {
// handle empty destructuring
argIncluded = true;
argumentIncluded = true;
} else {
for (const variable of paramVars) {
for (const variable of parameterVariables) {
if (variable.included) {
argIncluded = true;
argumentIncluded = true;
}
if (variable.calledFromTryStatement) {
calledFromTryStatement = true;
@ -81,11 +81,11 @@ export default class ParameterScope extends ChildScope {
}
}
}
if (!argIncluded && arg.shouldBeIncluded(context)) {
argIncluded = true;
if (!argumentIncluded && argument.shouldBeIncluded(context)) {
argumentIncluded = true;
}
if (argIncluded) {
arg.include(context, calledFromTryStatement);
if (argumentIncluded) {
argument.include(context, calledFromTryStatement);
}
}
}

@ -146,13 +146,17 @@ const returnsString: RawMemberDescription = {
const stringReplace: RawMemberDescription = {
value: {
hasEffectsWhenCalled({ args }, context) {
const arg1 = args[1];
const argument1 = args[1];
return (
args.length < 2 ||
(typeof arg1.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, {
(typeof argument1.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, {
deoptimizeCache() {}
}) === 'symbol' &&
arg1.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, context))
argument1.hasEffectsOnInteractionAtPath(
EMPTY_PATH,
NODE_INTERACTION_UNKNOWN_CALL,
context
))
);
},
returns: UNKNOWN_LITERAL_STRING
@ -245,12 +249,15 @@ export function getLiteralMembersForValue<T extends LiteralValue = LiteralValue>
value: T
): MemberDescriptions {
switch (typeof value) {
case 'boolean':
case 'boolean': {
return literalBooleanMembers;
case 'number':
}
case 'number': {
return literalNumberMembers;
case 'string':
}
case 'string': {
return literalStringMembers;
}
}
return Object.create(null);
}

@ -43,11 +43,7 @@ export default class ExportDefaultVariable extends LocalVariable {
getBaseVariableName(): string {
const original = this.getOriginalVariable();
if (original === this) {
return super.getBaseVariableName();
} else {
return original.getBaseVariableName();
}
return original === this ? super.getBaseVariableName() : original.getBaseVariableName();
}
getDirectOriginalVariable(): Variable | null {
@ -66,11 +62,9 @@ export default class ExportDefaultVariable extends LocalVariable {
getName(getPropertyAccess: (name: string) => string): string {
const original = this.getOriginalVariable();
if (original === this) {
return super.getName(getPropertyAccess);
} else {
return original.getName(getPropertyAccess);
}
return original === this
? super.getName(getPropertyAccess)
: original.getName(getPropertyAccess);
}
getOriginalVariable(): Variable {

@ -32,14 +32,16 @@ export default class GlobalVariable extends Variable {
context: HasEffectsContext
): boolean {
switch (interaction.type) {
case INTERACTION_ACCESSED:
case INTERACTION_ACCESSED: {
if (path.length === 0) {
// Technically, "undefined" is a global variable of sorts
return this.name !== 'undefined' && !getGlobalAtPath([this.name]);
}
return !getGlobalAtPath([this.name, ...path].slice(0, -1));
case INTERACTION_ASSIGNED:
}
case INTERACTION_ASSIGNED: {
return true;
}
case INTERACTION_CALLED: {
const globalAtPath = getGlobalAtPath([this.name, ...path]);
return !globalAtPath || globalAtPath.hasEffectsWhenCalled(interaction, context);

@ -6,7 +6,7 @@ import { createInclusionContext } from '../ExecutionContext';
import type {
NodeInteraction,
NodeInteractionCalled,
NodeInteractionWithThisArg
NodeInteractionWithThisArgument
} from '../NodeInteractions';
import {
INTERACTION_ACCESSED,
@ -92,7 +92,7 @@ export default class LocalVariable extends Variable {
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath,
recursionTracker: PathTracker
): void {
@ -157,25 +157,28 @@ export default class LocalVariable extends Variable {
context: HasEffectsContext
): boolean {
switch (interaction.type) {
case INTERACTION_ACCESSED:
case INTERACTION_ACCESSED: {
if (this.isReassigned) return true;
return (this.init &&
!context.accessed.trackEntityAtPathAndGetIfTracked(path, this) &&
this.init.hasEffectsOnInteractionAtPath(path, interaction, context))!;
case INTERACTION_ASSIGNED:
}
case INTERACTION_ASSIGNED: {
if (this.included) return true;
if (path.length === 0) return false;
if (this.isReassigned) return true;
return (this.init &&
!context.assigned.trackEntityAtPathAndGetIfTracked(path, this) &&
this.init.hasEffectsOnInteractionAtPath(path, interaction, context))!;
case INTERACTION_CALLED:
}
case INTERACTION_CALLED: {
if (this.isReassigned) return true;
return (this.init &&
!(
interaction.withNew ? context.instantiated : context.called
).trackEntityAtPathAndGetIfTracked(path, interaction.args, this) &&
this.init.hasEffectsOnInteractionAtPath(path, interaction, context))!;
}
}
}
@ -199,15 +202,15 @@ export default class LocalVariable extends Variable {
includeCallArguments(
context: InclusionContext,
args: readonly (ExpressionEntity | SpreadElement)[]
parameters: readonly (ExpressionEntity | SpreadElement)[]
): void {
if (this.isReassigned || (this.init && context.includedCallArguments.has(this.init))) {
for (const arg of args) {
arg.include(context, false);
for (const argument of parameters) {
argument.include(context, false);
}
} else if (this.init) {
context.includedCallArguments.add(this.init);
this.init.includeCallArguments(context, args);
this.init.includeCallArguments(context, parameters);
context.includedCallArguments.delete(this.init);
}
}

@ -39,7 +39,7 @@ export default class NamespaceVariable extends Variable {
return this.memberVariables;
}
const memberVariables: { [name: string]: Variable } = Object.create(null);
for (const name of this.context.getExports().concat(this.context.getReexports())) {
for (const name of [...this.context.getExports(), ...this.context.getReexports()]) {
if (name[0] !== '*' && name !== this.module.info.syntheticNamedExports) {
const exportedVariable = this.context.traceExport(name);
if (exportedVariable) {
@ -91,10 +91,10 @@ export default class NamespaceVariable extends Variable {
let output = getObject(members, { lineBreakIndent: { base: '', t } });
if (this.mergedNamespaces.length > 0) {
const assignmentArgs = this.mergedNamespaces.map(variable =>
const assignmentArguments = this.mergedNamespaces.map(variable =>
variable.getName(getPropertyAccess)
);
output = `/*#__PURE__*/${MERGE_NAMESPACES_VARIABLE}(${output},${_}[${assignmentArgs.join(
output = `/*#__PURE__*/${MERGE_NAMESPACES_VARIABLE}(${output},${_}[${assignmentArguments.join(
`,${_}`
)}])`;
} else {

@ -1,6 +1,6 @@
import type { AstContext } from '../../Module';
import type { HasEffectsContext } from '../ExecutionContext';
import type { NodeInteraction, NodeInteractionWithThisArg } from '../NodeInteractions';
import type { NodeInteraction, NodeInteractionWithThisArgument } from '../NodeInteractions';
import { type ExpressionEntity, UNKNOWN_EXPRESSION } from '../nodes/shared/Expression';
import {
DiscriminatedPathTracker,
@ -10,7 +10,7 @@ import {
import LocalVariable from './LocalVariable';
interface ThisDeoptimizationInteraction {
interaction: NodeInteractionWithThisArg;
interaction: NodeInteractionWithThisArgument;
path: ObjectPath;
}
@ -48,7 +48,7 @@ export default class ThisVariable extends LocalVariable {
}
deoptimizeThisOnInteractionAtPath(
interaction: NodeInteractionWithThisArg,
interaction: NodeInteractionWithThisArgument,
path: ObjectPath
): void {
const thisDeoptimization: ThisDeoptimizationInteraction = {

@ -39,28 +39,28 @@ export default function amd(
const deps = dependencies.map(
m => `'${updateExtensionForRelativeAmdId(m.importPath, amd.forceJsExtensionForImports)}'`
);
const args = dependencies.map(m => m.name);
const parameters = dependencies.map(m => m.name);
const { n, getNonArrowFunctionIntro, _ } = snippets;
if (namedExportsMode && hasExports) {
args.unshift(`exports`);
parameters.unshift(`exports`);
deps.unshift(`'exports'`);
}
if (accessedGlobals.has('require')) {
args.unshift('require');
parameters.unshift('require');
deps.unshift(`'require'`);
}
if (accessedGlobals.has('module')) {
args.unshift('module');
parameters.unshift('module');
deps.unshift(`'module'`);
}
const completeAmdId = getCompleteAmdId(amd, id);
const params =
const defineParameters =
(completeAmdId ? `'${completeAmdId}',${_}` : ``) +
(deps.length ? `[${deps.join(`,${_}`)}],${_}` : ``);
(deps.length > 0 ? `[${deps.join(`,${_}`)}],${_}` : ``);
const useStrict = strict ? `${_}'use strict';` : '';
magicString.prepend(
@ -100,7 +100,7 @@ export default function amd(
// factory function should be wrapped by parentheses to avoid lazy parsing,
// cf. https://v8.dev/blog/preparser#pife
.prepend(
`${amd.define}(${params}(${getNonArrowFunctionIntro(args, {
`${amd.define}(${defineParameters}(${getNonArrowFunctionIntro(parameters, {
isAsync: false,
name: null
})}{${useStrict}${n}${n}`

@ -26,7 +26,7 @@ export default function es(
if (intro) magicString.prepend(intro);
const exportBlock = getExportBlock(exports, snippets);
if (exportBlock.length) magicString.append(n + n + exportBlock.join(n).trim());
if (exportBlock.length > 0) magicString.append(n + n + exportBlock.join(n).trim());
if (outro) magicString.append(outro);
magicString.trim();
@ -63,11 +63,9 @@ function getImportBlock(dependencies: ChunkDependency[], { _ }: GenerateCodeSnip
importBlock.push(
`import ${defaultImport ? `${defaultImport.local},${_}` : ''}{${_}${importedNames
.map(specifier => {
if (specifier.imported === specifier.local) {
return specifier.imported;
} else {
return `${specifier.imported} as ${specifier.local}`;
}
return specifier.imported === specifier.local
? specifier.imported
: `${specifier.imported} as ${specifier.local}`;
})
.join(`,${_}`)}${_}}${_}from${_}${pathWithAssertion}`
);
@ -108,11 +106,9 @@ function getImportBlock(dependencies: ChunkDependency[], { _ }: GenerateCodeSnip
importBlock.push(
`export${_}{${_}${namedReexports
.map(specifier => {
if (specifier.imported === specifier.reexported) {
return specifier.imported;
} else {
return `${specifier.imported} as ${specifier.reexported}`;
}
return specifier.imported === specifier.reexported
? specifier.imported
: `${specifier.imported} as ${specifier.reexported}`;
})
.join(`,${_}`)}${_}}${_}from${_}${pathWithAssertion}`
);
@ -135,7 +131,7 @@ function getExportBlock(exports: ChunkExports, { _, cnst }: GenerateCodeSnippets
: `${specifier.local} as ${specifier.exported}`
);
}
if (exportDeclaration.length) {
if (exportDeclaration.length > 0) {
exportBlock.push(`export${_}{${_}${exportDeclaration.join(`,${_}`)}${_}};`);
}
return exportBlock;

@ -1,9 +1,9 @@
import type { Bundle as MagicStringBundle } from 'magic-string';
import type { NormalizedOutputOptions } from '../rollup/types';
import {
errIllegalIdentifierAsName,
errMissingNameOptionForIifeExport,
error
error,
errorIllegalIdentifierAsName,
errorMissingNameOptionForIifeExport
} from '../utils/error';
import { isLegal } from '../utils/identifierHelpers';
import { getExportBlock, getNamespaceMarkers } from './shared/getExportBlock';
@ -47,17 +47,17 @@ export default function iife(
const useVariableAssignment = !extend && !isNamespaced;
if (name && useVariableAssignment && !isLegal(name)) {
return error(errIllegalIdentifierAsName(name));
return error(errorIllegalIdentifierAsName(name));
}
warnOnBuiltins(onwarn, dependencies);
const external = trimEmptyImports(dependencies);
const deps = external.map(dep => dep.globalName || 'null');
const args = external.map(m => m.name);
const parameters = external.map(m => m.name);
if (hasExports && !name) {
onwarn(errMissingNameOptionForIifeExport());
onwarn(errorMissingNameOptionForIifeExport());
}
if (namedExportsMode && hasExports) {
@ -68,10 +68,10 @@ export default function iife(
getPropertyAccess
)}${_}||${_}{}`
);
args.unshift('exports');
parameters.unshift('exports');
} else {
deps.unshift('{}');
args.unshift('exports');
parameters.unshift('exports');
}
}
@ -88,7 +88,7 @@ export default function iife(
);
magicString.prepend(`${intro}${interopBlock}`);
let wrapperIntro = `(${getNonArrowFunctionIntro(args, {
let wrapperIntro = `(${getNonArrowFunctionIntro(parameters, {
isAsync: false,
name: null
})}{${n}${useStrict}${n}`;

@ -75,12 +75,10 @@ export default function getInteropBlock(
helper = defaultInteropHelpersByInteropType[moduleInterop];
}
}
} else if (imported === '*' && reexported !== '*') {
if (!hasNamespace) {
hasNamespace = true;
helper = namespaceInteropHelpersByInteropType[moduleInterop];
variableName = namespaceVariableName!;
}
} else if (imported === '*' && reexported !== '*' && !hasNamespace) {
hasNamespace = true;
helper = namespaceInteropHelpersByInteropType[moduleInterop];
variableName = namespaceVariableName!;
}
if (helper) {
addInteropStatement(variableName!, helper, name);

@ -19,7 +19,7 @@ export default function setupNamespace(
propertyPath += getPropertyAccess(part);
return `${propertyPath}${_}=${_}${propertyPath}${_}||${_}{}${s}`;
})
.join(compact ? ',' : '\n') + (compact && parts.length ? ';' : '\n')
.join(compact ? ',' : '\n') + (compact && parts.length > 0 ? ';' : '\n')
);
}
@ -36,13 +36,13 @@ export function assignToDeepVariable(
let propertyPath = root;
let deepAssignment =
parts
.map(part => {
[
...parts.map(part => {
propertyPath += getPropertyAccess(part);
return `${propertyPath}${_}=${_}${propertyPath}${_}||${_}{}`;
})
.concat(`${propertyPath}${getPropertyAccess(last)}`)
.join(`,${_}`) + `${_}=${_}${assignment}`;
}),
`${propertyPath}${getPropertyAccess(last)}`
].join(`,${_}`) + `${_}=${_}${assignment}`;
if (parts.length > 0) {
deepAssignment = `(${deepAssignment})`;
}

@ -3,12 +3,12 @@ import type { ChunkDependency } from '../../Chunk';
export default function trimEmptyImports(
dependencies: readonly ChunkDependency[]
): ChunkDependency[] {
let i = dependencies.length;
let index = dependencies.length;
while (i--) {
const { imports, reexports } = dependencies[i];
while (index--) {
const { imports, reexports } = dependencies[index];
if (imports || reexports) {
return dependencies.slice(0, i + 1);
return dependencies.slice(0, index + 1);
}
}

@ -1,6 +1,6 @@
import type { ChunkDependency } from '../../Chunk';
import type { RollupWarning } from '../../rollup/types';
import { errMissingNodeBuiltins } from '../../utils/error';
import { errorMissingNodeBuiltins } from '../../utils/error';
const builtins = {
assert: 1,
@ -34,7 +34,7 @@ export default function warnOnBuiltins(
.map(({ importPath }) => importPath)
.filter(importPath => importPath in builtins || importPath.startsWith('node:'));
if (!externalBuiltins.length) return;
if (externalBuiltins.length === 0) return;
warn(errMissingNodeBuiltins(externalBuiltins));
warn(errorMissingNodeBuiltins(externalBuiltins));
}

@ -36,7 +36,7 @@ export default function system(
snippets
);
const registeredName = name ? `'${name}',${_}` : '';
const wrapperParams = accessedGlobals.has('module')
const wrapperParameters = accessedGlobals.has('module')
? ['exports', 'module']
: hasExports
? ['exports']
@ -47,13 +47,14 @@ export default function system(
let wrapperStart =
`System.register(${registeredName}[` +
dependencies.map(({ importPath }) => `'${importPath}'`).join(`,${_}`) +
`],${_}(${getNonArrowFunctionIntro(wrapperParams, { isAsync: false, name: null })}{${n}${t}${
strict ? "'use strict';" : ''
}` +
`],${_}(${getNonArrowFunctionIntro(wrapperParameters, {
isAsync: false,
name: null
})}{${n}${t}${strict ? "'use strict';" : ''}` +
getStarExcludesBlock(starExcludes, t, snippets) +
getImportBindingsBlock(importBindings, t, snippets) +
`${n}${t}return${_}{${
setters.length
setters.length > 0
? `${n}${t}${t}setters:${_}[${setters
.map(setter =>
setter
@ -180,7 +181,7 @@ const getStarExcludesBlock = (
): string =>
starExcludes
? `${n}${t}${cnst} _starExcludes${_}=${_}${getObject(
[...starExcludes].map(prop => [prop, '1']),
[...starExcludes].map(property => [property, '1']),
{ lineBreakIndent: { base: t, t } }
)};`
: '';
@ -189,7 +190,7 @@ const getImportBindingsBlock = (
importBindings: readonly string[],
t: string,
{ _, n }: GenerateCodeSnippets
): string => (importBindings.length ? `${n}${t}var ${importBindings.join(`,${_}`)};` : '');
): string => (importBindings.length > 0 ? `${n}${t}var ${importBindings.join(`,${_}`)};` : '');
const getHoistedExportsBlock = (
exports: ChunkExports,

@ -1,6 +1,6 @@
import type { Bundle as MagicStringBundle } from 'magic-string';
import type { NormalizedOutputOptions } from '../rollup/types';
import { errMissingNameOptionForUmdExport, error } from '../utils/error';
import { error, errorMissingNameOptionForUmdExport } from '../utils/error';
import type { GenerateCodeSnippets } from '../utils/generateCodeSnippets';
import getCompleteAmdId from './shared/getCompleteAmdId';
import { getExportBlock, getNamespaceMarkers } from './shared/getExportBlock';
@ -12,21 +12,21 @@ import updateExtensionForRelativeAmdId from './shared/updateExtensionForRelative
import warnOnBuiltins from './shared/warnOnBuiltins';
import type { FinaliserOptions } from './index';
function globalProp(
function globalProperty(
name: string | false | undefined,
globalVar: string,
globalVariable: string,
getPropertyAccess: (name: string) => string
) {
if (!name) return 'null';
return `${globalVar}${keypath(name, getPropertyAccess)}`;
return `${globalVariable}${keypath(name, getPropertyAccess)}`;
}
function safeAccess(
name: string,
globalVar: string,
globalVariable: string,
{ _, getPropertyAccess }: GenerateCodeSnippets
) {
let propertyPath = globalVar;
let propertyPath = globalVariable;
return name
.split('.')
.map(part => (propertyPath += getPropertyAccess(part)))
@ -65,11 +65,11 @@ export default function umd(
}: NormalizedOutputOptions
): void {
const { _, cnst, getFunctionIntro, getNonArrowFunctionIntro, getPropertyAccess, n, s } = snippets;
const factoryVar = compact ? 'f' : 'factory';
const globalVar = compact ? 'g' : 'global';
const factoryVariable = compact ? 'f' : 'factory';
const globalVariable = compact ? 'g' : 'global';
if (hasExports && !name) {
return error(errMissingNameOptionForUmdExport());
return error(errorMissingNameOptionForUmdExport());
}
warnOnBuiltins(onwarn, dependencies);
@ -81,9 +81,9 @@ export default function umd(
const trimmedImports = trimEmptyImports(dependencies);
const globalDeps = trimmedImports.map(module =>
globalProp(module.globalName, globalVar, getPropertyAccess)
globalProperty(module.globalName, globalVariable, getPropertyAccess)
);
const factoryParams = trimmedImports.map(m => m.name);
const factoryParameters = trimmedImports.map(m => m.name);
if (namedExportsMode && (hasExports || noConflict)) {
amdDeps.unshift(`'exports'`);
@ -91,20 +91,22 @@ export default function umd(
globalDeps.unshift(
assignToDeepVariable(
name!,
globalVar,
globalVariable,
globals,
`${extend ? `${globalProp(name!, globalVar, getPropertyAccess)}${_}||${_}` : ''}{}`,
`${
extend ? `${globalProperty(name!, globalVariable, getPropertyAccess)}${_}||${_}` : ''
}{}`,
snippets
)
);
factoryParams.unshift('exports');
factoryParameters.unshift('exports');
}
const completeAmdId = getCompleteAmdId(amd, id);
const amdParams =
const amdParameters =
(completeAmdId ? `'${completeAmdId}',${_}` : ``) +
(amdDeps.length ? `[${amdDeps.join(`,${_}`)}],${_}` : ``);
(amdDeps.length > 0 ? `[${amdDeps.join(`,${_}`)}],${_}` : ``);
const define = amd.define;
const cjsExport = !namedExportsMode && hasExports ? `module.exports${_}=${_}` : ``;
@ -113,67 +115,67 @@ export default function umd(
let iifeExport;
if (noConflict) {
const noConflictExportsVar = compact ? 'e' : 'exports';
const noConflictExportsVariable = compact ? 'e' : 'exports';
let factory;
if (!namedExportsMode && hasExports) {
factory = `${cnst} ${noConflictExportsVar}${_}=${_}${assignToDeepVariable(
factory = `${cnst} ${noConflictExportsVariable}${_}=${_}${assignToDeepVariable(
name!,
globalVar,
globalVariable,
globals,
`${factoryVar}(${globalDeps.join(`,${_}`)})`,
`${factoryVariable}(${globalDeps.join(`,${_}`)})`,
snippets
)};`;
} else {
const module = globalDeps.shift();
factory =
`${cnst} ${noConflictExportsVar}${_}=${_}${module};${n}` +
`${t}${t}${factoryVar}(${[noConflictExportsVar].concat(globalDeps).join(`,${_}`)});`;
`${cnst} ${noConflictExportsVariable}${_}=${_}${module};${n}` +
`${t}${t}${factoryVariable}(${[noConflictExportsVariable, ...globalDeps].join(`,${_}`)});`;
}
iifeExport =
`(${getFunctionIntro([], { isAsync: false, name: null })}{${n}` +
`${t}${t}${cnst} current${_}=${_}${safeAccess(name!, globalVar, snippets)};${n}` +
`${t}${t}${cnst} current${_}=${_}${safeAccess(name!, globalVariable, snippets)};${n}` +
`${t}${t}${factory}${n}` +
`${t}${t}${noConflictExportsVar}.noConflict${_}=${_}${getFunctionIntro([], {
`${t}${t}${noConflictExportsVariable}.noConflict${_}=${_}${getFunctionIntro([], {
isAsync: false,
name: null
})}{${_}` +
`${globalProp(
`${globalProperty(
name!,
globalVar,
globalVariable,
getPropertyAccess
)}${_}=${_}current;${_}return ${noConflictExportsVar}${s}${_}};${n}` +
)}${_}=${_}current;${_}return ${noConflictExportsVariable}${s}${_}};${n}` +
`${t}})()`;
} else {
iifeExport = `${factoryVar}(${globalDeps.join(`,${_}`)})`;
iifeExport = `${factoryVariable}(${globalDeps.join(`,${_}`)})`;
if (!namedExportsMode && hasExports) {
iifeExport = assignToDeepVariable(name!, globalVar, globals, iifeExport, snippets);
iifeExport = assignToDeepVariable(name!, globalVariable, globals, iifeExport, snippets);
}
}
const iifeNeedsGlobal = hasExports || (noConflict && namedExportsMode) || globalDeps.length > 0;
const wrapperParams: string[] = [factoryVar];
const wrapperParameters: string[] = [factoryVariable];
if (iifeNeedsGlobal) {
wrapperParams.unshift(globalVar);
wrapperParameters.unshift(globalVariable);
}
const globalArg = iifeNeedsGlobal ? `this,${_}` : '';
const globalArgument = iifeNeedsGlobal ? `this,${_}` : '';
const iifeStart = iifeNeedsGlobal
? `(${globalVar}${_}=${_}typeof globalThis${_}!==${_}'undefined'${_}?${_}globalThis${_}:${_}${globalVar}${_}||${_}self,${_}`
? `(${globalVariable}${_}=${_}typeof globalThis${_}!==${_}'undefined'${_}?${_}globalThis${_}:${_}${globalVariable}${_}||${_}self,${_}`
: '';
const iifeEnd = iifeNeedsGlobal ? ')' : '';
const cjsIntro = iifeNeedsGlobal
? `${t}typeof exports${_}===${_}'object'${_}&&${_}typeof module${_}!==${_}'undefined'${_}?` +
`${_}${cjsExport}${factoryVar}(${cjsDeps.join(`,${_}`)})${_}:${n}`
`${_}${cjsExport}${factoryVariable}(${cjsDeps.join(`,${_}`)})${_}:${n}`
: '';
const wrapperIntro =
`(${getNonArrowFunctionIntro(wrapperParams, { isAsync: false, name: null })}{${n}` +
`(${getNonArrowFunctionIntro(wrapperParameters, { isAsync: false, name: null })}{${n}` +
cjsIntro +
`${t}typeof ${define}${_}===${_}'function'${_}&&${_}${define}.amd${_}?${_}${define}(${amdParams}${factoryVar})${_}:${n}` +
`${t}typeof ${define}${_}===${_}'function'${_}&&${_}${define}.amd${_}?${_}${define}(${amdParameters}${factoryVariable})${_}:${n}` +
`${t}${iifeStart}${iifeExport}${iifeEnd};${n}` +
// factory function should be wrapped by parentheses to avoid lazy parsing,
// cf. https://v8.dev/blog/preparser#pife
`})(${globalArg}(${getNonArrowFunctionIntro(factoryParams, {
`})(${globalArgument}(${getNonArrowFunctionIntro(factoryParameters, {
isAsync: false,
name: null
})}{${useStrict}${n}`;

@ -5,10 +5,11 @@ import type { PluginDriver } from '../utils/PluginDriver';
import { getSortedValidatedPlugins } from '../utils/PluginDriver';
import { ensureArray } from '../utils/ensureArray';
import {
errAlreadyClosed,
errCannotEmitFromOptionsHook,
errMissingFileOrDirOption,
error
error,
errorAlreadyClosed,
errorCannotEmitFromOptionsHook,
// eslint-disable-next-line unicorn/prevent-abbreviations
errorMissingFileOrDirOption
} from '../utils/error';
import { promises as fs } from '../utils/fs';
import { catchUnfinishedHookActions } from '../utils/hookActions';
@ -61,14 +62,14 @@ export async function rollupInternal(
await graph.pluginDriver.hookParallel('buildStart', [inputOptions]);
timeEnd('initialize', 2);
await graph.build();
} catch (err: any) {
} catch (error_: any) {
const watchFiles = Object.keys(graph.watchFiles);
if (watchFiles.length > 0) {
err.watchFiles = watchFiles;
error_.watchFiles = watchFiles;
}
await graph.pluginDriver.hookParallel('buildEnd', [err]);
await graph.pluginDriver.hookParallel('buildEnd', [error_]);
await graph.pluginDriver.hookParallel('closeBundle', []);
throw err;
throw error_;
}
await graph.pluginDriver.hookParallel('buildEnd', []);
});
@ -86,7 +87,7 @@ export async function rollupInternal(
},
closed: false,
async generate(rawOutputOptions: OutputOptions) {
if (result.closed) return error(errAlreadyClosed());
if (result.closed) return error(errorAlreadyClosed());
return handleGenerateWrite(
false,
@ -98,7 +99,7 @@ export async function rollupInternal(
},
watchFiles: Object.keys(graph.watchFiles),
async write(rawOutputOptions: OutputOptions) {
if (result.closed) return error(errAlreadyClosed());
if (result.closed) return error(errorAlreadyClosed());
return handleGenerateWrite(
true,
@ -147,11 +148,11 @@ function applyOptionHook(watchMode: boolean) {
}
function normalizePlugins(plugins: readonly Plugin[], anonymousPrefix: string): void {
plugins.forEach((plugin, index) => {
for (const [index, plugin] of plugins.entries()) {
if (!plugin.name) {
plugin.name = `${anonymousPrefix}${index + 1}`;
}
});
}
}
function handleGenerateWrite(
@ -177,7 +178,7 @@ function handleGenerateWrite(
if (isWrite) {
timeStart('WRITE', 1);
if (!outputOptions.dir && !outputOptions.file) {
return error(errMissingFileOrDirOption());
return error(errorMissingFileOrDirOption());
}
await Promise.all(
Object.values(generated).map(chunk =>
@ -226,7 +227,7 @@ function getOutputOptions(
[rawOutputOptions.output || rawOutputOptions] as [OutputOptions],
(outputOptions, result) => result || outputOptions,
pluginContext => {
const emitError = () => pluginContext.error(errCannotEmitFromOptionsHook());
const emitError = () => pluginContext.error(errorCannotEmitFromOptionsHook());
return {
...pluginContext,
emitFile: emitError,

@ -176,7 +176,7 @@ export interface PluginContext extends MinimalPluginContext {
addWatchFile: (id: string) => void;
cache: PluginCache;
emitFile: EmitFile;
error: (err: RollupError | string, pos?: number | { column: number; line: number }) => never;
error: (error: RollupError | string, pos?: number | { column: number; line: number }) => never;
getFileName: (fileReferenceId: string) => string;
getModuleIds: () => IterableIterator<string>;
getModuleInfo: GetModuleInfo;
@ -287,7 +287,7 @@ export type ResolveDynamicImportHook = (
export type ResolveImportMetaHook = (
this: PluginContext,
prop: string | null,
property: string | null,
options: { chunkId: string; format: InternalModuleFormat; moduleId: string }
) => string | null | void;
@ -335,7 +335,7 @@ export interface OutputBundle {
export interface FunctionPluginHooks {
augmentChunkHash: (this: PluginContext, chunk: RenderedChunk) => string | void;
buildEnd: (this: PluginContext, err?: Error) => void;
buildEnd: (this: PluginContext, error?: Error) => void;
buildStart: (this: PluginContext, options: NormalizedInputOptions) => void;
closeBundle: (this: PluginContext) => void;
closeWatcher: (this: PluginContext) => void;
@ -359,7 +359,7 @@ export interface FunctionPluginHooks {
targetModuleId: string | null;
}
) => { left: string; right: string } | null | void;
renderError: (this: PluginContext, err?: Error) => void;
renderError: (this: PluginContext, error?: Error) => void;
renderStart: (
this: PluginContext,
outputOptions: NormalizedOutputOptions,
@ -426,8 +426,11 @@ export type ParallelPluginHooks = Exclude<
export type AddonHooks = 'banner' | 'footer' | 'intro' | 'outro';
type MakeAsync<Fn> = Fn extends (this: infer This, ...args: infer Args) => infer Return
? (this: This, ...args: Args) => Return | Promise<Return>
type MakeAsync<Function_> = Function_ extends (
this: infer This,
...parameters: infer Arguments
) => infer Return
? (this: This, ...parameters: Arguments) => Return | Promise<Return>
: never;
// eslint-disable-next-line @typescript-eslint/ban-types
@ -854,13 +857,13 @@ export interface RollupWatchOptions extends InputOptions {
}
export type AwaitedEventListener<
T extends { [event: string]: (...args: any) => any },
T extends { [event: string]: (...parameters: any) => any },
K extends keyof T
> = (...args: Parameters<T[K]>) => void | Promise<void>;
> = (...parameters: Parameters<T[K]>) => void | Promise<void>;
export interface AwaitingEventEmitter<T extends { [event: string]: (...args: any) => any }> {
export interface AwaitingEventEmitter<T extends { [event: string]: (...parameters: any) => any }> {
close(): Promise<void>;
emit<K extends keyof T>(event: K, ...args: Parameters<T[K]>): Promise<unknown>;
emit<K extends keyof T>(event: K, ...parameters: Parameters<T[K]>): Promise<unknown>;
/**
* Removes an event listener.
*/
@ -880,7 +883,7 @@ export interface AwaitingEventEmitter<T extends { [event: string]: (...args: any
*/
onCurrentRun<K extends keyof T>(
event: K,
listener: (...args: Parameters<T[K]>) => Promise<ReturnType<T[K]>>
listener: (...parameters: Parameters<T[K]>) => Promise<ReturnType<T[K]>>
): this;
removeAllListeners(): this;
removeListenersForCurrentRun(): this;

@ -10,16 +10,16 @@ import type {
import { BuildPhase } from './buildPhase';
import { createHash } from './crypto';
import {
errAssetNotFinalisedForFileName,
errAssetReferenceIdNotFoundForSetSource,
errAssetSourceAlreadySet,
errChunkNotGeneratedForFileName,
errFailedValidation,
errFileNameConflict,
errFileReferenceIdNotFoundForFilename,
errInvalidRollupPhaseForChunkEmission,
errNoAssetSourceSet,
error
error,
errorAssetNotFinalisedForFileName,
errorAssetReferenceIdNotFoundForSetSource,
errorAssetSourceAlreadySet,
errorChunkNotGeneratedForFileName,
errorFailedValidation,
errorFileNameConflict,
errorFileReferenceIdNotFoundForFilename,
errorInvalidRollupPhaseForChunkEmission,
errorNoAssetSourceSet
} from './error';
import { defaultHashSize } from './hashPlaceholders';
import type { OutputBundleWithPlaceholders } from './outputBundle';
@ -42,14 +42,15 @@ function generateAssetFileName(
: outputOptions.assetFileNames,
'output.assetFileNames',
{
ext: () => extname(emittedName).substring(1),
ext: () => extname(emittedName).slice(1),
extname: () => extname(emittedName),
hash: size =>
createHash()
.update(source)
.digest('hex')
.substring(0, size || defaultHashSize),
name: () => emittedName.substring(0, emittedName.length - extname(emittedName).length)
.slice(0, Math.max(0, size || defaultHashSize)),
name: () =>
emittedName.slice(0, Math.max(0, emittedName.length - extname(emittedName).length))
}
),
bundle
@ -62,7 +63,7 @@ function reserveFileNameInBundle(
warn: WarningHandler
) {
if (bundle[lowercaseBundleKeys].has(fileName.toLowerCase())) {
warn(errFileNameConflict(fileName));
warn(errorFileNameConflict(fileName));
} else {
bundle[fileName] = FILE_PLACEHOLDER;
}
@ -117,7 +118,7 @@ function getValidSource(
if (!(typeof source === 'string' || source instanceof Uint8Array)) {
const assetName = emittedFile.fileName || emittedFile.name || fileReferenceId;
return error(
errFailedValidation(
errorFailedValidation(
`Could not set source for ${
typeof assetName === 'string' ? `asset "${assetName}"` : 'unnamed asset'
}, asset source needs to be a string, Uint8Array or Buffer.`
@ -129,7 +130,7 @@ function getValidSource(
function getAssetFileName(file: ConsumedAsset, referenceId: string): string {
if (typeof file.fileName !== 'string') {
return error(errAssetNotFinalisedForFileName(file.name || referenceId));
return error(errorAssetNotFinalisedForFileName(file.name || referenceId));
}
return file.fileName;
}
@ -145,7 +146,7 @@ function getChunkFileName(
const chunk = facadeChunkByModule.get(file.module!)!;
return chunk.id || chunk.getFileName();
}
return error(errChunkNotGeneratedForFileName(file.fileName || file.name));
return error(errorChunkNotGeneratedForFileName(file.fileName || file.name));
}
interface FileEmitterOutput {
@ -173,7 +174,7 @@ export class FileEmitter {
public emitFile = (emittedFile: unknown): string => {
if (!hasValidType(emittedFile)) {
return error(
errFailedValidation(
errorFailedValidation(
`Emitted files must be of type "asset" or "chunk", received "${
emittedFile && (emittedFile as any).type
}".`
@ -182,7 +183,7 @@ export class FileEmitter {
}
if (!hasValidName(emittedFile)) {
return error(
errFailedValidation(
errorFailedValidation(
`The "fileName" or "name" properties of emitted files must be strings that are neither absolute nor relative paths, received "${
emittedFile.fileName || emittedFile.name
}".`
@ -198,13 +199,13 @@ export class FileEmitter {
public finaliseAssets = (): void => {
for (const [referenceId, emittedFile] of this.filesByReferenceId) {
if (emittedFile.type === 'asset' && typeof emittedFile.fileName !== 'string')
return error(errNoAssetSourceSet(emittedFile.name || referenceId));
return error(errorNoAssetSourceSet(emittedFile.name || referenceId));
}
};
public getFileName = (fileReferenceId: string): string => {
const emittedFile = this.filesByReferenceId.get(fileReferenceId);
if (!emittedFile) return error(errFileReferenceIdNotFoundForFilename(fileReferenceId));
if (!emittedFile) return error(errorFileReferenceIdNotFoundForFilename(fileReferenceId));
if (emittedFile.type === 'chunk') {
return getChunkFileName(emittedFile, this.facadeChunkByModule);
}
@ -213,16 +214,16 @@ export class FileEmitter {
public setAssetSource = (referenceId: string, requestedSource: unknown): void => {
const consumedFile = this.filesByReferenceId.get(referenceId);
if (!consumedFile) return error(errAssetReferenceIdNotFoundForSetSource(referenceId));
if (!consumedFile) return error(errorAssetReferenceIdNotFoundForSetSource(referenceId));
if (consumedFile.type !== 'asset') {
return error(
errFailedValidation(
errorFailedValidation(
`Asset sources can only be set for emitted assets but "${referenceId}" is an emitted chunk.`
)
);
}
if (consumedFile.source !== undefined) {
return error(errAssetSourceAlreadySet(consumedFile.name || referenceId));
return error(errorAssetSourceAlreadySet(consumedFile.name || referenceId));
}
const source = getValidSource(requestedSource, consumedFile, referenceId);
if (this.output) {
@ -264,7 +265,7 @@ export class FileEmitter {
referenceId = createHash()
.update(referenceId || idBase)
.digest('hex')
.substring(0, 8);
.slice(0, 8);
} while (this.filesByReferenceId.has(referenceId));
this.filesByReferenceId.set(referenceId, file);
@ -299,11 +300,11 @@ export class FileEmitter {
private emitChunk(emittedChunk: EmittedFile): string {
if (this.graph.phase > BuildPhase.LOAD_AND_PARSE) {
return error(errInvalidRollupPhaseForChunkEmission());
return error(errorInvalidRollupPhaseForChunkEmission());
}
if (typeof emittedChunk.id !== 'string') {
return error(
errFailedValidation(
errorFailedValidation(
`Emitted chunks need to have a valid string id, received "${emittedChunk.id}"`
)
);

@ -1,5 +1,5 @@
import type { PluginCache, SerializablePluginCache } from '../rollup/types';
import { errAnonymousPluginCache, errDuplicatePluginName, error } from './error';
import { error, errorAnonymousPluginCache, errorDuplicatePluginName } from './error';
import { ANONYMOUS_OUTPUT_PLUGIN_PREFIX, ANONYMOUS_PLUGIN_PREFIX } from './pluginUtils';
export function createPluginCache(cache: SerializablePluginCache): PluginCache {
@ -9,7 +9,7 @@ export function createPluginCache(cache: SerializablePluginCache): PluginCache {
},
get(id: string) {
const item = cache[id];
if (!item) return undefined;
if (!item) return;
item[0] = 0;
return item[1];
},
@ -64,9 +64,9 @@ function uncacheablePluginError(pluginName: string): never {
pluginName.startsWith(ANONYMOUS_PLUGIN_PREFIX) ||
pluginName.startsWith(ANONYMOUS_OUTPUT_PLUGIN_PREFIX)
) {
return error(errAnonymousPluginCache());
return error(errorAnonymousPluginCache());
}
return error(errDuplicatePluginName(pluginName));
return error(errorDuplicatePluginName(pluginName));
}
export function getCacheForUncacheablePlugin(pluginName: string): PluginCache {

@ -12,9 +12,9 @@ import { createPluginCache, getCacheForUncacheablePlugin, NO_CACHE } from './Plu
import { BLANK, EMPTY_OBJECT } from './blank';
import { BuildPhase } from './buildPhase';
import {
errInvalidRollupPhaseForAddWatchFile,
error,
errPluginError,
errorInvalidRollupPhaseForAddWatchFile,
errorPluginError,
warnDeprecation
} from './error';
import { ANONYMOUS_OUTPUT_PLUGIN_PREFIX, ANONYMOUS_PLUGIN_PREFIX } from './pluginUtils';
@ -55,14 +55,14 @@ export function getPluginContext(
return {
addWatchFile(id) {
if (graph.phase >= BuildPhase.GENERATE) {
return this.error(errInvalidRollupPhaseForAddWatchFile());
return this.error(errorInvalidRollupPhaseForAddWatchFile());
}
graph.watchFiles[id] = true;
},
cache: cacheInstance,
emitFile: fileEmitter.emitFile.bind(fileEmitter),
error(err): never {
return error(errPluginError(err, plugin.name));
error(error_): never {
return error(errorPluginError(error_, plugin.name));
},
getFileName: fileEmitter.getFileName,
getModuleIds: () => graph.modulesById.keys(),

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save