Skip to content

Commit

Permalink
feat: detect require with a string arg
Browse files Browse the repository at this point in the history
  • Loading branch information
j4k0xb committed Jul 23, 2023
1 parent ce3199c commit 39348d4
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 24 deletions.
46 changes: 25 additions & 21 deletions src/extractor/webpack/bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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])
);
Expand All @@ -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<t.Identifier>[];
arg.replaceWith(
t.stringLiteral(relativePath(module.path, requiredModule.path))
);
}
moduleId = requireId.current!.value.toString();
[arg] = path.get('arguments') as NodePath<t.Identifier>[];
} 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,
Expand Down
3 changes: 2 additions & 1 deletion test/__snapshots__/extractor.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 0 additions & 2 deletions test/extractor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ test.each([
const { bundle } = await webcrack(
await readFile(join('test', 'samples', filename), 'utf8')
);
assert(bundle);
bundle.applyTransforms();
expect(bundle).toMatchSnapshot();
});

Expand Down
1 change: 1 addition & 0 deletions test/samples/webpack-jsonp-chunk.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 39348d4

Please sign in to comment.