Skip to content
This repository was archived by the owner on Aug 4, 2021. It is now read-only.

Commit c8fabd7

Browse files
authored
Use new context functions, fix issue when resolveId returns an object (#387)
* Update dependencies * Transform to new plugin hooks * Use Sets, remove a micro task * Make transform hook sync * Switch to using a Map again * Refine CJS Promise handling * Switch from buble to babel, add Node 6 and 12 tests * Get rid of Node12 for now until we figured out how to rewrite tests with globals * Use external "is-reference" * Change format of proxy ids to `\0file/path?commonjs-proxy` * Update dependencies * fix tests * Remove Node 6 again from tests
1 parent 851ed8e commit c8fabd7

File tree

23 files changed

+1615
-539
lines changed

23 files changed

+1615
-539
lines changed

.travis.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ node_js:
66
env:
77
global:
88
- BUILD_TIMEOUT=10000
9-
install: npm install
9+
install: npm ci --ignore-scripts
10+
before_install:
11+
- if [[ $TRAVIS_NODE_VERSION -lt 8 ]]; then npm install --global npm@5; fi

package-lock.json

+1,432-316
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+18-13
Original file line numberDiff line numberDiff line change
@@ -22,31 +22,36 @@
2222
"README.md"
2323
],
2424
"peerDependencies": {
25-
"rollup": ">=0.56.0"
25+
"rollup": ">=1.12.0"
2626
},
2727
"dependencies": {
2828
"estree-walker": "^0.6.0",
29+
"is-reference": "^1.1.2",
2930
"magic-string": "^0.25.2",
30-
"resolve": "^1.10.0",
31-
"rollup-pluginutils": "^2.6.0"
31+
"resolve": "^1.10.1",
32+
"rollup-pluginutils": "^2.7.0"
3233
},
3334
"devDependencies": {
35+
"@babel/core": "7.4.4",
36+
"@babel/preset-env": "^7.4.4",
37+
"@babel/register": "^7.4.4",
3438
"acorn": "^6.1.1",
3539
"eslint": "^5.16.0",
36-
"eslint-plugin-import": "^2.16.0",
37-
"husky": "^1.3.1",
38-
"lint-staged": "^8.1.5",
40+
"eslint-plugin-import": "^2.17.2",
41+
"husky": "^2.3.0",
42+
"lint-staged": "^8.1.7",
3943
"locate-character": "^2.0.5",
40-
"mocha": "^6.0.2",
41-
"prettier": "^1.16.4",
44+
"mocha": "^6.1.4",
45+
"prettier": "^1.17.1",
4246
"require-relative": "^0.8.7",
43-
"rollup": "^1.8.0",
44-
"rollup-plugin-buble": "^0.19.6",
45-
"rollup-plugin-node-resolve": "^4.0.1",
47+
"rollup": "^1.12.0",
48+
"rollup-plugin-babel": "^4.3.2",
49+
"rollup-plugin-json": "^4.0.0",
50+
"rollup-plugin-node-resolve": "^4.2.4",
4651
"shx": "^0.3.2",
4752
"source-map": "^0.7.3",
48-
"source-map-support": "^0.5.11",
49-
"typescript": "^3.4.1"
53+
"source-map-support": "^0.5.12",
54+
"typescript": "^3.4.5"
5055
},
5156
"repository": "rollup/rollup-plugin-commonjs",
5257
"author": "Rich Harris",

rollup.config.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1-
import buble from 'rollup-plugin-buble';
1+
import babel from 'rollup-plugin-babel';
2+
import json from 'rollup-plugin-json';
23
import pkg from './package.json';
34

45
export default {
56
input: 'src/index.js',
67
plugins: [
7-
buble({
8-
transforms: { dangerousForOf: true }
8+
json(),
9+
babel({
10+
presets: [['@babel/preset-env', {
11+
targets: {
12+
node: 6
13+
}
14+
}]]
915
})
1016
],
1117
external: Object.keys( pkg.dependencies ).concat([ 'fs', 'path' ]),

src/ast-utils.js

+1-14
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,4 @@
1-
export function isReference(node, parent) {
2-
if (parent.type === 'MemberExpression') return parent.computed || node === parent.object;
3-
4-
// disregard the `bar` in { bar: foo }
5-
if (parent.type === 'Property' && node !== parent.value) return false;
6-
7-
// disregard the `bar` in `class Foo { bar () {...} }`
8-
if (parent.type === 'MethodDefinition') return false;
9-
10-
// disregard the `bar` in `export { foo as bar }`
11-
if (parent.type === 'ExportSpecifier' && node !== parent.local) return false;
12-
13-
return true;
14-
}
1+
export {default as isReference} from 'is-reference';
152

163
export function flatten(node) {
174
const parts = [];

src/default-resolver.js

-39
This file was deleted.

src/helpers.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1-
export const PROXY_PREFIX = '\0commonjs-proxy-';
2-
export const EXTERNAL_PREFIX = '\0commonjs-external-';
1+
export const PROXY_SUFFIX = '?commonjs-proxy';
2+
export const getProxyId = id => `\0${id}${PROXY_SUFFIX}`;
3+
export const getIdFromProxyId = proxyId => proxyId.slice(1, -PROXY_SUFFIX.length);
4+
5+
export const EXTERNAL_SUFFIX = '?commonjs-external';
6+
export const getExternalProxyId = id => `\0${id}${EXTERNAL_SUFFIX}`;
7+
export const getIdFromExternalProxyId = proxyId => proxyId.slice(1, -EXTERNAL_SUFFIX.length);
8+
39
export const HELPERS_ID = '\0commonjsHelpers.js';
410

511
// `x['default']` is used instead of `x.default` for backward compatibility with ES3 browsers.

src/index.js

+66-61
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { extname, resolve } from 'path';
22
import { sync as nodeResolveSync } from 'resolve';
33
import { createFilter } from 'rollup-pluginutils';
4-
import { EXTERNAL_PREFIX, HELPERS, HELPERS_ID, PROXY_PREFIX } from './helpers.js';
4+
import { peerDependencies } from '../package.json';
5+
import { EXTERNAL_SUFFIX, getIdFromExternalProxyId, getIdFromProxyId, HELPERS, HELPERS_ID, PROXY_SUFFIX } from './helpers';
56
import { getIsCjsPromise, setIsCjsPromise } from './is-cjs';
67
import { getResolveId } from './resolve-id';
78
import { checkEsModule, hasCjsKeywords, transformCommonjs } from './transform.js';
@@ -27,8 +28,8 @@ export default function commonjs(options = {}) {
2728
});
2829
}
2930

30-
const esModulesWithoutDefaultExport = Object.create(null);
31-
const esModulesWithDefaultExport = Object.create(null);
31+
const esModulesWithoutDefaultExport = new Set();
32+
const esModulesWithDefaultExport = new Set();
3233
const allowDynamicRequire = !!options.ignore; // TODO maybe this should be configurable?
3334

3435
const ignoreRequire =
@@ -38,24 +39,59 @@ export default function commonjs(options = {}) {
3839
? id => options.ignore.includes(id)
3940
: () => false;
4041

41-
let entryModuleIdsPromise = null;
42-
4342
const resolveId = getResolveId(extensions);
4443

4544
const sourceMap = options.sourceMap !== false;
4645

46+
function transformAndCheckExports(code, id) {
47+
{
48+
const { isEsModule, hasDefaultExport, ast } = checkEsModule(this.parse, code, id);
49+
if (isEsModule) {
50+
(hasDefaultExport ? esModulesWithDefaultExport : esModulesWithoutDefaultExport).add(id);
51+
return null;
52+
}
53+
54+
// it is not an ES module but it does not have CJS-specific elements.
55+
if (!hasCjsKeywords(code, ignoreGlobal)) {
56+
esModulesWithoutDefaultExport.add(id);
57+
return null;
58+
}
59+
60+
const transformed = transformCommonjs(
61+
this.parse,
62+
code,
63+
id,
64+
this.getModuleInfo(id).isEntry,
65+
ignoreGlobal,
66+
ignoreRequire,
67+
customNamedExports[id],
68+
sourceMap,
69+
allowDynamicRequire,
70+
ast
71+
);
72+
if (!transformed) {
73+
esModulesWithoutDefaultExport.add(id);
74+
return null;
75+
}
76+
77+
return transformed;
78+
}
79+
}
80+
4781
return {
4882
name: 'commonjs',
4983

50-
options(options) {
51-
resolveId.setRollupOptions(options);
52-
const input = options.input || options.entry;
53-
const entryModules = Array.isArray(input)
54-
? input
55-
: typeof input === 'object' && input !== null
56-
? Object.values(input)
57-
: [input];
58-
entryModuleIdsPromise = Promise.all(entryModules.map(entry => resolveId(entry)));
84+
buildStart() {
85+
const [major, minor] = this.meta.rollupVersion.split('.').map(Number);
86+
const minVersion = peerDependencies.rollup.slice(2);
87+
const [minMajor, minMinor] = minVersion.split('.').map(Number);
88+
if (major < minMajor || (major === minMajor && minor < minMinor)) {
89+
this.error(
90+
`Insufficient Rollup version: "rollup-plugin-commonjs" requires at least rollup@${minVersion} but found rollup@${
91+
this.meta.rollupVersion
92+
}.`
93+
);
94+
}
5995
},
6096

6197
resolveId,
@@ -64,25 +100,25 @@ export default function commonjs(options = {}) {
64100
if (id === HELPERS_ID) return HELPERS;
65101

66102
// generate proxy modules
67-
if (id.startsWith(EXTERNAL_PREFIX)) {
68-
const actualId = id.slice(EXTERNAL_PREFIX.length);
103+
if (id.endsWith(EXTERNAL_SUFFIX)) {
104+
const actualId = getIdFromExternalProxyId(id);
69105
const name = getName(actualId);
70106

71107
return `import ${name} from ${JSON.stringify(actualId)}; export default ${name};`;
72108
}
73109

74-
if (id.startsWith(PROXY_PREFIX)) {
75-
const actualId = id.slice(PROXY_PREFIX.length);
110+
if (id.endsWith(PROXY_SUFFIX)) {
111+
const actualId = getIdFromProxyId(id);
76112
const name = getName(actualId);
77113

78114
return getIsCjsPromise(actualId).then(isCjs => {
79115
if (isCjs)
80116
return `import { __moduleExports } from ${JSON.stringify(
81117
actualId
82118
)}; export default __moduleExports;`;
83-
else if (esModulesWithoutDefaultExport[actualId])
119+
else if (esModulesWithoutDefaultExport.has(actualId))
84120
return `import * as ${name} from ${JSON.stringify(actualId)}; export default ${name};`;
85-
else if (esModulesWithDefaultExport[actualId]) {
121+
else if (esModulesWithDefaultExport.has(actualId)) {
86122
return `export {default} from ${JSON.stringify(actualId)};`;
87123
} else
88124
return `import * as ${name} from ${JSON.stringify(
@@ -94,51 +130,20 @@ export default function commonjs(options = {}) {
94130

95131
transform(code, id) {
96132
if (!filter(id) || extensions.indexOf(extname(id)) === -1) {
97-
setIsCjsPromise(id, Promise.resolve(null));
133+
setIsCjsPromise(id, null);
98134
return null;
99135
}
100136

101-
const transformPromise = entryModuleIdsPromise
102-
.then(entryModuleIds => {
103-
const { isEsModule, hasDefaultExport, ast } = checkEsModule(this.parse, code, id);
104-
if (isEsModule) {
105-
(hasDefaultExport ? esModulesWithDefaultExport : esModulesWithoutDefaultExport)[
106-
id
107-
] = true;
108-
return null;
109-
}
110-
111-
// it is not an ES module but it does not have CJS-specific elements.
112-
if (!hasCjsKeywords(code, ignoreGlobal)) {
113-
esModulesWithoutDefaultExport[id] = true;
114-
return null;
115-
}
116-
117-
const transformed = transformCommonjs(
118-
this.parse,
119-
code,
120-
id,
121-
entryModuleIds.indexOf(id) !== -1,
122-
ignoreGlobal,
123-
ignoreRequire,
124-
customNamedExports[id],
125-
sourceMap,
126-
allowDynamicRequire,
127-
ast
128-
);
129-
if (!transformed) {
130-
esModulesWithoutDefaultExport[id] = true;
131-
return null;
132-
}
133-
134-
return transformed;
135-
})
136-
.catch(err => {
137-
this.error(err, err.loc);
138-
});
137+
let transformed;
138+
try {
139+
transformed = transformAndCheckExports.call(this, code, id);
140+
} catch (err) {
141+
transformed = null;
142+
this.error(err, err.loc);
143+
}
139144

140-
setIsCjsPromise(id, transformPromise.then(Boolean, () => false));
141-
return transformPromise;
145+
setIsCjsPromise(id, Boolean(transformed));
146+
return transformed;
142147
}
143148
};
144149
}

src/is-cjs.js

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,29 @@
1-
const isCjsPromises = Object.create(null);
1+
const isCjsPromises = new Map();
22

33
export function getIsCjsPromise(id) {
4-
let isCjsPromise = isCjsPromises[id];
4+
let isCjsPromise = isCjsPromises.get(id);
55
if (isCjsPromise) return isCjsPromise.promise;
66

77
const promise = new Promise(resolve => {
8-
isCjsPromises[id] = isCjsPromise = {
8+
isCjsPromise = {
99
resolve,
1010
promise: undefined
1111
};
12+
isCjsPromises.set(id, isCjsPromise);
1213
});
1314
isCjsPromise.promise = promise;
1415

1516
return promise;
1617
}
1718

18-
export function setIsCjsPromise(id, promise) {
19-
const isCjsPromise = isCjsPromises[id];
19+
export function setIsCjsPromise(id, resolution) {
20+
const isCjsPromise = isCjsPromises.get(id);
2021
if (isCjsPromise) {
2122
if (isCjsPromise.resolve) {
22-
isCjsPromise.resolve(promise);
23+
isCjsPromise.resolve(resolution);
2324
isCjsPromise.resolve = undefined;
2425
}
2526
} else {
26-
isCjsPromises[id] = { promise, resolve: undefined };
27+
isCjsPromises.set(id, { promise: Promise.resolve(resolution), resolve: undefined });
2728
}
2829
}

0 commit comments

Comments
 (0)