diff --git a/src/parseUtils.js b/src/parseUtils.js index f5989105..1d775ae3 100644 --- a/src/parseUtils.js +++ b/src/parseUtils.js @@ -18,13 +18,54 @@ function parseBundle(bundlePath) { }); const walkState = { - locations: null + locations: null, + expressionStatementDepth: 0 }; walk.recursive( ast, walkState, { + ExpressionStatement(node, state, c) { + if (state.locations) return; + + state.expressionStatementDepth++; + + if ( + // Webpack 5 stores modules in the the top-level IIFE + state.expressionStatementDepth === 1 && + ast.body.includes(node) && + isIIFE(node) + ) { + const fn = getIIFECallExpression(node); + + if ( + // It should not contain neither arguments + fn.arguments.length === 0 && + // ...nor parameters + fn.callee.params.length === 0 + ) { + // Modules are stored in the very first variable as hash + const {body} = fn.callee.body; + + if ( + body.length && + body[0].type === 'VariableDeclaration' && + body[0].declarations.length && + body[0].declarations[0].type === 'VariableDeclarator' && + body[0].declarations[0].init.type === 'ObjectExpression' + ) { + state.locations = getModulesLocations(body[0].declarations[0].init); + } + } + } + + if (!state.locations) { + c(node.expression, state); + } + + state.expressionStatementDepth--; + }, AssignmentExpression(node, state) { if (state.locations) return; @@ -111,6 +152,24 @@ function parseBundle(bundlePath) { }; } +function isIIFE(node) { + return ( + node.type === 'ExpressionStatement' && + ( + node.expression.type === 'CallExpression' || + (node.expression.type === 'UnaryExpression' && node.expression.argument.type === 'CallExpression') + ) + ); +} + +function getIIFECallExpression(node) { + if (node.expression.type === 'UnaryExpression') { + return node.expression.argument; + } else { + return node.expression; + } +} + function isModulesList(node) { return ( isSimpleModulesList(node) || diff --git a/test/.gitignore b/test/.gitignore index ce6b1486..6c0140ff 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -2,3 +2,5 @@ output # Sandbox config /webpack.config.js +# Output of sandbox config +/dist diff --git a/test/bundles/validWebpack5LegacyBundle.js b/test/bundles/validWebpack5LegacyBundle.js new file mode 100644 index 00000000..e7dea0cc --- /dev/null +++ b/test/bundles/validWebpack5LegacyBundle.js @@ -0,0 +1 @@ +!function(){var o={631:function(o){o.exports="module a"},85:function(o){o.exports="module a"},326:function(o){o.exports="module b"}},t={};function r(e){if(t[e])return t[e].exports;var n=t[e]={exports:{}};return o[e](n,n.exports,r),n.exports}r(85),r(326),r(631)}(); diff --git a/test/bundles/validWebpack5LegacyBundle.modules.json b/test/bundles/validWebpack5LegacyBundle.modules.json new file mode 100644 index 00000000..487ad386 --- /dev/null +++ b/test/bundles/validWebpack5LegacyBundle.modules.json @@ -0,0 +1,7 @@ +{ + "modules": { + "631": "function(o){o.exports=\"module a\"}", + "85": "function(o){o.exports=\"module a\"}", + "326": "function(o){o.exports=\"module b\"}" + } +} diff --git a/test/bundles/validWebpack5ModernBundle.js b/test/bundles/validWebpack5ModernBundle.js new file mode 100644 index 00000000..b4673b91 --- /dev/null +++ b/test/bundles/validWebpack5ModernBundle.js @@ -0,0 +1 @@ +(()=>{var r={631:r=>{r.exports="module a"},85:r=>{r.exports="module a"},326:r=>{r.exports="module b"}},e={};function o(t){if(e[t])return e[t].exports;var p=e[t]={exports:{}};return r[t](p,p.exports,o),p.exports}o(85),o(326),o(631)})(); diff --git a/test/bundles/validWebpack5ModernBundle.modules.json b/test/bundles/validWebpack5ModernBundle.modules.json new file mode 100644 index 00000000..23519a15 --- /dev/null +++ b/test/bundles/validWebpack5ModernBundle.modules.json @@ -0,0 +1,7 @@ +{ + "modules": { + "631": "r=>{r.exports=\"module a\"}", + "85": "r=>{r.exports=\"module a\"}", + "326": "r=>{r.exports=\"module b\"}" + } +}