From ce3199c5cd8e953ae279712ccfb1c1e577bf802d Mon Sep 17 00:00:00 2001 From: j4k0xb <55899582+j4k0xb@users.noreply.github.com> Date: Sun, 23 Jul 2023 04:59:11 +0200 Subject: [PATCH] feat: extract webpackJsonp chunks --- src/extractor/webpack/index.ts | 31 ++++++++++++++++++++++- test/__snapshots__/extractor.test.ts.snap | 21 +++++++++++++++ test/extractor.test.ts | 1 + test/samples/webpack-jsonp-chunk.js | 11 ++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 test/samples/webpack-jsonp-chunk.js diff --git a/src/extractor/webpack/index.ts b/src/extractor/webpack/index.ts index 79d913e6..946c8337 100644 --- a/src/extractor/webpack/index.ts +++ b/src/extractor/webpack/index.ts @@ -100,11 +100,40 @@ export const unpackWebpack = { ) ); + // Examples: self.webpackChunk_N_E, window.webpackJsonp + const jsonpGlobal = m.capture( + constMemberExpression( + m.identifier(m.or('self', 'window')), + m.matcher(s => (s as string).startsWith('webpack')) + ) + ); + // (window.webpackJsonp = window.webpackJsonp || []).push([[0], {...}]) + const jsonpMatcher = m.callExpression( + constMemberExpression( + m.assignmentExpression( + '=', + jsonpGlobal, + m.logicalExpression('||', jsonpGlobal, m.arrayExpression([])) + ), + 'push' + ), + [ + m.arrayExpression( + m.anyList( + m.arrayExpression([m.numericLiteral()]), // chunkId + moduleFunctionsMatcher, + m.slice({ max: 1 }) // optional argument like [[188, 17, 16, 18]] + ) + ), + ] + ); + return { CallExpression(path) { if ( !webpack4Matcher.match(path.node) && - !webpack5Matcher.match(path.node) + !webpack5Matcher.match(path.node) && + !jsonpMatcher.match(path.node) ) return; path.stop(); diff --git a/test/__snapshots__/extractor.test.ts.snap b/test/__snapshots__/extractor.test.ts.snap index b2915e69..724c6090 100644 --- a/test/__snapshots__/extractor.test.ts.snap +++ b/test/__snapshots__/extractor.test.ts.snap @@ -434,6 +434,27 @@ export default 1;, } `; +exports[`extract webpack-jsonp-chunk.js 1`] = ` +WebpackBundle { + "entryId": "", + "modules": Map { + "2wwy" => WebpackModule { + "ast": const a = require("E8gZ");, + "id": "2wwy", + "isEntry": false, + "path": "./2wwy.js", + }, + "E8gZ" => WebpackModule { + "ast": module.exports = 4;, + "id": "E8gZ", + "isEntry": false, + "path": "./E8gZ.js", + }, + }, + "type": "webpack", +} +`; + exports[`extract webpack-object.js 1`] = ` WebpackBundle { "entryId": "386", diff --git a/test/extractor.test.ts b/test/extractor.test.ts index f54dde8d..1c18b213 100644 --- a/test/extractor.test.ts +++ b/test/extractor.test.ts @@ -11,6 +11,7 @@ test.each([ 'webpack-object.js', 'webpack-esm.js', 'webpack-var-injection.js', + 'webpack-jsonp-chunk.js', 'webpack-0.11.x.js', 'webpack5-object.js', 'webpack5-esm.js', diff --git a/test/samples/webpack-jsonp-chunk.js b/test/samples/webpack-jsonp-chunk.js new file mode 100644 index 00000000..784d6806 --- /dev/null +++ b/test/samples/webpack-jsonp-chunk.js @@ -0,0 +1,11 @@ +(window.webpackJsonp = window.webpackJsonp || []).push([ + [15], + { + '2wwy': function (e, t, i) { + const a = i('E8gZ'); + }, + E8gZ: function (e, t, i) { + e.exports = 4; + }, + }, +]);