Skip to content

Commit ad83213

Browse files
authored
Merge pull request #606 from embroider-build/allow-app-imports-dynamic
Fix dynamic import inside allowAppImports dirs
2 parents 2373ba7 + c0e49e9 commit ad83213

File tree

2 files changed

+69
-2
lines changed

2 files changed

+69
-2
lines changed

packages/ember-auto-import/ts/package.ts

+38-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
packageName as getPackageName,
1111
} from '@embroider/shared-internals';
1212
import semver from 'semver';
13-
import type { TransformOptions } from '@babel/core';
13+
import type { PluginItem, TransformOptions } from '@babel/core';
1414
import { MacrosConfig } from '@embroider/macros/src/node';
1515
import minimatch from 'minimatch';
1616
import { stripQuery } from './util';
@@ -141,6 +141,19 @@ export default class Package {
141141
this._hasBabelDetails = true;
142142
}
143143

144+
// this is used for two things:
145+
// - when interoperating with older versions of ember-auto-import, it's used
146+
// to configure the parser that we use to analyze source code. The parser
147+
// cares about the user's babel config so it will support all the same
148+
// syntax. (Newer EAI versions don't need to do this because they use the
149+
// faster analyzer that happens inside the existing babel parse.)
150+
// - when transpiling parts of the app itself that are configured with
151+
// allowAppImports. It would be surprising if these didn't get transpiled
152+
// with the same babel config that the rest of the app is getting. There is,
153+
// however, one exception: if the user has added
154+
// ember-auto-import/babel-plugin to get dynamic import support, we need to
155+
// remove that because inside the natively webpack-owned area it's not
156+
// needed and would actually break dynamic imports.
144157
get babelOptions(): TransformOptions {
145158
this._ensureBabelDetails();
146159
return this._babelOptions;
@@ -187,7 +200,11 @@ export default class Package {
187200

188201
if (babelOptions.plugins) {
189202
babelOptions.plugins = babelOptions.plugins.filter(
190-
(p: any) => !p._parallelBabel
203+
// removing the weird "_parallelBabel" entry that's only used by
204+
// broccoli-babel-transpiler and removing our own dynamic import babel
205+
// plugin if it was added (because it's only correct to use it against
206+
// the classic ember build, not the webpack-owned parts of the build.
207+
(p: any) => !p._parallelBabel && !isEAIBabelPlugin(p)
191208
);
192209
}
193210

@@ -674,3 +691,22 @@ function ensureTrailingSlash(url: string): string {
674691
}
675692
return url;
676693
}
694+
695+
function isEAIBabelPlugin(item: PluginItem) {
696+
let pluginPath: string | undefined;
697+
if (typeof item === 'string') {
698+
pluginPath = item;
699+
} else if (
700+
Array.isArray(item) &&
701+
item.length > 0 &&
702+
typeof item[0] === 'string'
703+
) {
704+
pluginPath = item[0];
705+
}
706+
707+
if (pluginPath) {
708+
return /ember-auto-import[\\/]babel-plugin/.test(pluginPath);
709+
}
710+
711+
return (item as any).baseDir?.() === __dirname;
712+
}

test-scenarios/dynamic-import-test.ts

+31
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,19 @@ appScenarios
6161
'export default function() { return "example3 worked" }; export const NO_FIND = "string or not to string"',
6262
'example4.js':
6363
'export default function() { return "example4 worked" }; export const NO_FIND = "please look away"',
64+
'does-dynamic-import.js': `
65+
export async function getRelativeTarget() {
66+
return (await import('./dynamic-target.js')).default;
67+
}
68+
export async function getPackageTarget() {
69+
return (await import('dynamic-target')).default;
70+
}
71+
`,
72+
'dynamic-target.js': `
73+
export default function() {
74+
return 'relative dynamic target loaded OK';
75+
}
76+
`,
6477
},
6578
templates: {
6679
'dynamic-import.hbs': `<div data-test="dynamic-import-result">{{this.model.result}}</div>`,
@@ -162,6 +175,7 @@ appScenarios
162175
'allow-app-imports-test.js': `
163176
import { module, test } from 'qunit';
164177
import checkScripts from '../helpers/check-scripts';
178+
import { getRelativeTarget, getPackageTarget } from '@ef4/app-template/lib/does-dynamic-import';
165179
166180
module('Unit | allow-app-import', function () {
167181
test("check scripts smoke test", async function(assert) {
@@ -206,6 +220,14 @@ appScenarios
206220
"expect to not find the 'example4 NO_FIND' in app-js because it's being consumed by webpack"
207221
);
208222
})
223+
test("dynamic relative import from inside the allowAppImports dir", async function (assert) {
224+
let fn = await getRelativeTarget();
225+
assert.equal(fn(), 'relative dynamic target loaded OK');
226+
})
227+
test("dynamic package import from inside the allowAppImports dir", async function (assert) {
228+
let fn = await getPackageTarget();
229+
assert.equal(fn(), 'package dynamic target loaded OK');
230+
})
209231
});
210232
`,
211233
},
@@ -223,6 +245,15 @@ appScenarios
223245
},
224246
},
225247
});
248+
project.addDevDependency('dynamic-target', {
249+
files: {
250+
'index.js': `
251+
export default function() {
252+
return 'package dynamic target loaded OK';
253+
}
254+
`,
255+
},
256+
});
226257
})
227258
.forEachScenario(scenario => {
228259
Qmodule(scenario.name, function (hooks) {

0 commit comments

Comments
 (0)