From 39348d48f3d580cb14e60f077ecbf90f28e02063 Mon Sep 17 00:00:00 2001 From: j4k0xb <55899582+j4k0xb@users.noreply.github.com> Date: Sun, 23 Jul 2023 05:41:02 +0200 Subject: [PATCH] feat: detect require with a string arg --- src/extractor/webpack/bundle.ts | 46 ++++++++++++----------- test/__snapshots__/extractor.test.ts.snap | 3 +- test/extractor.test.ts | 2 - test/samples/webpack-jsonp-chunk.js | 1 + 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/extractor/webpack/bundle.ts b/src/extractor/webpack/bundle.ts index efbd195f..4db22bcb 100644 --- a/src/extractor/webpack/bundle.ts +++ b/src/extractor/webpack/bundle.ts @@ -27,7 +27,7 @@ export class WebpackBundle extends Bundle { * Replaces `require(id)` calls with `require("./relative/path.js")` calls. */ private replaceRequirePaths() { - const requireId = m.capture(m.numericLiteral()); + const requireId = m.capture(m.or(m.numericLiteral(), m.stringLiteral())); const requireMatcher = m.or( m.callExpression(m.identifier('require'), [requireId]) ); @@ -36,28 +36,32 @@ export class WebpackBundle extends Bundle { this.modules.forEach(module => { traverse(module.ast, { - CallExpression: path => { + 'CallExpression|ImportDeclaration': path => { + let moduleId: string; + let arg: NodePath; + if (requireMatcher.match(path.node)) { - const requiredModule = this.modules.get( - requireId.current!.value.toString() - ); - if (requiredModule) { - const [arg] = path.get('arguments') as NodePath[]; - arg.replaceWith( - t.stringLiteral(relativePath(module.path, requiredModule.path)) - ); - } + moduleId = requireId.current!.value.toString(); + [arg] = path.get('arguments') as NodePath[]; + } else if (importMatcher.match(path.node)) { + moduleId = importId.current!.value; + arg = path.get('source') as NodePath; + } else { + return; } - }, - ImportDeclaration: path => { - if (importMatcher.match(path.node)) { - const requiredModule = this.modules.get(importId.current!.value); - if (requiredModule) { - const arg = path.get('source') as NodePath; - arg.replaceWith( - t.stringLiteral(relativePath(module.path, requiredModule.path)) - ); - } + + const requiredModule = this.modules.get(moduleId); + arg.replaceWith( + t.stringLiteral( + relativePath( + module.path, + requiredModule?.path ?? `./${moduleId}.js` + ) + ) + ); + // For example if its stored in another chunk + if (!requiredModule) { + arg.addComment('leading', 'webcrack:missing'); } }, noScope: true, diff --git a/test/__snapshots__/extractor.test.ts.snap b/test/__snapshots__/extractor.test.ts.snap index 724c6090..5478d6ea 100644 --- a/test/__snapshots__/extractor.test.ts.snap +++ b/test/__snapshots__/extractor.test.ts.snap @@ -439,7 +439,8 @@ WebpackBundle { "entryId": "", "modules": Map { "2wwy" => WebpackModule { - "ast": const a = require("E8gZ");, + "ast": const a = require("./E8gZ.js"); +const b = require( /*webcrack:missing*/"./w6GO.js");, "id": "2wwy", "isEntry": false, "path": "./2wwy.js", diff --git a/test/extractor.test.ts b/test/extractor.test.ts index 1c18b213..8c63cf79 100644 --- a/test/extractor.test.ts +++ b/test/extractor.test.ts @@ -21,8 +21,6 @@ test.each([ const { bundle } = await webcrack( await readFile(join('test', 'samples', filename), 'utf8') ); - assert(bundle); - bundle.applyTransforms(); expect(bundle).toMatchSnapshot(); }); diff --git a/test/samples/webpack-jsonp-chunk.js b/test/samples/webpack-jsonp-chunk.js index 784d6806..c1b602a9 100644 --- a/test/samples/webpack-jsonp-chunk.js +++ b/test/samples/webpack-jsonp-chunk.js @@ -3,6 +3,7 @@ { '2wwy': function (e, t, i) { const a = i('E8gZ'); + const b = i('w6GO'); }, E8gZ: function (e, t, i) { e.exports = 4;