diff --git a/package-lock.json b/package-lock.json index 3998cb3e1..23931eb01 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,8 @@ "eslint-plugin-ember": "^5.0.0", "eslint-plugin-node": "^6.0.1", "eslint-plugin-prettier": "^3.3.0", - "prettier": "^2.2.1" + "prettier": "^2.2.1", + "webpack-virtual-modules": "^0.4.3" } }, "node_modules/@babel/code-frame": { @@ -30991,6 +30992,12 @@ "node": ">=10.13.0" } }, + "node_modules/webpack-virtual-modules": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.4.3.tgz", + "integrity": "sha512-5NUqC2JquIL2pBAAo/VfBP6KuGkHIZQXW/lNKupLPfhViwh8wNsu0BObtl09yuKZszeEUfbXz8xhrHvSG16Nqw==", + "dev": true + }, "node_modules/webpack/node_modules/enhanced-resolve": { "version": "5.8.3", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", @@ -60584,6 +60591,12 @@ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.2.tgz", "integrity": "sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw==" }, + "webpack-virtual-modules": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.4.3.tgz", + "integrity": "sha512-5NUqC2JquIL2pBAAo/VfBP6KuGkHIZQXW/lNKupLPfhViwh8wNsu0BObtl09yuKZszeEUfbXz8xhrHvSG16Nqw==", + "dev": true + }, "websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", diff --git a/package.json b/package.json index 41a123941..4544d6c73 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "eslint-plugin-ember": "^5.0.0", "eslint-plugin-node": "^6.0.1", "eslint-plugin-prettier": "^3.3.0", - "prettier": "^2.2.1" + "prettier": "^2.2.1", + "webpack-virtual-modules": "^0.4.3" }, "volta": { "node": "14.16.0", diff --git a/packages/ember-auto-import/ts/webpack.ts b/packages/ember-auto-import/ts/webpack.ts index f9326e35b..b973f2448 100644 --- a/packages/ember-auto-import/ts/webpack.ts +++ b/packages/ember-auto-import/ts/webpack.ts @@ -14,6 +14,7 @@ import { PackageCache } from '@embroider/shared-internals'; import { Memoize } from 'typescript-memoize'; import makeDebug from 'debug'; import { ensureDirSync, symlinkSync, existsSync } from 'fs-extra'; +import VirtualModulesPlugin from 'webpack-virtual-modules'; const debug = makeDebug('ember-auto-import:webpack'); @@ -88,6 +89,8 @@ export default class WebpackBundler extends Plugin implements Bundler { private lastBuildResult: BuildResult | undefined; + private virtualModules; + constructor(priorTrees: InputNode[], private opts: BundlerOptions) { super(priorTrees, { persistentOutput: true, @@ -127,8 +130,12 @@ export default class WebpackBundler extends Plugin implements Bundler { entry[bundle] = [ join(stagingDir, 'l.js'), join(stagingDir, `${bundle}.js`), + // If I understand correctly, our virtual modules will need to go in here... + // `./__ember_auto_import__/l.js`, + // `./__ember_auto_import__/${bundle}.js`, ]; }); + let config: Configuration = { mode: this.opts.environment === 'production' ? 'production' : 'development', @@ -172,7 +179,9 @@ export default class WebpackBundler extends Plugin implements Bundler { ), }, module: { - noParse: (file: string) => file === join(stagingDir, 'l.js'), + // I guess webpack should also be prevented from parsing our virtual modules, so presumably we could + // filter them out like this? + noParse: (file: string) => file === join(stagingDir, 'l.js') || file === `./__ember_auto_import__/l.js`, rules: [ this.babelRule(stagingDir), { @@ -196,6 +205,10 @@ export default class WebpackBundler extends Plugin implements Bundler { }, node: false, externals: this.externalsHandler, + // Here we add our virtual modules as per https://github.com/sysgears/webpack-virtual-modules + plugins: [ + this.virtualModules + ] }; mergeConfig( @@ -232,7 +245,10 @@ export default class WebpackBundler extends Plugin implements Bundler { // // And we otherwise defer to the `skipBabel` setting as implemented by // `@embroider/shared-internals`. - return dirname(filename) !== stagingDir && shouldTranspile(filename); + return dirname(filename) !== stagingDir + // I presume we also don't want to apply babel to our virtual modules, which I guess could be done as follows... + && filename.indexOf('/__ember_auto_import__/')<0 + && shouldTranspile(filename); }, use: { loader: 'babel-loader-8', @@ -289,10 +305,27 @@ export default class WebpackBundler extends Plugin implements Bundler { async build(): Promise { let bundleDeps = await this.opts.splitter.deps(); + // Build our virtual modules which we'll pass into the webpack plugins array + let virtualModulesHash = {}; + for (let [bundle, deps] of bundleDeps.entries()) { + virtualModulesHash[`./__ember_auto_import__/${bundle}.js`] = entryTemplate({ + staticImports: deps.staticImports, + dynamicImports: deps.dynamicImports, + dynamicTemplateImports: + deps.dynamicTemplateImports.map(mapTemplateImports), + staticTemplateImports: + deps.staticTemplateImports.map(mapTemplateImports), + publicAssetURL: this.opts.publicAssetURL, + }); + } + virtualModulesHash[`./__ember_auto_import__/l.js`] = loader; + this.virtualModules = new VirtualModulesPlugin(virtualModulesHash); + for (let [bundle, deps] of bundleDeps.entries()) { this.writeEntryFile(bundle, deps); } this.writeLoaderFile(); + this.linkDeps(bundleDeps); let stats = await this.runWebpack(); this.lastBuildResult = this.summarizeStats(stats, bundleDeps); @@ -391,6 +424,7 @@ export default class WebpackBundler extends Plugin implements Bundler { packageName: string; packageRoot: string; }): void { + // I guess this is "part 2" of what stagingDir is being used for. Not yet sure how to replace this part... ensureDirSync(dirname(join(this.stagingDir, 'node_modules', packageName))); if (!existsSync(join(this.stagingDir, 'node_modules', packageName))) { symlinkSync( diff --git a/test-scenarios/package.json b/test-scenarios/package.json index 2a6c36ca5..f6591ae96 100644 --- a/test-scenarios/package.json +++ b/test-scenarios/package.json @@ -10,7 +10,7 @@ "jsdom": "^11.11.0" }, "scripts": { - "test": "qunit --require ts-node/register *-test.ts", + "test": "qunit --require ts-node/register *-test.ts --filter lts-common-chunk", "test:list": "scenario-tester list --require ts-node/register --files=*-test.ts", "test:output": "scenario-tester output --require ts-node/register --files=*-test.ts" },