diff --git a/packages/core/integration-tests/test/integration/require-async/resolve-chain.js b/packages/core/integration-tests/test/integration/require-async/resolve-chain.js new file mode 100644 index 00000000000..09a83bc31e8 --- /dev/null +++ b/packages/core/integration-tests/test/integration/require-async/resolve-chain.js @@ -0,0 +1 @@ +module.exports = Promise.resolve(require('./async')).then(x => x + 1335); diff --git a/packages/core/integration-tests/test/javascript.js b/packages/core/integration-tests/test/javascript.js index 3dfe9405ed0..4561a8e03ef 100644 --- a/packages/core/integration-tests/test/javascript.js +++ b/packages/core/integration-tests/test/javascript.js @@ -4630,6 +4630,29 @@ describe('javascript', function () { assert.equal(await run(b), 5); }); + it('should properly chain a dynamic import wrapped in a Promise.resolve()', async () => { + let b = await bundle( + path.join(__dirname, '/integration/require-async/resolve-chain.js'), + ); + + assertBundles(b, [ + { + name: 'resolve-chain.js', + assets: [ + 'resolve-chain.js', + 'bundle-url.js', + 'cacheLoader.js', + 'js-loader.js', + ], + }, + { + assets: ['async.js'], + }, + ]); + + assert.equal(await run(b), 1337); + }); + it('should detect parcel style async requires in commonjs', async () => { let b = await bundle( path.join(__dirname, '/integration/require-async/parcel.js'), diff --git a/packages/transformers/js/core/src/dependency_collector.rs b/packages/transformers/js/core/src/dependency_collector.rs index 9f9bd07deea..9891e7f90b8 100644 --- a/packages/transformers/js/core/src/dependency_collector.rs +++ b/packages/transformers/js/core/src/dependency_collector.rs @@ -458,10 +458,17 @@ impl<'a> Fold for DependencyCollector<'a> { // Promise.resolve().then(() => require('foo')) // Promise.resolve().then(() => { return require('foo') }) // Promise.resolve().then(function () { return require('foo') }) + // but not + // Promise.resolve(require('foo')) if let Call(call) = &*member.obj { if let Callee::Expr(e) = &call.callee { if let Member(m) = &**e { - if match_member_expr(m, vec!["Promise", "resolve"], self.decls) { + if match_member_expr(m, vec!["Promise", "resolve"], self.decls) && + // Make sure the arglist is empty. + // I.e. do not proceed with the below unless Promise.resolve has an empty arglist + // because build_promise_chain() will not work in this case. + call.args.is_empty() + { if let MemberProp::Ident(id) = &member.prop { if id.sym.to_string().as_str() == "then" { if let Some(arg) = node.args.get(0) {