Skip to content

Commit

Permalink
Merge branch 'master' into sanitize-windows-files
Browse files Browse the repository at this point in the history
  • Loading branch information
lukastaegert committed Feb 26, 2021
2 parents 7dc1aef + 9b8c94d commit d93d281
Show file tree
Hide file tree
Showing 16 changed files with 131 additions and 68 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,15 @@
# rollup changelog

## 2.39.1
*2021-02-23*

### Bug Fixes
* Make sure local variables named Symbol, Object or Promise do not conflict with code generated by Rollup (#3971)

### Pull Requests
* [#3964](https://github.com/rollup/rollup/pull/3964): Remove extra word (@jamonholmgren)
* [#3971](https://github.com/rollup/rollup/pull/3971): Avoid conflicts with local variables named Symbol, Object, Promise (@lukastaegert)

## 2.39.0
*2021-02-12*

Expand Down
4 changes: 2 additions & 2 deletions docs/01-command-line-reference.md
Expand Up @@ -207,7 +207,7 @@ If you want to switch from config files to using the [JavaScript API](guide/en/#

- When using the JavaScript API, the configuration passed to `rollup.rollup` must be an object and cannot be wrapped in a Promise or a function.
- You can no longer use an array of configurations. Instead, you should run `rollup.rollup` once for each set of `inputOptions`.
- The `output` option will be ignored. Instead, you should run `bundle.generate(outputOptions)` or `bundle.write(outputOptions)` once for each set of `outputOptions`.
- The `output` option will be ignored. Instead, you should run `bundle`<wbr>`.generate(`<wbr>`outputOptions)` or `bundle`<wbr>`.write(`<wbr>`outputOptions)` once for each set of `outputOptions`.

### Loading a configuration from a Node package

Expand Down Expand Up @@ -407,7 +407,7 @@ Pass additional settings to the config file via `process.ENV`.
rollup -c --environment INCLUDE_DEPS,BUILD:production
```

will set `process.env.INCLUDE_DEPS === 'true'` and `process.env.BUILD === 'production'`. You can use this option several times. In that case, subsequently set variables will overwrite previous definitions. This enables you for instance to overwrite environment variables in `package.json` scripts:
will set `process`<wbr>`.env`<wbr>`.INCLUDE_DEPS === 'true'` and `process.env.BUILD === 'production'`. You can use this option several times. In that case, subsequently set variables will overwrite previous definitions. This enables you for instance to overwrite environment variables in `package.json` scripts:

```json
// in package.json
Expand Down
52 changes: 26 additions & 26 deletions docs/05-plugin-development.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/08-troubleshooting.md
Expand Up @@ -2,7 +2,7 @@
title: Troubleshooting
---

If you get stuck, please try discussing the issue on the [Rollup Discord](https://is.gd/rollup_chat) or posting a question to https://stackoverflow.com/questions/tagged/rollupjs. If you've found a bug, or Rollup can't meet your needs, please try [raising an issue](https://github.com/rollup/rollup/issues). Lastly, you may try contacting [@RollupJS](https://twitter.com/RollupJS) on Twitter.
If you get stuck, please try discussing the issue on the [Rollup Discord](https://is.gd/rollup_chat) or posting a question to [Stackoverflow](https://stackoverflow.com/questions/tagged/rollupjs). If you've found a bug, or Rollup can't meet your needs, please try [raising an issue](https://github.com/rollup/rollup/issues). Lastly, you may try contacting [@RollupJS](https://twitter.com/RollupJS) on Twitter.

### Avoiding `eval`

Expand Down
34 changes: 17 additions & 17 deletions docs/999-big-list-of-options.md
Expand Up @@ -35,7 +35,7 @@ When given as a command line argument, it should be a comma-separated list of ID
rollup -i src/main.js ... -e foo,bar,baz
```

When providing a function, it is actually called with three parameters `(id, parent, isResolved)` that can give you more fine-grained control:
When providing a function, it is called with three parameters `(id, parent, isResolved)` that can give you more fine-grained control:

* `id` is the id of the module in question
* `parent` is the id of the module doing the import
Expand Down Expand Up @@ -467,7 +467,7 @@ console.log(ext_default, external.bar, external);
import('external2').then(console.log);
```

Keep in mind that for Rollup, `import * as ext_namespace from 'external'; console.log(ext_namespace.bar);` is completely equivalent to `import {bar} from 'external'; console.log(bar);` and will produce the same code. In the example above however, the namespace object itself is passed to a global function as well, which means we need it as a properly formed object.
Keep in mind that for Rollup, `import * as ext_namespace from 'external'; console`<wbr>`.log(`<wbr>`ext_namespace`<wbr>`.bar);` is completely equivalent to `import {bar} from 'external'; console.log(bar);` and will produce the same code. In the example above however, the namespace object itself is passed to a global function as well, which means we need it as a properly formed object.

- `"esModule"` assumes that required modules are transpiled ES modules where the required value corresponds to the module namespace, and the default export is the `.default` property of the exported object:

Expand Down Expand Up @@ -888,7 +888,7 @@ Default: `false`

If `true`, a separate sourcemap file will be created. If `"inline"`, the sourcemap will be appended to the resulting `output` file as a data URI. `"hidden"` works like `true` except that the corresponding sourcemap comments in the bundled files are suppressed.

#### output.sourcemapExcludeSources
#### output<wbr>.sourcemapExcludeSources
Type: `boolean`<br>
CLI: `--sourcemapExcludeSources`/`--no-sourcemapExcludeSources`<br>
Default: `false`
Expand All @@ -903,7 +903,7 @@ The location of the generated bundle. If this is an absolute path, all the `sour

`sourcemapFile` is not required if `output` is specified, in which case an output filename will be inferred by adding ".map" to the output filename for the bundle.

#### output.sourcemapPathTransform
#### output<wbr>.sourcemapPathTransform
Type: `(relativeSourcePath: string, sourcemapPath: string) => string`

A transformation to apply to each path in a sourcemap. `relativeSourcePath` is a relative path from the generated `.map` file to the corresponding source file while `sourcemapPath` is the fully resolved path of the generated sourcemap file.
Expand Down Expand Up @@ -1276,7 +1276,7 @@ export default {
};
```

#### output.namespaceToStringTag
#### output<wbr>.namespaceToStringTag
Type: `boolean`<br>
CLI: `--namespaceToStringTag`/`--no-namespaceToStringTag`<br>
Default: `false`
Expand Down Expand Up @@ -1466,9 +1466,9 @@ console.log(foo);

Note that despite the name, this option does not "add" side effects to modules that do not have side effects. If it is important that e.g. an empty module is "included" in the bundle because you need this for dependency tracking, the plugin interface allows you to designate modules as being excluded from tree-shaking via the [`resolveId`](guide/en/#resolveid), [`load`](guide/en/#load) or [`transform`](guide/en/#transform) hook.

**treeshake.propertyReadSideEffects**
**treeshake<wbr>.propertyReadSideEffects**
Type: `boolean`<br>
CLI: `--treeshake.propertyReadSideEffects`/`--no-treeshake.propertyReadSideEffects`<br>
CLI: `--treeshake`<wbr>`.propertyReadSideEffects`/`--no-treeshake`<wbr>`.propertyReadSideEffects`<br>
Default: `true`

If `false`, assume reading a property of an object never has side effects. Depending on your code, disabling this option can significantly reduce bundle size but can potentially break functionality if you rely on getters or errors from illegal property access.
Expand All @@ -1485,12 +1485,12 @@ const result = foo.bar;
const illegalAccess = foo.quux.tooDeep;
```

**treeshake.tryCatchDeoptimization**
**treeshake<wbr>.tryCatchDeoptimization**
Type: `boolean`<br>
CLI: `--treeshake.tryCatchDeoptimization`/`--no-treeshake.tryCatchDeoptimization`<br>
CLI: `--treeshake`<wbr>`.tryCatchDeoptimization`/`--no-treeshake`<wbr>`.tryCatchDeoptimization`<br>
Default: `true`

By default, Rollup assumes that many builtin globals of the runtime behave according to the latest specs when tree-shaking and do not throw unexpected errors. In order to support e.g. feature detection workflows that rely on those errors being thrown, Rollup will by default deactivate tree-shaking inside try-statements. If a function parameter is called from within a try-statement, this parameter will be deoptimized as well. Set `treeshake.tryCatchDeoptimization` to `false` if you do not need this feature and want to have tree-shaking inside try-statements.
By default, Rollup assumes that many builtin globals of the runtime behave according to the latest specs when tree-shaking and do not throw unexpected errors. In order to support e.g. feature detection workflows that rely on those errors being thrown, Rollup will by default deactivate tree-shaking inside try-statements. If a function parameter is called from within a try-statement, this parameter will be deoptimized as well. Set `treeshake`<wbr>`.tryCatchDeoptimization` to `false` if you do not need this feature and want to have tree-shaking inside try-statements.

```js
function otherFn() {
Expand Down Expand Up @@ -1525,9 +1525,9 @@ test(otherFn);

```

**treeshake.unknownGlobalSideEffects**
**treeshake<wbr>.unknownGlobalSideEffects**
Type: `boolean`<br>
CLI: `--treeshake.unknownGlobalSideEffects`/`--no-treeshake.unknownGlobalSideEffects`<br>
CLI: `--treeshake`<wbr>`.unknownGlobalSideEffects`/`--no-treeshake`<wbr>`.unknownGlobalSideEffects`<br>
Default: `true`

Since accessing a non-existing global variable will throw an error, Rollup does by default retain any accesses to non-builtin global variables. Set this option to `false` to avoid this check. This is probably safe for most code-bases.
Expand All @@ -1546,7 +1546,7 @@ const element = angular.element;
const element = angular.element;
```

In the example, the last line is always retained as accessing the `element` property could also throw an error if `angular` is e.g. `null`. To avoid this check, set `treeshake.propertyReadSideEffects` to `false` as well.
In the example, the last line is always retained as accessing the `element` property could also throw an error if `angular` is e.g. `null`. To avoid this check, set `treeshake`<wbr>`.propertyReadSideEffects` to `false` as well.

### Experimental options

Expand Down Expand Up @@ -1674,18 +1674,18 @@ _Use the [`output.manualChunks`](guide/en/#outputmanualchunks) output option ins
#### preserveModules
_Use the [`output.preserveModules`](guide/en/#outputpreservemodules) output option instead, which has the same signature._

#### output.dynamicImportFunction
#### output<wbr>.dynamicImportFunction
_Use the [`renderDynamicImport`](guide/en/#renderdynamicimport) plugin hook instead._<br>
Type: `string`<br>
CLI: `--dynamicImportFunction <name>`<br>
Default: `import`

This will rename the dynamic import function to the chosen name when outputting ES bundles. This is useful for generating code that uses a dynamic import polyfill such as [this one](https://github.com/uupaa/dynamic-import-polyfill).

#### treeshake.pureExternalModules
_Use [`treeshake.moduleSideEffects: 'no-external'`](guide/en/#treeshake) instead._<br>
#### treeshake<wbr>.pureExternalModules
_Use [`treeshake`<wbr>`.moduleSideEffects: 'no-external'`](guide/en/#treeshake) instead._<br>
Type: `boolean | string[] | (id: string) => boolean | null`<br>
CLI: `--treeshake.pureExternalModules`/`--no-treeshake.pureExternalModules`<br>
CLI: `--treeshake`<wbr>`.pureExternalModules`/`--no-treeshake`<wbr>`.pureExternalModules`<br>
Default: `false`

If `true`, assume external dependencies from which nothing is imported do not have other side effects like mutating global variables or logging.
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "rollup",
"version": "2.39.0",
"version": "2.39.1",
"description": "Next-generation ES module bundler",
"main": "dist/rollup.js",
"module": "dist/es/rollup.js",
Expand Down
7 changes: 5 additions & 2 deletions src/Chunk.ts
Expand Up @@ -1246,7 +1246,7 @@ export default class Chunk {
}
}

private setIdentifierRenderResolutions({ format, interop }: NormalizedOutputOptions) {
private setIdentifierRenderResolutions({ format, interop, namespaceToStringTag }: NormalizedOutputOptions) {
const syntheticExports = new Set<SyntheticNamedExportVariable>();
for (const exportName of this.getExportNames()) {
const exportVariable = this.exportsByName[exportName];
Expand All @@ -1267,10 +1267,13 @@ export default class Chunk {
}
}

const usedNames = new Set<string>();
const usedNames = new Set<string>(['Object', 'Promise']);
if (this.needsExportsShim) {
usedNames.add(MISSING_EXPORT_SHIM_VARIABLE);
}
if (namespaceToStringTag) {
usedNames.add('Symbol');
}
switch (format) {
case 'system':
usedNames.add('module').add('exports');
Expand Down
36 changes: 18 additions & 18 deletions test/form/samples/supports-core-js/_expected.js
Expand Up @@ -6060,7 +6060,7 @@ var IS_NODE$3 = engineIsNode;
var MutationObserver = global$q.MutationObserver || global$q.WebKitMutationObserver;
var document$2 = global$q.document;
var process$2 = global$q.process;
var Promise = global$q.Promise;
var Promise$1 = global$q.Promise;
// Node.js 11 shows ExperimentalWarning on getting `queueMicrotask`
var queueMicrotaskDescriptor = getOwnPropertyDescriptor$7(global$q, 'queueMicrotask');
var queueMicrotask = queueMicrotaskDescriptor && queueMicrotaskDescriptor.value;
Expand Down Expand Up @@ -6096,9 +6096,9 @@ if (!queueMicrotask) {
node.data = toggle = !toggle;
};
// environments with maybe non-completely correct, but existent Promise
} else if (Promise && Promise.resolve) {
} else if (Promise$1 && Promise$1.resolve) {
// Promise.resolve without an argument throws an error in LG WebOS 2
promise = Promise.resolve(undefined);
promise = Promise$1.resolve(undefined);
then = promise.then;
notify = function () {
then.call(promise, flush);
Expand Down Expand Up @@ -12383,7 +12383,7 @@ var wellKnownSymbol$y = wellKnownSymbol;
var InternalStateModule$h = internalState;
var getBuiltIn$m = getBuiltIn;

var Promise$1 = getBuiltIn$m('Promise');
var Promise$2 = getBuiltIn$m('Promise');

var setInternalState$h = InternalStateModule$h.set;
var getInternalState$e = InternalStateModule$h.get;
Expand All @@ -12394,15 +12394,15 @@ var $return = function (value) {
var iterator = getInternalState$e(this).iterator;
var $$return = iterator['return'];
return $$return === undefined
? Promise$1.resolve({ done: true, value: value })
? Promise$2.resolve({ done: true, value: value })
: anObject$13($$return.call(iterator, value));
};

var $throw = function (value) {
var iterator = getInternalState$e(this).iterator;
var $$throw = iterator['throw'];
return $$throw === undefined
? Promise$1.reject(value)
? Promise$2.reject(value)
: $$throw.call(iterator, value);
};

Expand All @@ -12416,11 +12416,11 @@ var asyncIteratorCreateProxy = function (nextHandler, IS_ITERATOR) {
AsyncIteratorProxy.prototype = redefineAll$8(create$b(path$3.AsyncIterator.prototype), {
next: function next(arg) {
var state = getInternalState$e(this);
if (state.done) return Promise$1.resolve({ done: true, value: undefined });
if (state.done) return Promise$2.resolve({ done: true, value: undefined });
try {
return Promise$1.resolve(anObject$13(nextHandler.call(state, arg, Promise$1)));
return Promise$2.resolve(anObject$13(nextHandler.call(state, arg, Promise$2)));
} catch (error) {
return Promise$1.reject(error);
return Promise$2.reject(error);
}
},
'return': $return,
Expand Down Expand Up @@ -12507,7 +12507,7 @@ var aFunction$x = aFunction$1;
var anObject$16 = anObject;
var getBuiltIn$n = getBuiltIn;

var Promise$2 = getBuiltIn$n('Promise');
var Promise$3 = getBuiltIn$n('Promise');
var push$2 = [].push;

var createMethod$7 = function (TYPE) {
Expand All @@ -12521,12 +12521,12 @@ var createMethod$7 = function (TYPE) {
var array = IS_TO_ARRAY ? [] : undefined;
if (!IS_TO_ARRAY) aFunction$x(fn);

return new Promise$2(function (resolve, reject) {
return new Promise$3(function (resolve, reject) {
var closeIteration = function (method, argument) {
try {
var returnMethod = iterator['return'];
if (returnMethod !== undefined) {
return Promise$2.resolve(returnMethod.call(iterator)).then(function () {
return Promise$3.resolve(returnMethod.call(iterator)).then(function () {
method(argument);
}, function (error) {
reject(error);
Expand All @@ -12543,7 +12543,7 @@ var createMethod$7 = function (TYPE) {

var loop = function () {
try {
Promise$2.resolve(anObject$16(next.call(iterator))).then(function (step) {
Promise$3.resolve(anObject$16(next.call(iterator))).then(function (step) {
try {
if (anObject$16(step).done) {
resolve(IS_TO_ARRAY ? array : IS_SOME ? false : IS_EVERY || undefined);
Expand All @@ -12553,7 +12553,7 @@ var createMethod$7 = function (TYPE) {
push$2.call(array, value);
loop();
} else {
Promise$2.resolve(fn(value)).then(function (result) {
Promise$3.resolve(fn(value)).then(function (result) {
if (IS_FOR_EACH) {
loop();
} else if (IS_EVERY) {
Expand Down Expand Up @@ -12798,7 +12798,7 @@ var aFunction$C = aFunction$1;
var anObject$1b = anObject;
var getBuiltIn$o = getBuiltIn;

var Promise$3 = getBuiltIn$o('Promise');
var Promise$4 = getBuiltIn$o('Promise');

$$3z({ target: 'AsyncIterator', proto: true, real: true }, {
reduce: function reduce(reducer /* , initialValue */) {
Expand All @@ -12808,10 +12808,10 @@ $$3z({ target: 'AsyncIterator', proto: true, real: true }, {
var accumulator = noInitial ? undefined : arguments[1];
aFunction$C(reducer);

return new Promise$3(function (resolve, reject) {
return new Promise$4(function (resolve, reject) {
var loop = function () {
try {
Promise$3.resolve(anObject$1b(next.call(iterator))).then(function (step) {
Promise$4.resolve(anObject$1b(next.call(iterator))).then(function (step) {
try {
if (anObject$1b(step).done) {
noInitial ? reject(TypeError('Reduce of empty iterator with no initial value')) : resolve(accumulator);
Expand All @@ -12822,7 +12822,7 @@ $$3z({ target: 'AsyncIterator', proto: true, real: true }, {
accumulator = value;
loop();
} else {
Promise$3.resolve(reducer(accumulator, value)).then(function (result) {
Promise$4.resolve(reducer(accumulator, value)).then(function (result) {
accumulator = result;
loop();
}, reject);
Expand Down
20 changes: 20 additions & 0 deletions test/function/samples/name-conflict-object/_config.js
@@ -0,0 +1,20 @@
const assert = require('assert');

module.exports = {
description: 'avoids name conflicts with local variables named Object',
options: {
external: 'external',
output: { exports: 'named' }
},
context: {
require() {
return { foo: 'foo' };
}
},
exports(exports) {
assert.strictEqual(exports.Object, null);
assert.strictEqual(exports.default, 'bar');
assert.strictEqual(exports.foo.foo, 'foo');
assert.strictEqual(exports.foo.default.foo, 'foo');
}
};
3 changes: 3 additions & 0 deletions test/function/samples/name-conflict-object/main.js
@@ -0,0 +1,3 @@
export * as foo from 'external';
export const Object = null;
export default 'bar';
9 changes: 9 additions & 0 deletions test/function/samples/name-conflict-promise/_config.js
@@ -0,0 +1,9 @@
const assert = require('assert');

module.exports = {
description: 'avoids name conflicts with local variables named Promise',
async exports(exports) {
assert.strictEqual(exports.Promise, 'bar');
assert.strictEqual((await exports.promised).Promise, 'foo');
}
};
1 change: 1 addition & 0 deletions test/function/samples/name-conflict-promise/dep.js
@@ -0,0 +1 @@
export const Promise = 'foo';
2 changes: 2 additions & 0 deletions test/function/samples/name-conflict-promise/main.js
@@ -0,0 +1,2 @@
export const Promise = 'bar';
export const promised = import('./dep');
14 changes: 14 additions & 0 deletions test/function/samples/name-conflict-symbol/_config.js
@@ -0,0 +1,14 @@
const assert = require('assert');

module.exports = {
description: 'avoids name conflicts with local variables named Symbol',
options: {
output: {
namespaceToStringTag: true
}
},
exports(exports) {
assert.strictEqual(exports.Symbol, null);
assert.strictEqual(exports.toString(), '[object Module]');
}
};
1 change: 1 addition & 0 deletions test/function/samples/name-conflict-symbol/main.js
@@ -0,0 +1 @@
export const Symbol = null;

0 comments on commit d93d281

Please sign in to comment.