Comparing version 0.4.9 to 0.5.0
@@ -9,2 +9,3 @@ const {walk} = require("estree-walker"); | ||
getRequireInfo, | ||
getNestedExports | ||
} = require("./util"); | ||
@@ -106,2 +107,17 @@ | ||
function analyzeNestedExports(node) { | ||
const nestedExports = getNestedExports(node); | ||
if (!nestedExports || !nestedExports.name || context.scope.has(nestedExports.leftMost.name)) { | ||
return; | ||
} | ||
nestedExports.leftMost.nestedExports = nestedExports; | ||
nestedExports.leftMost.rootPos = context.topLevel.get().start; | ||
if (nestedExports.leftMost.name === "module") { | ||
context.moduleNodes.push(nestedExports.leftMost); | ||
} else { | ||
context.exportsNodes.push(nestedExports.leftMost); | ||
} | ||
context.skip(); | ||
} | ||
function analyzeCallable(node) { | ||
@@ -166,2 +182,3 @@ if ( | ||
context.topLevel.enter(node, parent); | ||
context.assignment.enter(node); | ||
if (context.scope) { | ||
@@ -203,2 +220,4 @@ context.scope.enter(node); | ||
analyzeClass(node); | ||
} else if (node.type === "MemberExpression") { | ||
analyzeNestedExports(node); | ||
} | ||
@@ -205,0 +224,0 @@ if (!context.nested && !context.topLevel.isTop()) { |
const { | ||
createTopLevelAnalyzer, | ||
createScopeAnalyzer, | ||
createAssignmentAnalyzer, | ||
hasDefaultComment | ||
@@ -52,2 +53,3 @@ } = require("./util"); | ||
context.scope = options.nested ? createScopeAnalyzer(context.ast) : null; | ||
context.assignment = createAssignmentAnalyzer(); | ||
context.walkContext = null; | ||
@@ -54,0 +56,0 @@ context.skip = () => { |
function createExportWriter(context) { | ||
context.hasNonTopLevelExport = false; | ||
context.defaultExports = []; | ||
context.namedExports = []; | ||
context.namedExports = new Map; | ||
return {write}; | ||
@@ -12,16 +12,23 @@ | ||
for (const node of context.moduleNodes.concat(context.exportsNodes)) { | ||
if (!node.exported && !node.declared) { | ||
if (!node.exported && !node.declared && !node.nestedExports) { | ||
context.hasNonTopLevelExport = true; | ||
} else if ( | ||
node.exported && node.exported.name || | ||
node.declared && node.declared.exported.name | ||
) { | ||
context.namedExports.push(node); | ||
} else { | ||
continue; | ||
} | ||
const name = node.exported && node.exported.name || | ||
node.declared && node.declared.exported.name || | ||
node.nestedExports && node.nestedExports.name; | ||
if (!name) { | ||
context.defaultExports.push(node); | ||
continue; | ||
} | ||
let namedExport = context.namedExports.get(name); | ||
if (!namedExport) { | ||
namedExport = []; | ||
context.namedExports.set(name, namedExport); | ||
} | ||
namedExport.push(node); | ||
} | ||
if ( | ||
context.hasNonTopLevelExport || | ||
context.namedExports.length && context.defaultExports.length || | ||
context.namedExports.size && context.defaultExports.length || | ||
context.defaultExports.length > 1 // but why? | ||
@@ -187,7 +194,40 @@ ) { | ||
function writeNamedExport() { | ||
for (const node of context.namedExports) { | ||
if (node.declared) { | ||
writeNamedDeclare(node); | ||
for (const [name, nodes] of context.namedExports) { | ||
let init = 0; | ||
let assignment = 0; | ||
let declared = 0; | ||
for (const node of nodes) { | ||
if (node.declared) { | ||
declared++; | ||
init++; | ||
assignment++; | ||
} else if (node.exported) { | ||
init++; | ||
assignment++; | ||
} else if (node.nestedExports.node.isAssignment) { | ||
assignment++; | ||
} | ||
} | ||
if (init === 1 && (!declared || nodes.length === 1)) { | ||
for (const node of nodes) { | ||
if (node.declared) { | ||
writeNamedDeclare(node); | ||
} else if (node.exported) { | ||
writeNamedExports(node, assignment > 1 ? "let" : "const", nodes.length > 1); | ||
} else { | ||
writeNestedExports(node); | ||
} | ||
} | ||
} else { | ||
writeNamedExports(node); | ||
for (const node of nodes) { | ||
if (node.declared) { | ||
node.nestedExports = node.declared.exported; | ||
} else if (node.exported) { | ||
node.nestedExports = node.exported; | ||
} | ||
writeNestedExports(node); | ||
} | ||
writeNamedInit(nodes.reduce((node, curr) => { | ||
return curr.rootPos < node.rootPos ? curr : node; | ||
}), name); | ||
} | ||
@@ -221,8 +261,8 @@ } | ||
function writeNamedExports(node) { | ||
if (node.exported.value.type !== "Identifier" && !node.exported.required) { | ||
function writeNamedExports(node, kind = "const", shareExport = false) { | ||
if (node.exported.value.type !== "Identifier" && !node.exported.required || shareExport) { | ||
context.s.overwrite( | ||
node.exported.leftMost.start, | ||
node.exported.value.start, | ||
`const _export_${node.exported.name}_ = `, | ||
`${kind} _export_${node.exported.name}_ = `, | ||
{contentOnly: true} | ||
@@ -249,4 +289,20 @@ ); | ||
} | ||
function writeNestedExports(node) { | ||
context.s.overwrite( | ||
node.nestedExports.node.start, | ||
node.nestedExports.node.end, | ||
`_export_${node.nestedExports.name}_`, | ||
{contentOnly: true} | ||
); | ||
} | ||
function writeNamedInit(node, name) { | ||
context.s.appendLeft( | ||
node.rootPos, | ||
`let _export_${name}_;\nexport {_export_${name}_ as ${name}};\n` | ||
); | ||
} | ||
} | ||
module.exports = {createExportWriter}; |
@@ -59,4 +59,25 @@ const {attachScopes} = require("rollup-pluginutils"); | ||
function getExportInfo(node) { | ||
if (node.left.type !== "MemberExpression") { | ||
function createAssignmentAnalyzer() { | ||
return {enter}; | ||
function enter(node) { | ||
if (node.type === "AssignmentExpression" || node.type === "AssignmentPattern") { | ||
node.left.isAssignment = true; | ||
} else if (node.type === "UpdateExpression") { | ||
node.argument.isAssignment = true; | ||
} else if (node.type === "ObjectPattern" && node.isAssignment) { | ||
for (const prop of node.properties) { | ||
prop.value.isAssignment = true; | ||
} | ||
} else if (node.type === "ArrayPattern" && node.isAssignment) { | ||
for (const el of node.elements) { | ||
el.isAssignment = true; | ||
} | ||
} | ||
} | ||
} | ||
function getNestedExports(node) { | ||
// extract export info from member expression. | ||
if (node.type !== "MemberExpression") { | ||
return; | ||
@@ -66,14 +87,14 @@ } | ||
let isNamed = false; | ||
if (node.left.object.name === "module" && node.left.property.name === "exports") { | ||
// module.exports = ... | ||
if (node.object.name === "module" && node.property.name === "exports") { | ||
// module.exports | ||
isModule = true; | ||
} else if ( | ||
node.left.object.type === "MemberExpression" && | ||
node.left.object.object.name === "module" && | ||
node.left.object.property.name === "exports" | ||
node.object.type === "MemberExpression" && | ||
node.object.object.name === "module" && | ||
node.object.property.name === "exports" | ||
) { | ||
// module.exports.foo = ... | ||
// module.exports.foo | ||
isModule = true; | ||
isNamed = true; | ||
} else if (node.left.object.name === "exports") { | ||
} else if (node.object.name === "exports") { | ||
// exports.foo = ... | ||
@@ -85,8 +106,21 @@ isNamed = true; | ||
return { | ||
name: isNamed && node.left.property.name, | ||
node, | ||
name: isNamed ? node.property.name : undefined, | ||
leftMost: isModule && isNamed ? node.object.object : node.object | ||
}; | ||
} | ||
function getExportInfo(node) { | ||
const exportInfo = getNestedExports(node.left); | ||
if (!exportInfo) { | ||
return; | ||
} | ||
return { | ||
node: exportInfo.node, | ||
name: exportInfo.name, | ||
leftMost: exportInfo.leftMost, | ||
left: node.left, | ||
leftMost: isModule && isNamed ? node.left.object.object : node.left.object, | ||
key: node.left.property, | ||
value: node.right, | ||
object: !isNamed && node.right.type === "ObjectExpression" && node.right.properties.length ? | ||
object: !exportInfo.name && node.right.type === "ObjectExpression" && node.right.properties.length ? | ||
getObjectInfo(node.right) : null, | ||
@@ -273,5 +307,7 @@ required: node.right.type === "CallExpression" && getRequireInfo(node.right), | ||
createTopLevelAnalyzer, | ||
createAssignmentAnalyzer, | ||
getDeclareExport, | ||
getDeclareImport, | ||
getDynamicImport, | ||
getNestedExports, | ||
getExportInfo, | ||
@@ -278,0 +314,0 @@ getRequireInfo, |
{ | ||
"name": "cjs-es", | ||
"version": "0.4.9", | ||
"version": "0.5.0", | ||
"description": "Transform CommonJS module into ES module.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -140,4 +140,6 @@ cjs-es | ||
If the `require`/`module`/`exports` statement are nested, they would be hoisted. Require statement: | ||
If the `require`/`module`/`exports` statement are nested, they would be hoisted. | ||
#### Require statement | ||
```js | ||
@@ -158,5 +160,25 @@ if (foo) { | ||
Export statement: | ||
#### Export statement | ||
```js | ||
function test(key) { | ||
exports[key] = "foo"; | ||
} | ||
exports.foo = "FOO"; | ||
``` | ||
Result: | ||
```js | ||
let _exports_ = {}; | ||
function test(key) { | ||
_exports_[key] = "foo"; | ||
} | ||
_exports_.foo = "FOO"; | ||
export default _exports_; | ||
``` | ||
In some cases, there is no need to hoist the export statement: | ||
```js | ||
function test() { | ||
@@ -171,8 +193,7 @@ return exports.foo(); | ||
```js | ||
let _exports_ = {}; | ||
function test() { | ||
return _exports_.foo(); | ||
return _export_foo_(); | ||
} | ||
_exports_.foo = () => "foo"; | ||
export default _exports_; | ||
const _export_foo_ = () => "foo"; | ||
export {_export_foo_ as foo}; | ||
``` | ||
@@ -242,2 +263,6 @@ | ||
* 0.5.0 (Jul 19, 2018) | ||
- Add: don't hoist export statements in some cases. | ||
* 0.4.9 (Jun 29, 2018) | ||
@@ -244,0 +269,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
44272
1092
353