Skip to content

Commit

Permalink
feat(esmodule-flag): support various __esModule flag
Browse files Browse the repository at this point in the history
  • Loading branch information
pionxzh committed Nov 25, 2023
1 parent 8a7d455 commit 397d5b3
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,24 @@ const inlineTest = defineInlineTest(transform)
inlineTest('remove es module helper from ES5+',
`
Object.defineProperty(exports, "__esModule", {
value: true
value: true
});
Object.defineProperty(module.exports, "__esModule", {
value: !0
});
const a = require('a');
`,
`
const a = require('a');
`,
)

inlineTest('remove es module helper from ES3',
`
exports.__esModule = !0;
exports.__esModule = true;
exports["__esModule"] = true;
module.exports.__esModule = !0;
module.exports.__esModule = true;
module.exports["__esModule"] = true;
`,
`
`,
Expand Down
34 changes: 30 additions & 4 deletions packages/unminify/src/transformations/un-esmodule-flag.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { isLooseTrue } from '../utils/checker'
import wrap from '../wrapAstTransformation'
import type { ASTTransformation } from '../wrapAstTransformation'
import type { ASTNode, CallExpression, Identifier, JSCodeshift, MemberExpression, StringLiteral } from 'jscodeshift'

/**
* Removes the `__esModule` flag from the module.
*
* @example
* ```diff
* - Object.defineProperty(exports, '__esModule', { value: true })
* - exports.__esModule = !0
* - module.exports.__esModule = true
* ```
*/
export const transformAST: ASTTransformation = (context) => {
Expand All @@ -15,6 +19,7 @@ export const transformAST: ASTTransformation = (context) => {
/**
* Target: ES5+
* Object.defineProperty(exports, '__esModule', { value: true })
* Object.defineProperty(module.exports, '__esModule', { value: true })
*/
root
.find(j.ExpressionStatement, {
Expand All @@ -26,7 +31,7 @@ export const transformAST: ASTTransformation = (context) => {
property: { type: 'Identifier', name: 'defineProperty' },
},
arguments: [
{ type: 'Identifier', name: 'exports' } as const,
(node: CallExpression['arguments'][0]) => isExportObject(j, node),
{ type: 'StringLiteral', value: '__esModule' } as const,
],
},
Expand All @@ -36,18 +41,39 @@ export const transformAST: ASTTransformation = (context) => {
/**
* Target: ES3
* exports.__esModule = true
* module.exports.__esModule = true
*/
root
.find(j.AssignmentExpression, {
left: {
type: 'MemberExpression',
object: { type: 'Identifier', name: 'exports' },
property: { type: 'Identifier', name: '__esModule' },
object: (node: MemberExpression['object']) => isExportObject(j, node),
property: (node: MemberExpression['property']) => is__esModule(j, node),
},
operator: '=',
right: { type: 'BooleanLiteral', value: true },
right: node => isLooseTrue(j, node),
})
.remove()
}

function isExportObject(j: JSCodeshift, node: ASTNode): node is MemberExpression | Identifier {
return isExports(j, node) || isModuleExports(j, node)
}

function isExports(j: JSCodeshift, node: ASTNode): node is Identifier {
return j.Identifier.check(node) && node.name === 'exports'
}

function isModuleExports(j: JSCodeshift, node: ASTNode): node is MemberExpression {
return j.MemberExpression.check(node)
&& j.Identifier.check(node.object) && node.object.name === 'module'
&& j.Identifier.check(node.property) && node.property.name === 'exports'
}

const __esModule = '__esModule'
function is__esModule(j: JSCodeshift, node: ASTNode): node is Identifier | StringLiteral {
return (j.Identifier.check(node) && node.name === __esModule)
|| (j.StringLiteral.check(node) && node.value === __esModule)
}

export default wrap(transformAST)
8 changes: 8 additions & 0 deletions packages/unminify/src/utils/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ export function isFalse(j: JSCodeshift, node: ASTNode): node is BooleanLiteral {
return j.BooleanLiteral.check(node) && node.value === false
}

export function isLooseTrue(j: JSCodeshift, node: ASTNode): node is BooleanLiteral | UnaryExpression {
return isTrue(j, node) || (isLogicalNot(j, node) && j.NumericLiteral.check(node.argument) && node.argument.value === 0)
}

export function isLooseFalse(j: JSCodeshift, node: ASTNode): node is BooleanLiteral | UnaryExpression {
return isFalse(j, node) || (isLogicalNot(j, node) && j.NumericLiteral.check(node.argument) && node.argument.value === 1)
}

/**
* Check if node is `null` literal
*/
Expand Down

0 comments on commit 397d5b3

Please sign in to comment.