From c2f697cc4a1d651d3356cdbf536a6103a6f97a4d Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Mon, 9 Sep 2024 14:07:03 -0400 Subject: [PATCH 1/9] Switching to user-controlled babel config --- packages/compat/babel.cjs | 1 + packages/compat/package.json | 2 + packages/compat/src/babel.ts | 145 +++++++++ packages/compat/src/compat-app-builder.ts | 216 ++----------- packages/compat/src/compat-app.ts | 78 ++--- packages/compat/src/detect-babel-plugins.ts | 13 + packages/compat/src/rename-require-plugin.ts | 14 - packages/compat/tests/audit.test.ts | 7 +- packages/core/src/module-resolver.ts | 1 + packages/core/src/options.ts | 9 - packages/core/src/portable-babel-config.ts | 138 --------- packages/core/src/portable-babel-launcher.ts | 83 ----- .../core/tests/portable-babel-config.test.ts | 290 ------------------ packages/shared-internals/src/babel-filter.ts | 34 -- packages/shared-internals/src/index.ts | 1 - pnpm-lock.yaml | 32 +- tests/app-template/babel.config.cjs | 65 ++-- tests/app-template/package.json | 6 +- tests/scenarios/compat-resolver-test.ts | 1 + tests/scenarios/core-resolver-test.ts | 1 + 20 files changed, 295 insertions(+), 842 deletions(-) create mode 100644 packages/compat/babel.cjs create mode 100644 packages/compat/src/babel.ts delete mode 100644 packages/compat/src/rename-require-plugin.ts delete mode 100644 packages/core/src/portable-babel-config.ts delete mode 100644 packages/core/src/portable-babel-launcher.ts delete mode 100644 packages/core/tests/portable-babel-config.test.ts delete mode 100644 packages/shared-internals/src/babel-filter.ts diff --git a/packages/compat/babel.cjs b/packages/compat/babel.cjs new file mode 100644 index 000000000..3ddfa4d58 --- /dev/null +++ b/packages/compat/babel.cjs @@ -0,0 +1 @@ +module.exports = require('./src/babel'); diff --git a/packages/compat/package.json b/packages/compat/package.json index bba0453c9..210a0e384 100644 --- a/packages/compat/package.json +++ b/packages/compat/package.json @@ -12,6 +12,7 @@ "author": "Edward Faulkner", "main": "src/index.js", "files": [ + "babel.cjs", "src/**/*.js", "src/**/*.d.ts", "src/**/*.js.map" @@ -35,6 +36,7 @@ "@types/yargs": "^17.0.3", "assert-never": "^1.1.0", "babel-import-util": "^2.0.0", + "babel-plugin-debug-macros": "^1.0.2", "babel-plugin-ember-template-compilation": "^2.1.1", "babel-plugin-syntax-dynamic-import": "^6.18.0", "babylon": "^6.18.0", diff --git a/packages/compat/src/babel.ts b/packages/compat/src/babel.ts new file mode 100644 index 000000000..5ba21c037 --- /dev/null +++ b/packages/compat/src/babel.ts @@ -0,0 +1,145 @@ +import type { PluginItem } from '@babel/core'; +import { existsSync } from 'fs'; +import { + locateEmbroiderWorkingDir, + ResolverLoader, + templateColocationPluginPath, + type TemplateColocationPluginOptions, +} from '@embroider/core'; +import { join } from 'path'; +import type { Transform } from 'babel-plugin-ember-template-compilation'; +import type { Options as ResolverTransformOptions } from './resolver-transform'; +import type { Options as AdjustImportsOptions } from './babel-plugin-adjust-imports'; + +export interface CompatBabelState { + plugins: PluginItem[]; + templateTransforms: Transform[]; + babelMacros: PluginItem[]; + templateMacros: Transform[]; +} + +function loadCompatConfig(): CompatBabelState { + let compatFile = join(locateEmbroiderWorkingDir(process.cwd()), '_babel_compat_.js'); + if (existsSync(compatFile)) { + // eslint-disable-next-line @typescript-eslint/no-require-imports + return require(compatFile); + } + return { + plugins: [], + templateTransforms: [], + babelMacros: [], + templateMacros: [], + }; +} + +const resolverLoader = new ResolverLoader(process.cwd()); + +export function transformsFromV1Addons() { + let config = loadCompatConfig(); + return config.templateTransforms; +} + +export function looseModeSupport(): Transform { + const { resolver } = resolverLoader; + let opts: ResolverTransformOptions = { + appRoot: resolver.options.appRoot, + emberVersion: resolver.options.emberVersion, + }; + return [require.resolve('./resolver-transform'), opts]; +} + +export function templateMacros() { + let config = loadCompatConfig(); + return config.templateMacros; +} + +export function babelMacros() { + let config = loadCompatConfig(); + return config.babelMacros; +} + +export function adjustImports() { + let pluginConfig: AdjustImportsOptions = { + appRoot: resolverLoader.resolver.options.appRoot, + }; + return [require.resolve('./babel-plugin-adjust-imports'), pluginConfig]; +} + +export function oldDebugMacros(): PluginItem[] { + let debugMacros = require.resolve('babel-plugin-debug-macros'); + return [ + [ + debugMacros, + { + flags: [ + { + source: '@glimmer/env', + flags: { + DEBUG: true, + CI: false, + }, + }, + ], + debugTools: { + isDebug: true, + source: '@ember/debug', + assertPredicateIndex: 1, + }, + externalizeHelpers: { + module: '@ember/debug', + }, + }, + '@ember/debug stripping', + ], + [ + debugMacros, + { + externalizeHelpers: { + module: '@ember/application/deprecations', + }, + debugTools: { + isDebug: true, + source: '@ember/application/deprecations', + assertPredicateIndex: 1, + }, + }, + '@ember/application/deprecations stripping', + ], + ]; +} + +export function templateColocation(): PluginItem { + let colocationOptions: TemplateColocationPluginOptions = { + appRoot: resolverLoader.resolver.options.appRoot, + + // This extra weirdness is a compromise in favor of build performance. + // + // 1. When auto-upgrading an addon from v1 to v2, we definitely want to + // run any custom AST transforms in stage1. + // + // 2. In general case, AST transforms are allowed to manipulate Javascript + // scope. This means that running transforms -- even when we're doing + // source-to-source compilation that emits handlebars and not wire + // format -- implies changing .hbs files into .js files. + // + // 3. So stage1 may need to rewrite .hbs to .hbs.js (to avoid colliding + // with an existing co-located .js file). + // + // 4. But stage1 doesn't necessarily want to run babel over the + // corresponding JS file. Most of the time, that's just an + // unnecessarily expensive second parse. (We only run it in stage1 to + // eliminate an addon's custom babel plugins, and many addons don't + // have any.) + // + // 5. Therefore, the work of template-colocation gets defered until here, + // and it may see co-located templates named `.hbs.js` instead of the + // usual `.hbs. + templateExtensions: ['.hbs', '.hbs.js'], + + // All of the above only applies to auto-upgraded packages that were + // authored in v1. V2 packages don't get any of this complexity, they're + // supposed to take care of colocating their own templates explicitly. + packageGuard: true, + }; + return [templateColocationPluginPath, colocationOptions]; +} diff --git a/packages/compat/src/compat-app-builder.ts b/packages/compat/src/compat-app-builder.ts index d2df7f03d..4d143fed4 100644 --- a/packages/compat/src/compat-app-builder.ts +++ b/packages/compat/src/compat-app-builder.ts @@ -1,29 +1,15 @@ -import type { AddonPackage, Engine, TemplateColocationPluginOptions } from '@embroider/core'; -import { - explicitRelative, - warn, - jsHandlebarsCompile, - templateColocationPluginPath, - cacheBustingPluginVersion, - cacheBustingPluginPath, - Resolver, - locateEmbroiderWorkingDir, -} from '@embroider/core'; +import type { AddonPackage, Engine } from '@embroider/core'; +import { explicitRelative, locateEmbroiderWorkingDir } from '@embroider/core'; import { resolve as resolvePath } from 'path'; import type Options from './options'; import type { CompatResolverOptions } from './resolver-transform'; import type { PackageRules } from './dependency-rules'; import { activePackageRules } from './dependency-rules'; import flatMap from 'lodash/flatMap'; -import cloneDeep from 'lodash/cloneDeep'; import bind from 'bind-decorator'; import { outputJSONSync, writeFileSync, realpathSync } from 'fs-extra'; -import type { Options as EtcOptions } from 'babel-plugin-ember-template-compilation'; -import type { Options as ResolverTransformOptions } from './resolver-transform'; -import type { Options as AdjustImportsOptions } from './babel-plugin-adjust-imports'; -import { makePortable } from '@embroider/core/src/portable-babel-config'; import type { PortableHint } from '@embroider/core/src/portable'; -import { maybeNodeModuleVersion } from '@embroider/core/src/portable'; +import { maybeNodeModuleVersion, Portable } from '@embroider/core/src/portable'; import { Memoize } from 'typescript-memoize'; import { join, dirname } from 'path'; import resolve from 'resolve'; @@ -31,10 +17,10 @@ import type ContentForConfig from './content-for-config'; import type { V1Config } from './v1-config'; import type { Package } from '@embroider/core'; import { readdirSync } from 'fs-extra'; -import type { TransformOptions } from '@babel/core'; -import { MacrosConfig } from '@embroider/macros/src/node'; import type CompatApp from './compat-app'; +import type { CompatBabelState } from './babel'; +import { MacrosConfig } from '@embroider/macros/src/node'; // This exists during the actual broccoli build step. As opposed to CompatApp, // which also exists during pipeline-construction time. @@ -171,89 +157,12 @@ export class CompatAppBuilder { options, autoRun: this.compatApp.autoRun, staticAppPaths: this.options.staticAppPaths, + emberVersion: this.emberVersion(), }; return config; } - @Memoize() - private async babelConfig(resolverConfig: CompatResolverOptions) { - let babel = cloneDeep(this.compatApp.babelConfig()); - - if (!babel.plugins) { - babel.plugins = []; - } - - // Our stage3 code is always allowed to use dynamic import. We may emit it - // ourself when splitting routes. - babel.plugins.push(require.resolve('@babel/plugin-syntax-dynamic-import')); - - // https://github.com/webpack/webpack/issues/12154 - babel.plugins.push(require.resolve('./rename-require-plugin')); - - babel.plugins.push([ - require.resolve('babel-plugin-ember-template-compilation'), - await this.etcOptions(resolverConfig), - ]); - - // this is @embroider/macros configured for full stage3 resolution - babel.plugins.push(...this.compatApp.macrosConfig.babelPluginConfig()); - - let colocationOptions: TemplateColocationPluginOptions = { - appRoot: this.origAppPackage.root, - - // This extra weirdness is a compromise in favor of build performance. - // - // 1. When auto-upgrading an addon from v1 to v2, we definitely want to - // run any custom AST transforms in stage1. - // - // 2. In general case, AST transforms are allowed to manipulate Javascript - // scope. This means that running transforms -- even when we're doing - // source-to-source compilation that emits handlebars and not wire - // format -- implies changing .hbs files into .js files. - // - // 3. So stage1 may need to rewrite .hbs to .hbs.js (to avoid colliding - // with an existing co-located .js file). - // - // 4. But stage1 doesn't necessarily want to run babel over the - // corresponding JS file. Most of the time, that's just an - // unnecessarily expensive second parse. (We only run it in stage1 to - // eliminate an addon's custom babel plugins, and many addons don't - // have any.) - // - // 5. Therefore, the work of template-colocation gets defered until here, - // and it may see co-located templates named `.hbs.js` instead of the - // usual `.hbs. - templateExtensions: ['.hbs', '.hbs.js'], - - // All of the above only applies to auto-upgraded packages that were - // authored in v1. V2 packages don't get any of this complexity, they're - // supposed to take care of colocating their own templates explicitly. - packageGuard: true, - }; - babel.plugins.push([templateColocationPluginPath, colocationOptions]); - - babel.plugins.push([ - require.resolve('./babel-plugin-adjust-imports'), - (() => { - let pluginConfig: AdjustImportsOptions = { - appRoot: resolverConfig.appRoot, - }; - return pluginConfig; - })(), - ]); - - // we can use globally shared babel runtime by default - babel.plugins.push([ - require.resolve('@babel/plugin-transform-runtime'), - { absoluteRuntime: __dirname, useESModules: true, regenerator: false }, - ]); - - const portable = makePortable(babel, { basedir: this.origAppPackage.root }, this.portableHints); - addCachablePlugin(portable.config); - return portable; - } - // recurse to find all active addons that don't cross an engine boundary. // Inner engines themselves will be returned, but not those engines' children. // The output set's insertion order is the proper ember-cli compatible @@ -338,47 +247,7 @@ export class CompatAppBuilder { this.addContentForConfig(contentForConfig); this.addEmberEnvConfig(config.EmberENV); this.outputAppBootError(config.modulePrefix, config.APP, contentForConfig); - let babelConfig = await this.babelConfig(resolverConfig); - this.addBabelConfig(babelConfig); - this.addMacrosConfig(this.compatApp.macrosConfig.babelPluginConfig()[0]); - } - - private async etcOptions(resolverConfig: CompatResolverOptions): Promise { - let transforms = this.compatApp.htmlbarsPlugins; - - let { plugins: macroPlugins, setConfig } = MacrosConfig.transforms(); - setConfig(this.compatApp.macrosConfig); - for (let macroPlugin of macroPlugins) { - transforms.push(macroPlugin as any); - } - - if ( - this.options.staticComponents || - this.options.staticHelpers || - this.options.staticModifiers || - (globalThis as any).embroider_audit - ) { - let opts: ResolverTransformOptions = { - appRoot: resolverConfig.appRoot, - emberVersion: this.emberVersion(), - }; - transforms.push([require.resolve('./resolver-transform'), opts]); - } - - let resolver = new Resolver(resolverConfig); - let resolution = await resolver.nodeResolve( - 'ember-source/vendor/ember/ember-template-compiler', - resolvePath(this.origAppPackage.root, 'package.json') - ); - if (resolution.type !== 'real') { - throw new Error(`bug: unable to resolve ember-template-compiler from ${this.origAppPackage.root}`); - } - - return { - transforms, - compilerPath: resolution.filename, - enableLegacyModules: ['ember-cli-htmlbars', 'ember-cli-htmlbars-inline-precompile', 'htmlbars-inline-precompile'], - }; + this.addBabelCompat(); } @Memoize() @@ -401,18 +270,31 @@ export class CompatAppBuilder { }); } - private addBabelConfig(pconfig: { config: TransformOptions; isParallelSafe: boolean }) { - if (!pconfig.isParallelSafe) { - warn('Your build is slower because some babel plugins are non-serializable'); + private addBabelCompat() { + let plugins = this.compatApp.extraBabelPlugins(); + let templateTransforms = this.compatApp.htmlbarsPlugins; + let babelMacros = this.compatApp.macrosConfig.babelPluginConfig(); + let { plugins: templateMacros, setConfig } = MacrosConfig.transforms(); + setConfig(this.compatApp.macrosConfig); + + let config: CompatBabelState = { + plugins, + templateTransforms, + babelMacros, + templateMacros: templateMacros as any, + }; + + let portableConfig = new Portable({ hints: this.portableHints }).dehydrate(config); + if (!portableConfig.isParallelSafe) { + throw new Error(`non-serializble babel plugins or AST transforms found in your app`); } + writeFileSync( - join(locateEmbroiderWorkingDir(this.compatApp.root), '_babel_config_.js'), - `module.exports = ${JSON.stringify(pconfig.config, null, 2)}`, - 'utf8' - ); - writeFileSync( - join(locateEmbroiderWorkingDir(this.compatApp.root), '_babel_filter_.js'), - babelFilterTemplate({ skipBabel: this.options.skipBabel, appRoot: this.origAppPackage.root }), + join(locateEmbroiderWorkingDir(this.compatApp.root), '_babel_compat_.js'), + ` + const { Portable } = require('@embroider/core/src/portable'); + module.exports = new Portable().hydrate(${JSON.stringify(portableConfig.value, null, 2)}); + `, 'utf8' ); } @@ -464,12 +346,6 @@ export class CompatAppBuilder { }); } - private addMacrosConfig(macrosConfig: any) { - outputJSONSync(join(locateEmbroiderWorkingDir(this.compatApp.root), 'macros-config.json'), macrosConfig, { - spaces: 2, - }); - } - // Classic addons providing custom content-for "app-boot" is no longer supported. // The purpose of this error message is to help developers to move the classic addons code. // Developers can deactivate it with useAddonAppBoot build option. @@ -515,35 +391,3 @@ function defaultAddonPackageRules(): PackageRules[] { .filter(Boolean) .reduce((a, b) => a.concat(b), []); } - -const babelFilterTemplate = jsHandlebarsCompile(` -const { babelFilter } = require(${JSON.stringify(require.resolve('@embroider/core'))}); -module.exports = babelFilter({{json-stringify skipBabel}}, "{{js-string-escape appRoot}}"); -`) as (params: { skipBabel: Options['skipBabel']; appRoot: string }) => string; - -function addCachablePlugin(babelConfig: TransformOptions) { - if (Array.isArray(babelConfig.plugins) && babelConfig.plugins.length > 0) { - const plugins = Object.create(null); - plugins[cacheBustingPluginPath] = cacheBustingPluginVersion; - - for (const plugin of babelConfig.plugins) { - let absolutePathToPlugin: string; - if (Array.isArray(plugin) && typeof plugin[0] === 'string') { - absolutePathToPlugin = plugin[0] as string; - } else if (typeof plugin === 'string') { - absolutePathToPlugin = plugin; - } else { - throw new Error(`[Embroider] a babel plugin without an absolute path was from: ${plugin}`); - } - - plugins[absolutePathToPlugin] = maybeNodeModuleVersion(absolutePathToPlugin); - } - - babelConfig.plugins.push([ - cacheBustingPluginPath, - { - plugins, - }, - ]); - } -} diff --git a/packages/compat/src/compat-app.ts b/packages/compat/src/compat-app.ts index 7b01dda28..b260968c0 100644 --- a/packages/compat/src/compat-app.ts +++ b/packages/compat/src/compat-app.ts @@ -16,12 +16,12 @@ import type { AddonMeta, EmberAppInstance, OutputFileToInputFileMap, PackageInfo import { writeJSONSync, ensureDirSync, copySync, pathExistsSync, existsSync, writeFileSync } from 'fs-extra'; import AddToTree from './add-to-tree'; import DummyPackage from './dummy-package'; -import type { TransformOptions } from '@babel/core'; +import type { PluginItem, TransformOptions } from '@babel/core'; import { isEmbroiderMacrosPlugin, MacrosConfig } from '@embroider/macros/src/node'; import resolvePackagePath from 'resolve-package-path'; import Concat from 'broccoli-concat'; import mapKeys from 'lodash/mapKeys'; -import { isEmberAutoImportDynamic, isInlinePrecompilePlugin } from './detect-babel-plugins'; +import { isEmberAutoImportDynamic, isHtmlbarColocation, isInlinePrecompilePlugin } from './detect-babel-plugins'; import loadAstPlugins from './prepare-htmlbars-ast-plugins'; import { readFileSync } from 'fs'; import semver from 'semver'; @@ -181,63 +181,31 @@ export default class CompatApp { } @Memoize() - babelConfig(): TransformOptions { - // this finds all the built-in babel configuration that comes with ember-cli-babel - const babelAddon = (this.legacyEmberAppInstance.project as any).findAddonByName('ember-cli-babel'); - const babelConfig = babelAddon.buildBabelOptions({ - 'ember-cli-babel': { - ...this.legacyEmberAppInstance.options['ember-cli-babel'], - includeExternalHelpers: true, - compileModules: false, - disableDebugTooling: false, - disablePresetEnv: false, - disableEmberModulesAPIPolyfill: false, - }, - }); - - let plugins = babelConfig.plugins as any[]; - let presets = babelConfig.presets; - - // this finds any custom babel configuration that's on the app (either - // because the app author explicitly added some, or because addons have - // pushed plugins into it). - let appBabel = this.legacyEmberAppInstance.options.babel; + extraBabelPlugins(): PluginItem[] { + // this finds any custom babel plugins on the app (either because the app + // author explicitly added some, or because addons have pushed plugins into + // it). + let appBabel: TransformOptions = this.legacyEmberAppInstance.options.babel; if (appBabel) { if (appBabel.plugins) { - plugins = appBabel.plugins.concat(plugins); - } - if (appBabel.presets) { - presets = appBabel.presets.concat(presets); + return appBabel.plugins.filter(p => { + // even if the app was using @embroider/macros, we drop it from the config + // here in favor of our globally-configured one. + return ( + !isEmbroiderMacrosPlugin(p) && + // similarly, if the app was already using an inline template compiler + // babel plugin, we remove it here because we have our own + // always-installed version of that (v2 addons are allowed to assume it + // will be present in the final app build, the app doesn't get to turn + // that off or configure it.) + !isInlinePrecompilePlugin(p) && + !isEmberAutoImportDynamic(p) && + !isHtmlbarColocation(p) + ); + }); } } - - plugins = plugins.filter(p => { - // even if the app was using @embroider/macros, we drop it from the config - // here in favor of our globally-configured one. - return ( - !isEmbroiderMacrosPlugin(p) && - // similarly, if the app was already using an inline template compiler - // babel plugin, we remove it here because we have our own - // always-installed version of that (v2 addons are allowed to assume it - // will be present in the final app build, the app doesn't get to turn - // that off or configure it.) - !isInlinePrecompilePlugin(p) && - !isEmberAutoImportDynamic(p) - ); - }); - - const config: TransformOptions = { - babelrc: false, - plugins, - presets, - // this is here because broccoli-middleware can't render a codeFrame full - // of terminal codes. It would be nice to add something like - // https://github.com/mmalecki/ansispan to broccoli-middleware so we can - // leave color enabled. - highlightCode: false, - }; - - return config; + return []; } @Memoize() diff --git a/packages/compat/src/detect-babel-plugins.ts b/packages/compat/src/detect-babel-plugins.ts index 894c8bc62..f27a5a07c 100644 --- a/packages/compat/src/detect-babel-plugins.ts +++ b/packages/compat/src/detect-babel-plugins.ts @@ -59,6 +59,19 @@ export function isInlinePrecompilePlugin(item: PluginItem) { return false; } +export function isHtmlbarColocation(item: PluginItem): boolean { + let pluginPath: string; + if (typeof item === 'string') { + pluginPath = item; + } else if (Array.isArray(item) && item.length > 0 && typeof item[0] === 'string') { + pluginPath = item[0]; + } else { + return false; + } + + return pluginPath.includes(join(sep, 'ember-cli-htmlbars', sep, 'lib', sep, 'colocated-babel-plugin')); +} + function matchesSourceFile(filename: string) { return Boolean(htmlbarPathMatches.find(match => filename.endsWith(match))); } diff --git a/packages/compat/src/rename-require-plugin.ts b/packages/compat/src/rename-require-plugin.ts deleted file mode 100644 index 71382e1e5..000000000 --- a/packages/compat/src/rename-require-plugin.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { types as t } from '@babel/core'; -import type { NodePath } from '@babel/traverse'; - -export default function inlineHBSTransform(): unknown { - return { - visitor: { - ImportDefaultSpecifier(path: NodePath) { - if (path.node.local.name === 'require') { - path.scope.rename('require'); - } - }, - }, - }; -} diff --git a/packages/compat/tests/audit.test.ts b/packages/compat/tests/audit.test.ts index 4634d5cad..8aa99a592 100644 --- a/packages/compat/tests/audit.test.ts +++ b/packages/compat/tests/audit.test.ts @@ -8,7 +8,6 @@ import { Audit } from '../src/audit'; import type { CompatResolverOptions } from '../src/resolver-transform'; import type { TransformOptions } from '@babel/core'; import type { Options as InlinePrecompileOptions } from 'babel-plugin-ember-template-compilation'; -import { makePortable } from '@embroider/core/src/portable-babel-config'; import type { Transform } from 'babel-plugin-ember-template-compilation'; import type { Options as ResolverTransformOptions } from '../src/resolver-transform'; @@ -53,6 +52,7 @@ describe('audit', function () { resolvableExtensions, autoRun: true, staticAppPaths: [], + emberVersion: '4.0.0', }; let babel: TransformOptions = { @@ -77,11 +77,6 @@ describe('audit', function () { 'index.html': ``, 'app.js': `import Hello from './hello.hbs';`, 'hello.hbs': ``, - 'babel_config.js': `module.exports = ${JSON.stringify( - makePortable(babel, { basedir: '.' }, []).config, - null, - 2 - )}`, node_modules: { '.embroider': { 'resolver.json': JSON.stringify(resolverConfig), diff --git a/packages/core/src/module-resolver.ts b/packages/core/src/module-resolver.ts index 1eca30b01..eed011d9f 100644 --- a/packages/core/src/module-resolver.ts +++ b/packages/core/src/module-resolver.ts @@ -97,6 +97,7 @@ export interface Options { amdCompatibility: Required; autoRun: boolean; staticAppPaths: string[]; + emberVersion: string; } // TODO: once we can remove the stage2 entrypoint this type can get streamlined diff --git a/packages/core/src/options.ts b/packages/core/src/options.ts index b89b5672f..d957c6b26 100644 --- a/packages/core/src/options.ts +++ b/packages/core/src/options.ts @@ -59,14 +59,6 @@ export default interface Options { // route templates, and controllers which are governed by splitAtRoutes). staticAppPaths?: string[]; - // By default, all modules that get imported into the app go through Babel, so - // that all code will conform with your Babel targets. This option allows you - // to turn Babel off for a particular package. You might need this to work - // around a transpiler bug or you might use this as a build-performance - // optimization if you've manually verified that a particular package doesn't - // need transpilation to be safe in your target browsers. - skipBabel?: { package: string; semverRange?: string }[]; - // This is a performance optimization that can help you avoid the "Your build // is slower because some babel plugins are non-serializable" penalty. If you // provide the locations of known non-serializable objects, we can discover @@ -131,7 +123,6 @@ export function optionsWithDefaults(options?: Options): Required { staticComponents: false, splitAtRoutes: [], staticAppPaths: [], - skipBabel: [], pluginHints: [], amdCompatibility: 'cjs' as const, }; diff --git a/packages/core/src/portable-babel-config.ts b/packages/core/src/portable-babel-config.ts deleted file mode 100644 index f9dc7b3ea..000000000 --- a/packages/core/src/portable-babel-config.ts +++ /dev/null @@ -1,138 +0,0 @@ -import type { TransformOptions } from '@babel/core'; -import { join } from 'path'; -import resolve from 'resolve'; -import type { PortableHint } from './portable'; -import { Portable } from './portable'; - -export type ResolveOptions = { basedir: string } | { resolve: (name: string) => any }; - -export function makePortable( - config: TransformOptions, - resolveOptions: ResolveOptions, - hints: PortableHint[] -): { config: TransformOptions; isParallelSafe: boolean } { - return new PortableBabelConfig(resolveOptions, hints).convert(config); -} - -class PortableBabelConfig { - private resolve: (name: string) => any; - private basedir: string | undefined; - - constructor(resolveOptions: ResolveOptions, private hints: PortableHint[]) { - if ('resolve' in resolveOptions) { - this.resolve = resolveOptions.resolve; - } else { - this.basedir = resolveOptions.basedir; - this.resolve = (name: string) => resolve.sync(name, { basedir: resolveOptions.basedir }); - } - } - - convert(config: TransformOptions): { config: TransformOptions; isParallelSafe: boolean } { - let portable: Portable = new Portable({ - hints: this.hints, - dehydrate: (value: any, accessPath: string[]) => { - // this custom dehydrate hook handles babel plugins & presets. If we're - // not looking at plugins or presets, continue with stock Portable - // behavior - if (accessPath.length !== 2 || (accessPath[0] !== 'plugins' && accessPath[0] !== 'presets')) { - return undefined; - } - - // standardize to always handle an array - if (!Array.isArray(value)) { - value = [value]; - } - - let [plugin, argument, asName] = value; - - // string plugins need to get resolved correctly into absolute paths, - // so they will really be portable - if (typeof plugin === 'string') { - plugin = this.resolveBabelPlugin(plugin); - } - - // next we deal with serializability. Our Portable system already - // understands the protocol used by ember-cli-babel to identify plugin - // classes and get back to their serializable forms, so this will - // handle that case. - let dehydrated = portable.dehydrate([plugin, argument, asName], accessPath.concat('_internal')); - - if (dehydrated.needsHydrate) { - // we can eliminate the need for rehydration by going through our own - // portable babel launcher - return { - value: [ - join(__dirname, 'portable-babel-launcher.js'), - { module: dehydrated.value[0], arg: dehydrated.value[1], hints: this.hints }, - dehydrated.value[2] || `portable-babel-launcher-${accessPath[1]}`, - ], - needsHydrate: false, - isParallelSafe: dehydrated.isParallelSafe, - }; - } else { - // trim back down our array, because trailing undefined will get - // converted into null via json.stringify, and babel will complain - // about that. - while (dehydrated.value.length > 0 && dehydrated.value[dehydrated.value.length - 1] == null) { - dehydrated.value.pop(); - } - if (dehydrated.value.length === 1) { - dehydrated.value = dehydrated.value[0]; - } - return { - value: dehydrated.value, - needsHydrate: dehydrated.needsHydrate, - isParallelSafe: dehydrated.isParallelSafe, - }; - } - }, - }); - let result = portable.dehydrate(config); - if (result.needsHydrate) { - throw new Error(`bug: portable babel configs aren't supposed to need hydration`); - } - return { config: result.value, isParallelSafe: result.isParallelSafe }; - } - - // babel lets you use relative paths, absolute paths, package names, and - // package name shorthands. - // - // my-plugin -> my-plugin - // my-plugin -> babel-plugin-my-plugin - // @me/thing -> @me/thing - // @me/thing -> @me/babel-plugin-thing - // ./here -> /your/app/here - // /tmp/there -> /tmp/there - // - private resolveBabelPlugin(name: string) { - try { - return this.resolve(name); - } catch (err) { - if (err.code !== 'MODULE_NOT_FOUND') { - throw err; - } - if (name.startsWith('.') || name.startsWith('/')) { - throw err; - } - try { - let expanded; - if (name.startsWith('@')) { - let [space, pkg, ...rest] = name.split('/'); - expanded = [space, `babel-plugin-${pkg}`, ...rest].join('/'); - } else { - expanded = `babel-plugin-${name}`; - } - return this.resolve(expanded); - } catch (err2) { - if (err2.code !== 'MODULE_NOT_FOUND') { - throw err2; - } - if (this.basedir) { - throw new Error(`unable to resolve babel plugin ${name} from ${this.basedir}`); - } else { - throw new Error(`unable to resolve babel plugin ${name}`); - } - } - } - } -} diff --git a/packages/core/src/portable-babel-launcher.ts b/packages/core/src/portable-babel-launcher.ts deleted file mode 100644 index 12e383845..000000000 --- a/packages/core/src/portable-babel-launcher.ts +++ /dev/null @@ -1,83 +0,0 @@ -import type { PortableHint } from './portable'; -import { Portable } from './portable'; - -export default function babelLauncher( - this: any, - babel: any, - launch: { module: any; arg: any; hints: PortableHint[] }, - key: string -) { - let p = new Portable({ hints: launch.hints }); - let hydrated = p.hydrate(launch); - let module; - if (typeof hydrated.module === 'string') { - // eslint-disable-next-line @typescript-eslint/no-require-imports - module = require(hydrated.module); - if (module.__esModule) { - module = module.default; - } - } else { - module = hydrated.module; - } - - let plugin = module.call(this, babel, hydrated.arg, key); - let innerStates = new WeakMap(); - - function convertState(state: any) { - let innerState = innerStates.get(state); - if (!innerState) { - innerState = Object.assign({}, state, { opts: hydrated.arg }); - innerStates.set(state, innerState); - } - return innerState; - } - - function wrap1(original: any) { - if (typeof original === 'function') { - return function (this: any, file: any) { - return original.call(convertState(this), file); - }; - } - } - - function wrap2(original: Function) { - return function (this: any, path: any, state: any) { - return original.call(convertState(this), path, convertState(state)); - }; - } - - let visitorProxy = { - get(target: any, prop: string) { - let original = target[prop]; - if (typeof original === 'function') { - return wrap2(original); - } - if (original && typeof original === 'object') { - let wrapped: any = {}; - if (typeof original.exit === 'function') { - wrapped.exit = wrap2(original.exit); - } - if (typeof original.enter === 'function') { - wrapped.enter = wrap2(original.enter); - } - return wrapped; - } - return original; - }, - }; - - return new Proxy(plugin, { - get(target, prop) { - let original = target[prop]; - switch (prop) { - case 'pre': - case 'post': - return wrap1(original); - case 'visitor': - return new Proxy(original, visitorProxy); - default: - return original; - } - }, - }); -} diff --git a/packages/core/tests/portable-babel-config.test.ts b/packages/core/tests/portable-babel-config.test.ts deleted file mode 100644 index 1895b3581..000000000 --- a/packages/core/tests/portable-babel-config.test.ts +++ /dev/null @@ -1,290 +0,0 @@ -import type { PluginItem, TransformOptions } from '@babel/core'; -import { makePortable } from '../src/portable-babel-config'; -import { join, sep, resolve } from 'path'; -import exampleTarget from './example-target'; -import { Portable, protocol } from '../src/portable'; - -function resolvableNames(...names: string[]) { - return { - resolve(name: string) { - if (name.startsWith('/')) { - return name; - } - if (name.startsWith('.')) { - return join('/notional-base-dir', name); - } - if (names.includes(name)) { - return join('/notional-base-dir/node_modules', name, 'index.js'); - } - let e = new Error(`stub resolver failure for ${name}`); - (e as any).code = 'MODULE_NOT_FOUND'; - throw e; - }, - }; -} - -function loadParallelSafe({ config, isParallelSafe }: { config: TransformOptions; isParallelSafe: boolean }): any { - if (!isParallelSafe) { - throw new Error(`not parallel safe`); - } - delete (global as any)[protocol]; - return load({ config }); -} - -function load({ config }: { config: TransformOptions }): any { - return JSON.parse(JSON.stringify(config)); -} - -function assertPortableBabelLauncher(plugin: PluginItem): { module: any; arg: any } { - if (!Array.isArray(plugin)) { - throw new Error(`expected array plugin not ${plugin}`); - } - expect(plugin[0]).toBe(resolve(__dirname, '../src/portable-babel-launcher.js')); - return new Portable().hydrate(plugin[1]); -} - -describe('portable-babel-config', () => { - test('absolute path', () => { - let config = makePortable( - { - plugins: ['/path/to/some/plugin.js'], - }, - resolvableNames(), - [] - ); - expect(loadParallelSafe(config).plugins).toEqual(['/path/to/some/plugin.js']); - }); - - test('local path', () => { - let config = makePortable( - { - plugins: ['./path/to/some/plugin.js'], - }, - resolvableNames(), - [] - ); - expect(loadParallelSafe(config).plugins).toEqual([ - '/notional-base-dir/path/to/some/plugin.js'.split('/').join(sep), - ]); - }); - - test('package name', () => { - let config = makePortable( - { - plugins: ['my-package'], - }, - resolvableNames('my-package'), - [] - ); - expect(loadParallelSafe(config).plugins).toEqual([ - '/notional-base-dir/node_modules/my-package/index.js'.split('/').join(sep), - ]); - }); - - test('package name shorthand', () => { - let config = makePortable( - { - plugins: ['my-package'], - }, - resolvableNames('babel-plugin-my-package'), - [] - ); - expect(loadParallelSafe(config).plugins).toEqual([ - '/notional-base-dir/node_modules/babel-plugin-my-package/index.js'.split('/').join(sep), - ]); - }); - - test('namespaced package name', () => { - let config = makePortable( - { - plugins: ['@me/my-package'], - }, - resolvableNames('@me/my-package'), - [] - ); - expect(loadParallelSafe(config).plugins).toEqual([ - '/notional-base-dir/node_modules/@me/my-package/index.js'.split('/').join(sep), - ]); - }); - - test('namespaced package name shorthand', () => { - let config = makePortable( - { - plugins: ['@me/my-package'], - }, - resolvableNames('@me/babel-plugin-my-package'), - [] - ); - expect(loadParallelSafe(config).plugins).toEqual([ - '/notional-base-dir/node_modules/@me/babel-plugin-my-package/index.js'.split('/').join(sep), - ]); - }); - - test('resolves name with json-safe config', () => { - let config = makePortable( - { - plugins: [['my-package', { theOptions: 'cool' }]], - }, - resolvableNames('babel-plugin-my-package'), - [] - ); - expect(loadParallelSafe(config).plugins).toEqual([ - ['/notional-base-dir/node_modules/babel-plugin-my-package/index.js'.split('/').join(sep), { theOptions: 'cool' }], - ]); - }); - - test('resolves name with arbitrary config', () => { - let options = { - precompile() { - return 'cool'; - }, - }; - let config = makePortable( - { - plugins: [['my-package', options]], - }, - resolvableNames('babel-plugin-my-package'), - [] - ); - expect(config.isParallelSafe).toBeFalsy(); - let { module, arg } = assertPortableBabelLauncher(load(config).plugins[0]); - expect(module).toBe('/notional-base-dir/node_modules/babel-plugin-my-package/index.js'); - expect(arg).toEqual(options); - }); - - test('passes through bare function', () => { - let func = function () {}; - let config = makePortable( - { - plugins: [func], - }, - resolvableNames(), - [] - ); - expect(config.isParallelSafe).toBeFalsy(); - let { module } = assertPortableBabelLauncher(load(config).plugins[0]); - expect(module).toBe(func); - }); - - test('passes through function with args', () => { - let func = function () {}; - let args = { theArgs: 'here' }; - let config = makePortable( - { - plugins: [[func, args]], - }, - resolvableNames(), - [] - ); - expect(config.isParallelSafe).toBeFalsy(); - let { module, arg } = assertPortableBabelLauncher(load(config).plugins[0]); - expect(module).toBe(func); - expect(arg).toEqual(args); - }); - - test('respects _parallelBabel api with buildUsing on PluginTarget', () => { - (exampleFunction as any)._parallelBabel = { - requireFile: __filename, - buildUsing: 'exampleFunction', - params: { - theParams: 'are here', - }, - }; - let config = makePortable( - { - plugins: [exampleFunction], - }, - resolvableNames(), - [] - ); - expect(config.isParallelSafe).toBeTruthy(); - let { module } = assertPortableBabelLauncher(load(config).plugins[0]); - expect(module).toEqual('this is the example function with theParams=are here'); - }); - - test('respects _parallelBabel api with useMethod on PluginTarget', () => { - (exampleFunction as any)._parallelBabel = { - requireFile: __filename, - useMethod: 'exampleFunction', - }; - let config = makePortable( - { - plugins: [exampleFunction], - }, - resolvableNames(), - [] - ); - expect(config.isParallelSafe).toBeTruthy(); - let { module } = assertPortableBabelLauncher(load(config).plugins[0]); - expect(module).toBe(exampleFunction); - }); - - test('respects _parallelBabel api with with only requireFile on PluginTarget', () => { - (exampleTarget as any)._parallelBabel = { - requireFile: resolve(__dirname, 'example-target.js'), - }; - let config = makePortable( - { - plugins: [[exampleTarget, 'hi']], - }, - resolvableNames(), - [] - ); - expect(config.isParallelSafe).toBeTruthy(); - let output = loadParallelSafe(config); - let { module, arg } = assertPortableBabelLauncher(output.plugins[0]); - expect(module).toEqual(exampleTarget); - expect(arg).toEqual('hi'); - }); - - test('respects _parallelBabel api on PluginOptions', () => { - function precompile() {} - precompile._parallelBabel = { - requireFile: __filename, - buildUsing: 'exampleFunction', - params: { theParams: 'reconstituted precompile' }, - }; - - let config = makePortable( - { - plugins: [['my-plugin', { precompile }]], - }, - resolvableNames('my-plugin'), - [] - ); - expect(config.isParallelSafe).toBeTruthy(); - let output = loadParallelSafe(config); - let { module, arg } = assertPortableBabelLauncher(output.plugins[0]); - expect(module).toEqual('/notional-base-dir/node_modules/my-plugin/index.js'); - expect(arg).toEqual({ precompile: 'this is the example function with theParams=reconstituted precompile' }); - }); - - test('undefined is a serializable value', function () { - let config = makePortable( - { - plugins: ['./x', { value: undefined }], - }, - resolvableNames(), - [] - ); - expect(config.isParallelSafe).toBeTruthy(); - let output = loadParallelSafe(config); - expect(output.plugins[0][1].value).toBeUndefined(); - }); -}); - -export function exampleFunction(params: any) { - if (params) { - return `this is the example function with theParams=${params.theParams}`; - } else { - return `this is the example function with no params`; - } -} - -export function examplePlugin(_babel: any, params: any) { - if (params) { - return `this is the example plugin with params=${params}`; - } else { - return `this is the example plugin with no params`; - } -} diff --git a/packages/shared-internals/src/babel-filter.ts b/packages/shared-internals/src/babel-filter.ts deleted file mode 100644 index 96cebe448..000000000 --- a/packages/shared-internals/src/babel-filter.ts +++ /dev/null @@ -1,34 +0,0 @@ -import PackageCache from './package-cache'; -import semver from 'semver'; - -export default function babelFilter(skipBabel: { package: string; semverRange?: string }[], appRoot: string) { - return function shouldTranspileFile(filename: string) { - if (!babelCanHandle(filename)) { - // quick exit for non JS extensions - return false; - } - - let owner = PackageCache.shared('embroider', appRoot).ownerOfFile(filename); - if (owner) { - for (let { package: pkg, semverRange } of skipBabel) { - if (owner.name === pkg && (semverRange == null || semver.satisfies(owner.version, semverRange))) { - if (owner.isEmberAddon()) { - throw new Error( - `You can't use skipBabel to disable transpilation of Ember addons, it only works for non-Ember third-party packages` - ); - } - return false; - } - } - } - return true; - }; -} - -function babelCanHandle(filename: string) { - // we can handle .mjs, .js and .ts files with babel. If typescript is enabled, - // .ts files become resolvable and stage3 will be asking us if they should get - // transpiled and the answer is yes. If typescript is not enbled, they will - // not be resolvable, so stage3 won't ask us about them. - return /\.m?[jt]s$/i.test(filename); -} diff --git a/packages/shared-internals/src/index.ts b/packages/shared-internals/src/index.ts index 67944148b..074128482 100644 --- a/packages/shared-internals/src/index.ts +++ b/packages/shared-internals/src/index.ts @@ -12,7 +12,6 @@ export { default as Package, V2AddonPackage as AddonPackage, V2AppPackage as App export { default as PackageCache } from './package-cache'; export type { RewrittenPackageIndex } from './rewritten-package-cache'; export { RewrittenPackageCache } from './rewritten-package-cache'; -export { default as babelFilter } from './babel-filter'; export { default as packageName } from './package-name'; export { default as tmpdir } from './tmpdir'; export * from './ember-cli-models'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1157bf6e8..4a70b7944 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -211,6 +211,9 @@ importers: babel-import-util: specifier: ^2.0.0 version: 2.1.1 + babel-plugin-debug-macros: + specifier: ^1.0.2 + version: 1.0.2(@babel/core@7.25.2) babel-plugin-ember-template-compilation: specifier: ^2.1.1 version: 2.2.5 @@ -1475,9 +1478,12 @@ importers: '@babel/eslint-parser': specifier: ^7.22.5 version: 7.25.1(@babel/core@7.25.2)(eslint@8.57.0) - '@babel/plugin-proposal-decorators': - specifier: ^7.22.5 - version: 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-runtime': + specifier: ^7.25.4 + version: 7.25.4(@babel/core@7.25.2) + '@babel/runtime': + specifier: ^7.25.6 + version: 7.25.6 '@ember/optional-features': specifier: ^2.0.0 version: 2.1.0 @@ -1514,12 +1520,15 @@ importers: '@rollup/plugin-babel': specifier: ^5.3.1 version: 5.3.1(@babel/core@7.25.2)(rollup@3.29.4) - broccoli-asset-rev: - specifier: ^3.0.0 - version: 3.0.0 + babel-plugin-ember-template-compilation: + specifier: ^2.2.5 + version: 2.2.5 concurrently: specifier: ^8.2.0 version: 8.2.2 + decorator-transforms: + specifier: ^2.0.0 + version: 2.0.0(@babel/core@7.25.2) ember-auto-import: specifier: ^2.6.3 version: 2.7.4 @@ -9843,6 +9852,17 @@ packages: '@babel/core': 7.25.2 semver: 5.7.2 + /babel-plugin-debug-macros@1.0.2(@babel/core@7.25.2): + resolution: {integrity: sha512-ADkMh1LL45678c+4iGn3Fp8hdI9qvxGBkH5x9HNiIlgYJGdQWmYNcA2cS3XAr76N85kDCg4VpqsTN1hFX2jbEA==} + engines: {node: '>=16'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.25.2 + babel-import-util: 2.1.1 + semver: 7.6.3 + dev: false + /babel-plugin-ember-data-packages-polyfill@0.1.2: resolution: {integrity: sha512-kTHnOwoOXfPXi00Z8yAgyD64+jdSXk3pknnS7NlqnCKAU6YDkXZ4Y7irl66kaZjZn0FBBt0P4YOZFZk85jYOww==} engines: {node: 6.* || 8.* || 10.* || >= 12.*} diff --git a/tests/app-template/babel.config.cjs b/tests/app-template/babel.config.cjs index baf775d4b..693c81bea 100644 --- a/tests/app-template/babel.config.cjs +++ b/tests/app-template/babel.config.cjs @@ -1,19 +1,48 @@ -// eslint-disable-next-line n/no-missing-require +const { + transformsFromV1Addons, + looseModeSupport, + templateMacros, + babelMacros, + adjustImports, + oldDebugMacros, + templateColocation, +} = require("@embroider/compat/babel"); -let config; - -// TODO - remove this once we have the better solution for injecting stage1 babel config into a real config file -// this is needed because there are things (like ember-composible-helpers) that are now finding our babel config during -// their stage1 build and historically they will never (99% of the time) have found any babel config. -// we might need to keep something like this so that prebuild will never apply babel configs during stage1 i.e. a util -// function that wraps your whole babel config -if ( - process.env.EMBROIDER_PREBUILD || - process.env.EMBROIDER_TEST_SETUP_FORCE === "classic" -) { - config = {}; -} else { - config = require("./node_modules/.embroider/_babel_config_"); -} - -module.exports = config; +module.exports = { + plugins: [ + [ + "babel-plugin-ember-template-compilation", + { + compilerPath: "ember-source/dist/ember-template-compiler.js", + enableLegacyModules: [ + "ember-cli-htmlbars", + "ember-cli-htmlbars-inline-precompile", + "htmlbars-inline-precompile", + ], + transforms: [ + ...transformsFromV1Addons(), + looseModeSupport(), + ...templateMacros(), + ], + }, + ], + ...babelMacros(), + [ + "module:decorator-transforms", + { + runtime: { import: require.resolve("decorator-transforms/runtime") }, + }, + ], + [ + "@babel/plugin-transform-runtime", + { + absoluteRuntime: __dirname, + useESModules: true, + regenerator: false, + }, + ], + adjustImports(), + ...oldDebugMacros(), + templateColocation(), + ], +}; diff --git a/tests/app-template/package.json b/tests/app-template/package.json index 0d674cf66..734f0f988 100644 --- a/tests/app-template/package.json +++ b/tests/app-template/package.json @@ -31,7 +31,8 @@ "devDependencies": { "@babel/core": "^7.19.3", "@babel/eslint-parser": "^7.22.5", - "@babel/plugin-proposal-decorators": "^7.22.5", + "@babel/plugin-transform-runtime": "^7.25.4", + "@babel/runtime": "^7.25.6", "@ember/optional-features": "^2.0.0", "@ember/string": "^3.1.1", "@ember/test-helpers": "^3.0.3", @@ -44,9 +45,10 @@ "@glimmer/component": "^1.1.2", "@glimmer/tracking": "^1.1.2", "@rollup/plugin-babel": "^5.3.1", - "broccoli-asset-rev": "^3.0.0", + "babel-plugin-ember-template-compilation": "^2.2.5", "concurrently": "^8.2.0", "ember-auto-import": "^2.6.3", + "decorator-transforms": "^2.0.0", "ember-cli": "~5.0.0", "ember-cli-app-version": "^6.0.0", "ember-cli-babel": "^7.26.11", diff --git a/tests/scenarios/compat-resolver-test.ts b/tests/scenarios/compat-resolver-test.ts index bdce94047..32b0c55fb 100644 --- a/tests/scenarios/compat-resolver-test.ts +++ b/tests/scenarios/compat-resolver-test.ts @@ -110,6 +110,7 @@ Scenarios.fromProject(() => new Project()) ], autoRun: true, staticAppPaths: [], + emberVersion: '4.0.0', }; givenFiles({ diff --git a/tests/scenarios/core-resolver-test.ts b/tests/scenarios/core-resolver-test.ts index d5b7caf6a..9d500c583 100644 --- a/tests/scenarios/core-resolver-test.ts +++ b/tests/scenarios/core-resolver-test.ts @@ -138,6 +138,7 @@ Scenarios.fromProject(() => new Project()) ], autoRun: true, staticAppPaths: [], + emberVersion: '4.0.0', }; givenFiles({ From e819961ae1ef8e5ae16780f11b2ab495156a061a Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Mon, 9 Sep 2024 14:17:09 -0400 Subject: [PATCH 2/9] going back to .jshere --- packages/compat/{babel.cjs => babel.js} | 0 packages/compat/package.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/compat/{babel.cjs => babel.js} (100%) diff --git a/packages/compat/babel.cjs b/packages/compat/babel.js similarity index 100% rename from packages/compat/babel.cjs rename to packages/compat/babel.js diff --git a/packages/compat/package.json b/packages/compat/package.json index 210a0e384..7f3dda833 100644 --- a/packages/compat/package.json +++ b/packages/compat/package.json @@ -12,7 +12,7 @@ "author": "Edward Faulkner", "main": "src/index.js", "files": [ - "babel.cjs", + "babel.js", "src/**/*.js", "src/**/*.d.ts", "src/**/*.js.map" From 0f9097a0218f4e4988f8648cea42f5e13b63d545 Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Mon, 9 Sep 2024 14:50:15 -0400 Subject: [PATCH 3/9] adjusting babel config --- packages/compat/package.json | 2 +- packages/compat/src/babel.ts | 13 +++ packages/core/package.json | 2 +- packages/macros/package.json | 2 +- pnpm-lock.yaml | 136 ++++++++++++++++++++-------- tests/app-template/babel.config.cjs | 24 ++--- tests/app-template/package.json | 4 +- tests/scenarios/package.json | 2 +- 8 files changed, 123 insertions(+), 62 deletions(-) diff --git a/packages/compat/package.json b/packages/compat/package.json index 7f3dda833..137b8fc00 100644 --- a/packages/compat/package.json +++ b/packages/compat/package.json @@ -37,7 +37,7 @@ "assert-never": "^1.1.0", "babel-import-util": "^2.0.0", "babel-plugin-debug-macros": "^1.0.2", - "babel-plugin-ember-template-compilation": "^2.1.1", + "babel-plugin-ember-template-compilation": "^2.3.0", "babel-plugin-syntax-dynamic-import": "^6.18.0", "babylon": "^6.18.0", "bind-decorator": "^1.0.11", diff --git a/packages/compat/src/babel.ts b/packages/compat/src/babel.ts index 5ba21c037..7ab426552 100644 --- a/packages/compat/src/babel.ts +++ b/packages/compat/src/babel.ts @@ -34,6 +34,11 @@ function loadCompatConfig(): CompatBabelState { const resolverLoader = new ResolverLoader(process.cwd()); +export function pluginsFromV1Addons() { + let config = loadCompatConfig(); + return config.plugins; +} + export function transformsFromV1Addons() { let config = loadCompatConfig(); return config.templateTransforms; @@ -143,3 +148,11 @@ export function templateColocation(): PluginItem { }; return [templateColocationPluginPath, colocationOptions]; } + +export function babelCompatSupport(): PluginItem[] { + return [...babelMacros(), adjustImports(), ...oldDebugMacros(), templateColocation(), ...pluginsFromV1Addons()]; +} + +export function templateCompatSupport(): Transform[] { + return [looseModeSupport(), ...templateMacros(), ...transformsFromV1Addons()]; +} diff --git a/packages/core/package.json b/packages/core/package.json index 757c0c618..d3a0a4c3f 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -27,7 +27,7 @@ "@embroider/reverse-exports": "workspace:*", "@embroider/shared-internals": "workspace:*", "assert-never": "^1.2.1", - "babel-plugin-ember-template-compilation": "^2.1.1", + "babel-plugin-ember-template-compilation": "^2.3.0", "broccoli-node-api": "^1.7.0", "broccoli-persistent-filter": "^3.1.2", "broccoli-plugin": "^4.0.7", diff --git a/packages/macros/package.json b/packages/macros/package.json index c14fee21e..2098e97c0 100644 --- a/packages/macros/package.json +++ b/packages/macros/package.json @@ -47,7 +47,7 @@ "@types/node": "^15.12.2", "@types/resolve": "^1.20.0", "@types/semver": "^7.3.6", - "babel-plugin-ember-template-compilation": "^2.1.1", + "babel-plugin-ember-template-compilation": "^2.3.0", "code-equality-assertions": "^0.9.0", "scenario-tester": "^3.0.1", "typescript": "^5.4.5" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4a70b7944..c2270b21e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -215,8 +215,8 @@ importers: specifier: ^1.0.2 version: 1.0.2(@babel/core@7.25.2) babel-plugin-ember-template-compilation: - specifier: ^2.1.1 - version: 2.2.5 + specifier: ^2.3.0 + version: 2.3.0 babel-plugin-syntax-dynamic-import: specifier: ^6.18.0 version: 6.18.0 @@ -402,8 +402,8 @@ importers: specifier: ^1.2.1 version: 1.3.0 babel-plugin-ember-template-compilation: - specifier: ^2.1.1 - version: 2.2.5 + specifier: ^2.3.0 + version: 2.3.0 broccoli-node-api: specifier: ^1.7.0 version: 1.7.0 @@ -599,8 +599,8 @@ importers: specifier: ^7.3.6 version: 7.5.8 babel-plugin-ember-template-compilation: - specifier: ^2.1.1 - version: 2.2.5 + specifier: ^2.3.0 + version: 2.3.0 code-equality-assertions: specifier: ^0.9.0 version: 0.9.0(@types/jest@29.5.12)(qunit@2.22.0) @@ -1492,7 +1492,7 @@ importers: version: 3.1.1 '@ember/test-helpers': specifier: ^3.0.3 - version: 3.3.1(@babel/core@7.25.2)(ember-source@5.8.0) + version: 3.3.1(@babel/core@7.25.2)(ember-source@5.11.0) '@embroider/compat': specifier: workspace:* version: link:../../packages/compat @@ -1521,8 +1521,8 @@ importers: specifier: ^5.3.1 version: 5.3.1(@babel/core@7.25.2)(rollup@3.29.4) babel-plugin-ember-template-compilation: - specifier: ^2.2.5 - version: 2.2.5 + specifier: ^2.3.0 + version: 2.3.0 concurrently: specifier: ^8.2.0 version: 8.2.2 @@ -1537,7 +1537,7 @@ importers: version: 5.0.0 ember-cli-app-version: specifier: ^6.0.0 - version: 6.0.1(ember-source@5.8.0) + version: 6.0.1(ember-source@5.11.0) ember-cli-babel: specifier: ^7.26.11 version: 7.26.11 @@ -1564,19 +1564,19 @@ importers: version: 2.1.2(@babel/core@7.25.2) ember-modifier: specifier: ^4.1.0 - version: 4.2.0(@babel/core@7.25.2)(ember-source@5.8.0) + version: 4.2.0(@babel/core@7.25.2)(ember-source@5.11.0) ember-page-title: specifier: ^7.0.0 version: 7.0.0 ember-qunit: specifier: ^7.0.0 - version: 7.0.0(@ember/test-helpers@3.3.1)(ember-source@5.8.0)(qunit@2.22.0) + version: 7.0.0(@ember/test-helpers@3.3.1)(ember-source@5.11.0)(qunit@2.22.0) ember-resolver: specifier: ^10.1.0 - version: 10.1.1(@ember/string@3.1.1)(ember-source@5.8.0) + version: 10.1.1(@ember/string@3.1.1)(ember-source@5.11.0) ember-source: - specifier: ~5.8.0 - version: 5.8.0(patch_hash=qsivfx5huurlb5tuvochap65l4)(@babel/core@7.25.2) + specifier: 5.11.0 + version: 5.11.0(patch_hash=bo72463n2ws4z6rctmcukxpqeq)(@glimmer/component@1.1.2) ember-template-lint: specifier: ^5.10.1 version: 5.13.0 @@ -1770,8 +1770,8 @@ importers: specifier: ^7.3.6 version: 7.5.8 babel-plugin-ember-template-compilation: - specifier: ^2.1.1 - version: 2.2.5 + specifier: ^2.3.0 + version: 2.3.0 bootstrap: specifier: ^4.3.1 version: 4.6.2(popper.js@1.16.1) @@ -5612,7 +5612,7 @@ packages: - webpack dev: true - /@ember/test-helpers@3.3.1(@babel/core@7.25.2)(ember-source@5.8.0): + /@ember/test-helpers@3.3.1(@babel/core@7.25.2)(ember-source@5.11.0): resolution: {integrity: sha512-h4uFBy4pquBtHsHI+tx9S0wtMmn1L+8dkXiDiyoqG1+3e0Awk6GBujiFM9s4ANq6wC8uIhC3wEFyts10h2OAoQ==} engines: {node: 16.* || >= 18} peerDependencies: @@ -5627,7 +5627,7 @@ packages: ember-auto-import: 2.7.4 ember-cli-babel: 8.2.0(@babel/core@7.25.2) ember-cli-htmlbars: 6.3.0 - ember-source: 5.8.0(patch_hash=qsivfx5huurlb5tuvochap65l4)(@babel/core@7.25.2) + ember-source: 5.11.0(patch_hash=bo72463n2ws4z6rctmcukxpqeq)(@glimmer/component@1.1.2) transitivePeerDependencies: - '@babel/core' - '@glint/template' @@ -9882,8 +9882,8 @@ packages: dependencies: ember-rfc176-data: 0.3.18 - /babel-plugin-ember-template-compilation@2.2.5: - resolution: {integrity: sha512-NQ2DT0DsYyHVrEpFQIy2U8S91JaKSE8NOSZzMd7KZFJVgA6KodJq3Uj852HcH9LsSfvwppnM+dRo1G8bzTnnFw==} + /babel-plugin-ember-template-compilation@2.3.0: + resolution: {integrity: sha512-4ZrKVSqdw5PxEKRbqfOpPhrrNBDG3mFPhyT6N1Oyyem81ZIkCvNo7TPKvlTHeFxqb6HtUvCACP/pzFpZ74J4pg==} engines: {node: '>= 12.*'} dependencies: '@glimmer/syntax': 0.84.3 @@ -12685,7 +12685,7 @@ packages: '@embroider/shared-internals': 2.6.3 babel-loader: 8.3.0(@babel/core@7.25.2) babel-plugin-ember-modules-api-polyfill: 3.5.0 - babel-plugin-ember-template-compilation: 2.2.5 + babel-plugin-ember-template-compilation: 2.3.0 babel-plugin-htmlbars-inline-precompile: 5.3.1 babel-plugin-syntax-dynamic-import: 6.18.0 broccoli-debug: 0.6.5 @@ -12729,7 +12729,7 @@ packages: '@embroider/shared-internals': 2.6.3 babel-loader: 8.3.0(@babel/core@7.25.2)(webpack@5.94.0) babel-plugin-ember-modules-api-polyfill: 3.5.0 - babel-plugin-ember-template-compilation: 2.2.5 + babel-plugin-ember-template-compilation: 2.3.0 babel-plugin-htmlbars-inline-precompile: 5.3.1 babel-plugin-syntax-dynamic-import: 6.18.0 broccoli-debug: 0.6.5 @@ -12849,27 +12849,27 @@ packages: - supports-color dev: true - /ember-cli-app-version@6.0.1(ember-source@5.3.0): + /ember-cli-app-version@6.0.1(ember-source@5.11.0): resolution: {integrity: sha512-XA1FwkWA5QytmWF0jcJqEr3jcZoiCl9Fb33TZgOVfClL7Voxe+/RwzISEprBRQgbf7j8z1xf8/RJCKfclUy3rQ==} engines: {node: 14.* || 16.* || >= 18} peerDependencies: ember-source: ^3.28.0 || >= 4.0.0 dependencies: ember-cli-babel: 7.26.11 - ember-source: 5.3.0(@babel/core@7.25.2)(@glimmer/component@1.1.2)(@glint/template@1.4.0)(webpack@5.94.0) + ember-source: 5.11.0(patch_hash=bo72463n2ws4z6rctmcukxpqeq)(@glimmer/component@1.1.2) git-repo-info: 2.1.1 transitivePeerDependencies: - supports-color dev: true - /ember-cli-app-version@6.0.1(ember-source@5.8.0): + /ember-cli-app-version@6.0.1(ember-source@5.3.0): resolution: {integrity: sha512-XA1FwkWA5QytmWF0jcJqEr3jcZoiCl9Fb33TZgOVfClL7Voxe+/RwzISEprBRQgbf7j8z1xf8/RJCKfclUy3rQ==} engines: {node: 14.* || 16.* || >= 18} peerDependencies: ember-source: ^3.28.0 || >= 4.0.0 dependencies: ember-cli-babel: 7.26.11 - ember-source: 5.8.0(patch_hash=qsivfx5huurlb5tuvochap65l4)(@babel/core@7.25.2) + ember-source: 5.3.0(@babel/core@7.25.2)(@glimmer/component@1.1.2)(@glint/template@1.4.0)(webpack@5.94.0) git-repo-info: 2.1.1 transitivePeerDependencies: - supports-color @@ -13132,7 +13132,7 @@ packages: engines: {node: 12.* || 14.* || >= 16} dependencies: '@ember/edition-utils': 1.2.0 - babel-plugin-ember-template-compilation: 2.2.5 + babel-plugin-ember-template-compilation: 2.3.0 babel-plugin-htmlbars-inline-precompile: 5.3.1 broccoli-debug: 0.6.5 broccoli-persistent-filter: 3.1.3 @@ -15508,7 +15508,7 @@ packages: - supports-color dev: true - /ember-modifier@4.2.0(@babel/core@7.25.2)(ember-source@5.3.0): + /ember-modifier@4.2.0(@babel/core@7.25.2)(ember-source@5.11.0): resolution: {integrity: sha512-BJ48eTEGxD8J7+lofwVmee7xDgNDgpr5dd6+MSu4gk+I6xb35099RMNorXY5hjjwMJEyi/IRR6Yn3M7iJMz8Zw==} peerDependencies: ember-source: ^3.24 || >=4.0 @@ -15520,13 +15520,13 @@ packages: decorator-transforms: 2.0.0(@babel/core@7.25.2) ember-cli-normalize-entity-name: 1.0.0 ember-cli-string-utils: 1.1.0 - ember-source: 5.3.0(@babel/core@7.25.2)(@glimmer/component@1.1.2)(@glint/template@1.4.0)(webpack@5.94.0) + ember-source: 5.11.0(patch_hash=bo72463n2ws4z6rctmcukxpqeq)(@glimmer/component@1.1.2) transitivePeerDependencies: - '@babel/core' - supports-color dev: true - /ember-modifier@4.2.0(@babel/core@7.25.2)(ember-source@5.8.0): + /ember-modifier@4.2.0(@babel/core@7.25.2)(ember-source@5.3.0): resolution: {integrity: sha512-BJ48eTEGxD8J7+lofwVmee7xDgNDgpr5dd6+MSu4gk+I6xb35099RMNorXY5hjjwMJEyi/IRR6Yn3M7iJMz8Zw==} peerDependencies: ember-source: ^3.24 || >=4.0 @@ -15538,7 +15538,7 @@ packages: decorator-transforms: 2.0.0(@babel/core@7.25.2) ember-cli-normalize-entity-name: 1.0.0 ember-cli-string-utils: 1.1.0 - ember-source: 5.8.0(patch_hash=qsivfx5huurlb5tuvochap65l4)(@babel/core@7.25.2) + ember-source: 5.3.0(@babel/core@7.25.2)(@glimmer/component@1.1.2)(@glint/template@1.4.0)(webpack@5.94.0) transitivePeerDependencies: - '@babel/core' - supports-color @@ -15718,7 +15718,7 @@ packages: - webpack dev: true - /ember-qunit@7.0.0(@ember/test-helpers@3.3.1)(ember-source@5.8.0)(qunit@2.22.0): + /ember-qunit@7.0.0(@ember/test-helpers@3.3.1)(ember-source@5.11.0)(qunit@2.22.0): resolution: {integrity: sha512-KhrndHYEXsHnXvmsGyJLJQ6VCudXaRs5dzPZBsdttZJIhsB6PmYAvq2Q+mh3GRDT/59T/sRDrB3FD3/lATS8aA==} engines: {node: 16.* || >= 18} peerDependencies: @@ -15726,14 +15726,14 @@ packages: ember-source: '>=4.0.0' qunit: ^2.13.0 dependencies: - '@ember/test-helpers': 3.3.1(@babel/core@7.25.2)(ember-source@5.8.0) + '@ember/test-helpers': 3.3.1(@babel/core@7.25.2)(ember-source@5.11.0) broccoli-funnel: 3.0.8 broccoli-merge-trees: 3.0.2 common-tags: 1.8.2 ember-auto-import: 2.7.4 ember-cli-babel: 7.26.11 ember-cli-test-loader: 3.1.0 - ember-source: 5.8.0(patch_hash=qsivfx5huurlb5tuvochap65l4)(@babel/core@7.25.2) + ember-source: 5.11.0(patch_hash=bo72463n2ws4z6rctmcukxpqeq)(@glimmer/component@1.1.2) qunit: 2.22.0 resolve-package-path: 4.0.3 silent-error: 1.1.1 @@ -15819,7 +15819,7 @@ packages: - supports-color dev: true - /ember-resolver@10.1.1(@ember/string@3.1.1)(ember-source@5.8.0): + /ember-resolver@10.1.1(@ember/string@3.1.1)(ember-source@5.11.0): resolution: {integrity: sha512-y1zzn6C4YGJui+tJzcCKlsf1oSOSVAkRrvmg8OwqVIKnALKKb9ihx2qLCslHg8x0wJvJgMtDMXgrczvQrZW0Lw==} engines: {node: 14.* || 16.* || >= 18} peerDependencies: @@ -15831,7 +15831,7 @@ packages: dependencies: '@ember/string': 3.1.1 ember-cli-babel: 7.26.11 - ember-source: 5.8.0(patch_hash=qsivfx5huurlb5tuvochap65l4)(@babel/core@7.25.2) + ember-source: 5.11.0(patch_hash=bo72463n2ws4z6rctmcukxpqeq)(@glimmer/component@1.1.2) transitivePeerDependencies: - supports-color dev: true @@ -16102,6 +16102,62 @@ packages: - webpack dev: true + /ember-source@5.11.0(patch_hash=bo72463n2ws4z6rctmcukxpqeq)(@glimmer/component@1.1.2): + resolution: {integrity: sha512-ufjjTyyaVKBpgTf0NrX7HQqzphcgpNQdkMss2SENkHkM9cidcdEPxulqcMNFxjHCsLBE7rGxmPFSci3x7LdIzA==} + engines: {node: '>= 18.*'} + peerDependencies: + '@glimmer/component': ^1.1.2 + dependencies: + '@babel/core': 7.25.2 + '@ember/edition-utils': 1.2.0 + '@glimmer/compiler': 0.92.0 + '@glimmer/component': 1.1.2(@babel/core@7.25.2) + '@glimmer/destroyable': 0.92.0 + '@glimmer/env': 0.1.7 + '@glimmer/global-context': 0.92.0 + '@glimmer/interfaces': 0.92.0 + '@glimmer/manager': 0.92.0 + '@glimmer/node': 0.92.0 + '@glimmer/opcode-compiler': 0.92.0 + '@glimmer/owner': 0.92.0 + '@glimmer/program': 0.92.0 + '@glimmer/reference': 0.92.0 + '@glimmer/runtime': 0.92.0 + '@glimmer/syntax': 0.92.0 + '@glimmer/util': 0.92.0 + '@glimmer/validator': 0.92.0 + '@glimmer/vm': 0.92.0 + '@glimmer/vm-babel-plugins': 0.92.0(@babel/core@7.25.2) + '@simple-dom/interface': 1.4.0 + backburner.js: 2.8.0 + broccoli-file-creator: 2.1.1 + broccoli-funnel: 3.0.8 + broccoli-merge-trees: 4.2.0 + chalk: 4.1.2 + ember-auto-import: 2.7.4 + ember-cli-babel: 8.2.0(@babel/core@7.25.2) + ember-cli-get-component-path-option: 1.0.0 + ember-cli-is-package-missing: 1.0.0 + ember-cli-normalize-entity-name: 1.0.0 + ember-cli-path-utils: 1.0.0 + ember-cli-string-utils: 1.1.0 + ember-cli-typescript-blueprint-polyfill: 0.1.0 + ember-cli-version-checker: 5.1.2 + ember-router-generator: 2.0.0 + inflection: 2.0.1 + route-recognizer: 0.3.4 + router_js: 8.0.6(route-recognizer@0.3.4) + semver: 7.6.3 + silent-error: 1.1.1 + simple-html-tokenizer: 0.5.11 + transitivePeerDependencies: + - '@glint/template' + - rsvp + - supports-color + - webpack + dev: true + patched: true + /ember-source@5.11.0(patch_hash=bo72463n2ws4z6rctmcukxpqeq)(webpack@5.94.0): resolution: {integrity: sha512-ufjjTyyaVKBpgTf0NrX7HQqzphcgpNQdkMss2SENkHkM9cidcdEPxulqcMNFxjHCsLBE7rGxmPFSci3x7LdIzA==} engines: {node: '>= 18.*'} @@ -16354,7 +16410,7 @@ packages: '@glimmer/vm-babel-plugins': 0.87.1(@babel/core@7.25.2) '@simple-dom/interface': 1.4.0 babel-plugin-debug-macros: 0.3.4(@babel/core@7.25.2) - babel-plugin-ember-template-compilation: 2.2.5 + babel-plugin-ember-template-compilation: 2.3.0 babel-plugin-filter-imports: 4.0.0 backburner.js: 2.8.0 broccoli-concat: 4.2.5 @@ -16414,7 +16470,7 @@ packages: '@glimmer/vm-babel-plugins': 0.87.1(@babel/core@7.25.2) '@simple-dom/interface': 1.4.0 babel-plugin-debug-macros: 0.3.4(@babel/core@7.25.2) - babel-plugin-ember-template-compilation: 2.2.5 + babel-plugin-ember-template-compilation: 2.3.0 babel-plugin-filter-imports: 4.0.0 backburner.js: 2.8.0 broccoli-concat: 4.2.5 @@ -25514,7 +25570,7 @@ packages: '@glimmer/vm-babel-plugins': 0.87.1(@babel/core@7.25.2) '@simple-dom/interface': 1.4.0 babel-plugin-debug-macros: 0.3.4(@babel/core@7.25.2) - babel-plugin-ember-template-compilation: 2.2.5 + babel-plugin-ember-template-compilation: 2.3.0 babel-plugin-filter-imports: 4.0.0 backburner.js: 2.8.0 broccoli-concat: 4.2.5 diff --git a/tests/app-template/babel.config.cjs b/tests/app-template/babel.config.cjs index 693c81bea..940d2cd74 100644 --- a/tests/app-template/babel.config.cjs +++ b/tests/app-template/babel.config.cjs @@ -1,11 +1,6 @@ const { - transformsFromV1Addons, - looseModeSupport, - templateMacros, - babelMacros, - adjustImports, - oldDebugMacros, - templateColocation, + babelCompatSupport, + templateCompatSupport, } = require("@embroider/compat/babel"); module.exports = { @@ -19,14 +14,9 @@ module.exports = { "ember-cli-htmlbars-inline-precompile", "htmlbars-inline-precompile", ], - transforms: [ - ...transformsFromV1Addons(), - looseModeSupport(), - ...templateMacros(), - ], + transforms: [...templateCompatSupport()], }, ], - ...babelMacros(), [ "module:decorator-transforms", { @@ -41,8 +31,10 @@ module.exports = { regenerator: false, }, ], - adjustImports(), - ...oldDebugMacros(), - templateColocation(), + ...babelCompatSupport(), ], + + generatorOpts: { + compact: false, + }, }; diff --git a/tests/app-template/package.json b/tests/app-template/package.json index 734f0f988..8c9e25fd0 100644 --- a/tests/app-template/package.json +++ b/tests/app-template/package.json @@ -45,7 +45,7 @@ "@glimmer/component": "^1.1.2", "@glimmer/tracking": "^1.1.2", "@rollup/plugin-babel": "^5.3.1", - "babel-plugin-ember-template-compilation": "^2.2.5", + "babel-plugin-ember-template-compilation": "^2.3.0", "concurrently": "^8.2.0", "ember-auto-import": "^2.6.3", "decorator-transforms": "^2.0.0", @@ -63,7 +63,7 @@ "ember-page-title": "^7.0.0", "ember-qunit": "^7.0.0", "ember-resolver": "^10.1.0", - "ember-source": "~5.8.0", + "ember-source": "5.11.0", "ember-template-lint": "^5.10.1", "eslint": "^8.42.0", "eslint-config-prettier": "^8.8.0", diff --git a/tests/scenarios/package.json b/tests/scenarios/package.json index 20d8fe953..c0d3f4b05 100644 --- a/tests/scenarios/package.json +++ b/tests/scenarios/package.json @@ -57,7 +57,7 @@ "@types/lodash": "^4.14.170", "@types/node-fetch": "^2.6.11", "@types/semver": "^7.3.6", - "babel-plugin-ember-template-compilation": "^2.1.1", + "babel-plugin-ember-template-compilation": "^2.3.0", "bootstrap": "^4.3.1", "broccoli-funnel": "^3.0.5", "broccoli-merge-trees": "^3.0.2", From 615ab15d9882d63f957f8060620b79d1cff0d6a7 Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Mon, 9 Sep 2024 15:19:22 -0400 Subject: [PATCH 4/9] switch all test scenarios to use standalone babel --- tests/addon-template/babel.config.cjs | 55 +++++++++++++------ .../ts-app-template-classic/babel.config.cjs | 49 ++++++++++++----- tests/ts-app-template/babel.config.cjs | 49 ++++++++++++----- 3 files changed, 108 insertions(+), 45 deletions(-) diff --git a/tests/addon-template/babel.config.cjs b/tests/addon-template/babel.config.cjs index baf775d4b..940d2cd74 100644 --- a/tests/addon-template/babel.config.cjs +++ b/tests/addon-template/babel.config.cjs @@ -1,19 +1,40 @@ -// eslint-disable-next-line n/no-missing-require +const { + babelCompatSupport, + templateCompatSupport, +} = require("@embroider/compat/babel"); -let config; +module.exports = { + plugins: [ + [ + "babel-plugin-ember-template-compilation", + { + compilerPath: "ember-source/dist/ember-template-compiler.js", + enableLegacyModules: [ + "ember-cli-htmlbars", + "ember-cli-htmlbars-inline-precompile", + "htmlbars-inline-precompile", + ], + transforms: [...templateCompatSupport()], + }, + ], + [ + "module:decorator-transforms", + { + runtime: { import: require.resolve("decorator-transforms/runtime") }, + }, + ], + [ + "@babel/plugin-transform-runtime", + { + absoluteRuntime: __dirname, + useESModules: true, + regenerator: false, + }, + ], + ...babelCompatSupport(), + ], -// TODO - remove this once we have the better solution for injecting stage1 babel config into a real config file -// this is needed because there are things (like ember-composible-helpers) that are now finding our babel config during -// their stage1 build and historically they will never (99% of the time) have found any babel config. -// we might need to keep something like this so that prebuild will never apply babel configs during stage1 i.e. a util -// function that wraps your whole babel config -if ( - process.env.EMBROIDER_PREBUILD || - process.env.EMBROIDER_TEST_SETUP_FORCE === "classic" -) { - config = {}; -} else { - config = require("./node_modules/.embroider/_babel_config_"); -} - -module.exports = config; + generatorOpts: { + compact: false, + }, +}; diff --git a/tests/ts-app-template-classic/babel.config.cjs b/tests/ts-app-template-classic/babel.config.cjs index 7637754cc..29a153bfc 100644 --- a/tests/ts-app-template-classic/babel.config.cjs +++ b/tests/ts-app-template-classic/babel.config.cjs @@ -1,16 +1,37 @@ -// eslint-disable-next-line n/no-missing-require +const { babelCompatSupport, templateCompatSupport } = require('@embroider/compat/babel'); -let config; +module.exports = { + plugins: [ + [ + 'babel-plugin-ember-template-compilation', + { + compilerPath: 'ember-source/dist/ember-template-compiler.js', + enableLegacyModules: [ + 'ember-cli-htmlbars', + 'ember-cli-htmlbars-inline-precompile', + 'htmlbars-inline-precompile', + ], + transforms: [...templateCompatSupport()], + }, + ], + [ + 'module:decorator-transforms', + { + runtime: { import: require.resolve('decorator-transforms/runtime') }, + }, + ], + [ + '@babel/plugin-transform-runtime', + { + absoluteRuntime: __dirname, + useESModules: true, + regenerator: false, + }, + ], + ...babelCompatSupport(), + ], -// TODO - remove this once we have the better solution for injecting stage1 babel config into a real config file -// this is needed because there are things (like ember-composible-helpers) that are now finding our babel config during -// their stage1 build and historically they will never (99% of the time) have found any babel config. -// we might need to keep something like this so that prebuild will never apply babel configs during stage1 i.e. a util -// function that wraps your whole babel config -if (process.env.EMBROIDER_PREBUILD || process.env.EMBROIDER_TEST_SETUP_FORCE === 'classic') { - config = {}; -} else { - config = require('./node_modules/.embroider/_babel_config_'); -} - -module.exports = config; + generatorOpts: { + compact: false, + }, +}; diff --git a/tests/ts-app-template/babel.config.cjs b/tests/ts-app-template/babel.config.cjs index 7637754cc..29a153bfc 100644 --- a/tests/ts-app-template/babel.config.cjs +++ b/tests/ts-app-template/babel.config.cjs @@ -1,16 +1,37 @@ -// eslint-disable-next-line n/no-missing-require +const { babelCompatSupport, templateCompatSupport } = require('@embroider/compat/babel'); -let config; +module.exports = { + plugins: [ + [ + 'babel-plugin-ember-template-compilation', + { + compilerPath: 'ember-source/dist/ember-template-compiler.js', + enableLegacyModules: [ + 'ember-cli-htmlbars', + 'ember-cli-htmlbars-inline-precompile', + 'htmlbars-inline-precompile', + ], + transforms: [...templateCompatSupport()], + }, + ], + [ + 'module:decorator-transforms', + { + runtime: { import: require.resolve('decorator-transforms/runtime') }, + }, + ], + [ + '@babel/plugin-transform-runtime', + { + absoluteRuntime: __dirname, + useESModules: true, + regenerator: false, + }, + ], + ...babelCompatSupport(), + ], -// TODO - remove this once we have the better solution for injecting stage1 babel config into a real config file -// this is needed because there are things (like ember-composible-helpers) that are now finding our babel config during -// their stage1 build and historically they will never (99% of the time) have found any babel config. -// we might need to keep something like this so that prebuild will never apply babel configs during stage1 i.e. a util -// function that wraps your whole babel config -if (process.env.EMBROIDER_PREBUILD || process.env.EMBROIDER_TEST_SETUP_FORCE === 'classic') { - config = {}; -} else { - config = require('./node_modules/.embroider/_babel_config_'); -} - -module.exports = config; + generatorOpts: { + compact: false, + }, +}; From e1ee21ac1fd223108745d893baa9fabdec115280 Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Mon, 9 Sep 2024 19:42:37 -0400 Subject: [PATCH 5/9] remove babel app meta and fix audit tests --- packages/compat/src/audit.ts | 20 ++--------- packages/compat/tests/audit.test.ts | 41 ++++++++++++++++++----- packages/shared-internals/src/metadata.ts | 6 ---- packages/webpack/src/ember-webpack.ts | 27 +++++---------- test-packages/support/transpiler.ts | 15 +-------- tests/scenarios/compat-resolver-test.ts | 6 ---- tests/scenarios/core-resolver-test.ts | 6 ---- 7 files changed, 45 insertions(+), 76 deletions(-) diff --git a/packages/compat/src/audit.ts b/packages/compat/src/audit.ts index b3545f7d6..f6fabf5f4 100644 --- a/packages/compat/src/audit.ts +++ b/packages/compat/src/audit.ts @@ -1,4 +1,4 @@ -import { existsSync, readFileSync, readJSONSync } from 'fs-extra'; +import { readFileSync, readJSONSync } from 'fs-extra'; import { join, resolve as resolvePath, dirname } from 'path'; import type { AppMeta, ResolverOptions } from '@embroider/core'; import { explicitRelative, hbsToJS, locateEmbroiderWorkingDir, Resolver, RewrittenPackageCache } from '@embroider/core'; @@ -122,15 +122,6 @@ export class Audit { } let audit = new this(options.app, options); - if (options['reuse-build']) { - if (!audit.meta.babel.isParallelSafe) { - throw new BuildError( - `You can't use the ${chalk.red( - '--reuse-build' - )} option because some of your babel or HBS plugins are non-serializable` - ); - } - } return audit.run(); } @@ -153,13 +144,8 @@ export class Audit { @Memoize() private get babelConfig() { - // Depending on how the app builds, the babel config is not at the same location - let embroiderLocation = join(locateEmbroiderWorkingDir(this.originAppRoot), '_babel_config_.js'); - let config = existsSync(embroiderLocation) - ? // eslint-disable-next-line @typescript-eslint/no-require-imports - require(embroiderLocation) - : // eslint-disable-next-line @typescript-eslint/no-require-imports - require(join(this.movedAppRoot, this.meta.babel.filename)); + // eslint-disable-next-line @typescript-eslint/no-require-imports + let config = require(join(this.originAppRoot, 'babel.config.cjs')); config = Object.assign({}, config); config.plugins = config.plugins.filter((p: any) => !isMacrosPlugin(p)); diff --git a/packages/compat/tests/audit.test.ts b/packages/compat/tests/audit.test.ts index 8aa99a592..7ab9ef8f2 100644 --- a/packages/compat/tests/audit.test.ts +++ b/packages/compat/tests/audit.test.ts @@ -10,6 +10,7 @@ import type { TransformOptions } from '@babel/core'; import type { Options as InlinePrecompileOptions } from 'babel-plugin-ember-template-compilation'; import type { Transform } from 'babel-plugin-ember-template-compilation'; import type { Options as ResolverTransformOptions } from '../src/resolver-transform'; +import { resolve } from 'path'; describe('audit', function () { throwOnWarnings(); @@ -18,12 +19,23 @@ describe('audit', function () { async function audit() { await app.write(); - let audit = new Audit(app.baseDir); - return await audit.run(); + let origCwd = process.cwd(); + try { + process.chdir(app.baseDir); + let audit = new Audit(app.baseDir); + return await audit.run(); + } finally { + process.chdir(origCwd); + } } beforeEach(async function () { app = new Project('audit-this-app'); + app.linkDevDependency('babel-plugin-ember-template-compilation', { + baseDir: __dirname, + }); + app.linkDevDependency('@embroider/compat', { target: resolve(__dirname, '..') }); + app.linkDevDependency('@embroider/core', { baseDir: __dirname }); const resolvableExtensions = ['.js', '.hbs']; @@ -77,6 +89,25 @@ describe('audit', function () { 'index.html': ``, 'app.js': `import Hello from './hello.hbs';`, 'hello.hbs': ``, + 'babel.config.cjs': ` + const { + babelCompatSupport, + templateCompatSupport, + } = require("@embroider/compat/babel"); + module.exports = { + plugins: [ + ['babel-plugin-ember-template-compilation', { + transforms: [ + ...templateCompatSupport(), + ], + enableLegacyModules: [ + 'ember-cli-htmlbars' + ] + }], + ...babelCompatSupport() + ] + } + `, node_modules: { '.embroider': { 'resolver.json': JSON.stringify(resolverConfig), @@ -87,12 +118,6 @@ describe('audit', function () { type: 'app', version: 2, assets: ['index.html'], - babel: { - filename: 'babel_config.js', - isParallelSafe: true, - majorVersion: 7, - fileFilter: 'babel_filter.js', - }, 'root-url': '/', 'auto-upgraded': true, }; diff --git a/packages/shared-internals/src/metadata.ts b/packages/shared-internals/src/metadata.ts index c3bd5def5..8cd4ccfad 100644 --- a/packages/shared-internals/src/metadata.ts +++ b/packages/shared-internals/src/metadata.ts @@ -9,12 +9,6 @@ export interface AppMeta { main?: string; 'auto-upgraded'?: true; assets: Filename[]; - babel: { - filename: string; - isParallelSafe: boolean; - majorVersion: 7; - fileFilter: string; - }; 'root-url': string; version: 2; } diff --git a/packages/webpack/src/ember-webpack.ts b/packages/webpack/src/ember-webpack.ts index 8d3b15c46..ec8eaf75e 100644 --- a/packages/webpack/src/ember-webpack.ts +++ b/packages/webpack/src/ember-webpack.ts @@ -42,7 +42,6 @@ import type { MinifyOptions } from 'terser'; interface AppInfo { entrypoints: HTMLEntrypoint[]; otherAssets: string[]; - babel: AppMeta['babel']; rootURL: AppMeta['root-url']; publicAssetURL: string; resolverConfig: ResolverOptions; @@ -52,7 +51,6 @@ interface AppInfo { // AppInfos are equal if they result in the same webpack config. function equalAppInfo(left: AppInfo, right: AppInfo): boolean { return ( - isEqual(left.babel, right.babel) && left.entrypoints.length === right.entrypoints.length && left.entrypoints.every((e, index) => isEqual(e.modules, right.entrypoints[index].modules)) ); @@ -161,7 +159,6 @@ const Webpack: PackagerConstructor = class Webpack implements Packager private examineApp(): AppInfo { let meta = getAppMeta(this.pathToVanillaApp); let rootURL = meta['ember-addon']['root-url']; - let babel = meta['ember-addon']['babel']; let entrypoints = []; let otherAssets = []; let publicAssetURL = this.publicAssetURL || rootURL; @@ -178,11 +175,11 @@ const Webpack: PackagerConstructor = class Webpack implements Packager join(locateEmbroiderWorkingDir(this.appRoot), 'resolver.json') ); - return { entrypoints, otherAssets, babel, rootURL, resolverConfig, publicAssetURL, packageName: meta.name }; + return { entrypoints, otherAssets, rootURL, resolverConfig, publicAssetURL, packageName: meta.name }; } private configureWebpack(appInfo: AppInfo, variant: Variant, variantIndex: number): Configuration { - const { entrypoints, babel, publicAssetURL, packageName, resolverConfig } = appInfo; + const { entrypoints, publicAssetURL, packageName, resolverConfig } = appInfo; let entry: { [name: string]: string } = {}; for (let entrypoint of entrypoints) { @@ -194,9 +191,8 @@ const Webpack: PackagerConstructor = class Webpack implements Packager let { plugins: stylePlugins, loaders: styleLoaders } = this.setupStyleConfig(variant); let babelLoaderOptions = makeBabelLoaderOptions( - babel.majorVersion, variant, - join(this.pathToVanillaApp, babel.filename), + join(this.appRoot, 'babel.config.cjs'), this.extraBabelLoaderOptions ); @@ -225,7 +221,7 @@ const Webpack: PackagerConstructor = class Webpack implements Packager { test: /\.hbs$/, use: nonNullArray([ - maybeThreadLoader(babel.isParallelSafe, this.extraThreadLoaderOptions), + maybeThreadLoader(this.extraThreadLoaderOptions), babelLoaderOptions, { loader: require.resolve('@embroider/hbs-loader'), @@ -243,15 +239,9 @@ const Webpack: PackagerConstructor = class Webpack implements Packager }, { // eslint-disable-next-line @typescript-eslint/no-require-imports - test: require(join(this.pathToVanillaApp, babel.fileFilter)), use: nonNullArray([ - maybeThreadLoader(babel.isParallelSafe, this.extraThreadLoaderOptions), - makeBabelLoaderOptions( - babel.majorVersion, - variant, - join(this.pathToVanillaApp, babel.filename), - this.extraBabelLoaderOptions - ), + maybeThreadLoader(this.extraThreadLoaderOptions), + makeBabelLoaderOptions(variant, join(this.appRoot, 'babel.config.cjs'), this.extraBabelLoaderOptions), ]), }, { @@ -680,8 +670,8 @@ function warmUp(extraOptions: object | false | undefined) { ]); } -function maybeThreadLoader(isParallelSafe: boolean, extraOptions: object | false | undefined) { - if (!canUseThreadLoader(extraOptions) || !isParallelSafe) { +function maybeThreadLoader(extraOptions: object | false | undefined) { + if (!canUseThreadLoader(extraOptions)) { return null; } @@ -708,7 +698,6 @@ function nonNullArray(array: T[]): NonNullable[] { } function makeBabelLoaderOptions( - _majorVersion: 7, variant: Variant, appBabelConfigPath: string, extraOptions: BabelLoaderOptions | undefined diff --git a/test-packages/support/transpiler.ts b/test-packages/support/transpiler.ts index f1cbef381..4ab2c4bf3 100644 --- a/test-packages/support/transpiler.ts +++ b/test-packages/support/transpiler.ts @@ -3,7 +3,6 @@ import { join } from 'path'; import type { TransformOptions } from '@babel/core'; import { transform } from '@babel/core'; import type { BoundExpectFile } from './file-assertions'; -import type { AppMeta } from '../../packages/core/src/index'; import { hbsToJS, locateEmbroiderWorkingDir, RewrittenPackageCache } from '../../packages/core/src/index'; import { Memoize } from 'typescript-memoize'; import { getRewrittenLocation } from './rewritten-path'; @@ -47,20 +46,8 @@ export class Transpiler { return readJSONSync(join(this.appOutputPath, 'package.json')); } - private get emberMeta(): AppMeta { - return this.pkgJSON['ember-addon'] as AppMeta; - } - @Memoize() private get babelConfig() { - if (this.emberMeta['babel'].majorVersion !== 7) { - throw new Error(`@embroider/test-support only suports babel 7`); - } - - // Depending on how the app builds, the babel config is not at the same location - let embroiderLocation = join(locateEmbroiderWorkingDir(this.appDir), '_babel_config_.js'); - return existsSync(embroiderLocation) - ? (require(embroiderLocation) as TransformOptions) - : (require(join(this.appDir, this.emberMeta['babel'].filename)) as TransformOptions); + return require(join(this.appOutputPath, './babel.config.cjs')) as TransformOptions; } } diff --git a/tests/scenarios/compat-resolver-test.ts b/tests/scenarios/compat-resolver-test.ts index 32b0c55fb..d506a2c7a 100644 --- a/tests/scenarios/compat-resolver-test.ts +++ b/tests/scenarios/compat-resolver-test.ts @@ -21,12 +21,6 @@ Scenarios.fromProject(() => new Project()) 'auto-upgraded': true, assets: ['index.html'], 'root-url': '/', - babel: { - majorVersion: 7, - filename: '_babel_config.js', - isParallelSafe: true, - fileFilter: '_babel_filter.js', - }, }; app.pkg = { name: 'my-app', diff --git a/tests/scenarios/core-resolver-test.ts b/tests/scenarios/core-resolver-test.ts index 9d500c583..5cff55c65 100644 --- a/tests/scenarios/core-resolver-test.ts +++ b/tests/scenarios/core-resolver-test.ts @@ -19,12 +19,6 @@ Scenarios.fromProject(() => new Project()) 'auto-upgraded': true, assets: ['index.html'], 'root-url': '/', - babel: { - majorVersion: 7, - filename: '_babel_config.js', - isParallelSafe: true, - fileFilter: '_babel_filter.js', - }, }; app.pkg = { name: 'my-app', From 823aca97bb549d185325b570899085ad6ad63bd9 Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Mon, 9 Sep 2024 19:45:38 -0400 Subject: [PATCH 6/9] lint fix --- packages/webpack/src/ember-webpack.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/webpack/src/ember-webpack.ts b/packages/webpack/src/ember-webpack.ts index ec8eaf75e..0e6b4c759 100644 --- a/packages/webpack/src/ember-webpack.ts +++ b/packages/webpack/src/ember-webpack.ts @@ -238,7 +238,6 @@ const Webpack: PackagerConstructor = class Webpack implements Packager ]), }, { - // eslint-disable-next-line @typescript-eslint/no-require-imports use: nonNullArray([ maybeThreadLoader(this.extraThreadLoaderOptions), makeBabelLoaderOptions(variant, join(this.appRoot, 'babel.config.cjs'), this.extraBabelLoaderOptions), From 69414d52fa602a4ec6f10aed9d41015ffb33e163 Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Tue, 10 Sep 2024 18:46:04 +0100 Subject: [PATCH 7/9] updating compat resolver tests --- test-packages/support/transpiler.ts | 8 +++- tests/scenarios/compat-resolver-test.ts | 60 ++++++++++++++----------- 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/test-packages/support/transpiler.ts b/test-packages/support/transpiler.ts index 4ab2c4bf3..a1b8963e0 100644 --- a/test-packages/support/transpiler.ts +++ b/test-packages/support/transpiler.ts @@ -48,6 +48,12 @@ export class Transpiler { @Memoize() private get babelConfig() { - return require(join(this.appOutputPath, './babel.config.cjs')) as TransformOptions; + let origDir = process.cwd(); + process.chdir(this.appOutputPath); + try { + return require(join(this.appOutputPath, './babel.config.cjs')) as TransformOptions; + } finally { + process.chdir(origDir); + } } } diff --git a/tests/scenarios/compat-resolver-test.ts b/tests/scenarios/compat-resolver-test.ts index d506a2c7a..197db5a1c 100644 --- a/tests/scenarios/compat-resolver-test.ts +++ b/tests/scenarios/compat-resolver-test.ts @@ -4,7 +4,6 @@ import type { ExpectFile } from '@embroider/test-support/file-assertions/qunit'; import { expectFilesAt } from '@embroider/test-support/file-assertions/qunit'; import { outputFileSync } from 'fs-extra'; import { resolve, sep } from 'path'; -import type { Options as EtcOptions } from 'babel-plugin-ember-template-compilation'; import QUnit from 'qunit'; import { Project, Scenarios } from 'scenario-tester'; @@ -30,6 +29,11 @@ Scenarios.fromProject(() => new Project()) app.mergeFiles({ 'index.html': '', }); + app.linkDevDependency('babel-plugin-ember-template-compilation', { + baseDir: __dirname, + }); + app.linkDevDependency('@embroider/compat', { baseDir: __dirname }); + app.linkDevDependency('@embroider/core', { baseDir: __dirname }); }) .forEachScenario(scenario => { Qmodule(scenario.name, function (hooks) { @@ -60,17 +64,8 @@ Scenarios.fromProject(() => new Project()) configure = async function ( opts?: Partial, extraOpts?: ConfigureOpts, - emberVersion = '4.6.0' //based on app-template package.json + emberVersion = '4.6.0' ) { - let etcOptions: EtcOptions = { - compilerPath: require.resolve('ember-source-latest/dist/ember-template-compiler'), - targetFormat: 'hbs', - transforms: [ - ...(extraOpts?.astPlugins ?? []), - [require.resolve('@embroider/compat/src/resolver-transform'), { appRoot: app.dir, emberVersion }], - ], - }; - let resolverOptions: CompatResolverOptions = { amdCompatibility: 'cjs', renameModules: {}, @@ -104,19 +99,30 @@ Scenarios.fromProject(() => new Project()) ], autoRun: true, staticAppPaths: [], - emberVersion: '4.0.0', + emberVersion, }; givenFiles({ - 'node_modules/.embroider/_babel_config_.js': ` - module.exports = { - plugins: ${JSON.stringify([ - [require.resolve('babel-plugin-ember-template-compilation'), etcOptions], - [require.resolve('@embroider/compat/src/babel-plugin-adjust-imports'), { appRoot: app.dir }], - ])} - }`, - 'node_modules/.embroider/_babel_filter.js': ` - module.exports = function(filename) { return true } + 'babel.config.cjs': ` + const { + babelCompatSupport, + templateCompatSupport, + } = require("@embroider/compat/babel"); + module.exports = { + plugins: [ + ['babel-plugin-ember-template-compilation', { + targetFormat: 'hbs', + transforms: [ + ...templateCompatSupport(), + ...(${JSON.stringify(extraOpts?.astPlugins ?? [])}) + ], + enableLegacyModules: [ + 'ember-cli-htmlbars' + ] + }], + ...babelCompatSupport() + ] + } `, 'node_modules/.embroider/resolver.json': JSON.stringify(resolverOptions), }); @@ -1281,11 +1287,11 @@ Scenarios.fromProject(() => new Project()) ); expectTranspiled('templates/application.hbs').equalsCode(` import { precompileTemplate } from "@ember/template-compilation"; - import thing_ from "@embroider/virtual/components/my-addon@thing"; - export default precompileTemplate("", { + import myAddonThing_ from "@embroider/virtual/components/my-addon$thing"; + export default precompileTemplate("", { moduleName: "my-app/templates/application.hbs", scope: () => ({ - thing_ + myAddonThing_ }) }); `); @@ -1305,11 +1311,11 @@ Scenarios.fromProject(() => new Project()) ); expectTranspiled('templates/application.hbs').equalsCode(` import { precompileTemplate } from "@ember/template-compilation"; - import thing_ from "@embroider/virtual/helpers/my-addon@thing"; - export default precompileTemplate("{{(thing_)}}", { + import myAddonThing_ from "@embroider/virtual/helpers/my-addon$thing"; + export default precompileTemplate("{{(myAddonThing_)}}", { moduleName: "my-app/templates/application.hbs", scope: () => ({ - thing_ + myAddonThing_ }) }); `); From 94660423abbb540735dd3811d46a8f3dc9b5766d Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Tue, 10 Sep 2024 19:01:27 +0100 Subject: [PATCH 8/9] update core resolver tests --- packages/compat/src/audit.ts | 18 ++++++++++----- tests/scenarios/core-resolver-test.ts | 32 +++++++++++++++++++++------ 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/packages/compat/src/audit.ts b/packages/compat/src/audit.ts index f6fabf5f4..a26d4c8cc 100644 --- a/packages/compat/src/audit.ts +++ b/packages/compat/src/audit.ts @@ -144,14 +144,20 @@ export class Audit { @Memoize() private get babelConfig() { - // eslint-disable-next-line @typescript-eslint/no-require-imports - let config = require(join(this.originAppRoot, 'babel.config.cjs')); + let origCwd = process.cwd(); + process.chdir(this.originAppRoot); + try { + // eslint-disable-next-line @typescript-eslint/no-require-imports + let config = require(join(this.originAppRoot, 'babel.config.cjs')); - config = Object.assign({}, config); - config.plugins = config.plugins.filter((p: any) => !isMacrosPlugin(p)); + config = Object.assign({}, config); + config.plugins = config.plugins.filter((p: any) => !isMacrosPlugin(p)); - config.ast = true; - return config; + config.ast = true; + return config; + } finally { + process.chdir(origCwd); + } } private get resolverParams(): ResolverOptions { diff --git a/tests/scenarios/core-resolver-test.ts b/tests/scenarios/core-resolver-test.ts index 5cff55c65..e32c12b04 100644 --- a/tests/scenarios/core-resolver-test.ts +++ b/tests/scenarios/core-resolver-test.ts @@ -37,6 +37,11 @@ Scenarios.fromProject(() => new Project()) 'index.js': '', }, }); + app.linkDevDependency('babel-plugin-ember-template-compilation', { + baseDir: __dirname, + }); + app.linkDevDependency('@embroider/compat', { baseDir: __dirname }); + app.linkDevDependency('@embroider/core', { baseDir: __dirname }); let v1Addon = baseAddon(); v1Addon.name = 'a-v1-addon'; @@ -136,14 +141,27 @@ Scenarios.fromProject(() => new Project()) }; givenFiles({ - 'node_modules/.embroider/_babel_config_.js': ` - module.exports = { - plugins: [] - } - `, - 'node_modules/.embroider/_babel_filter.js': ` - module.exports = function(filename) { return true } + 'babel.config.cjs': ` + const { + babelCompatSupport, + templateCompatSupport, + } = require("@embroider/compat/babel"); + module.exports = { + plugins: [ + ['babel-plugin-ember-template-compilation', { + targetFormat: 'hbs', + transforms: [ + ...templateCompatSupport(), + ], + enableLegacyModules: [ + 'ember-cli-htmlbars' + ] + }], + ...babelCompatSupport() + ] + } `, + 'node_modules/.embroider/resolver.json': JSON.stringify(resolverOptions), 'node_modules/my-addon/package.json': addonPackageJSON('my-addon', opts?.addonMeta), }); From 3386e96466a0b6272aff0c3eb508fd38e88353b7 Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Tue, 10 Sep 2024 19:33:31 +0100 Subject: [PATCH 9/9] template macros must go before looseMose --- packages/compat/src/babel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compat/src/babel.ts b/packages/compat/src/babel.ts index 7ab426552..407bbdc9d 100644 --- a/packages/compat/src/babel.ts +++ b/packages/compat/src/babel.ts @@ -154,5 +154,5 @@ export function babelCompatSupport(): PluginItem[] { } export function templateCompatSupport(): Transform[] { - return [looseModeSupport(), ...templateMacros(), ...transformsFromV1Addons()]; + return [...transformsFromV1Addons(), ...templateMacros(), looseModeSupport()]; }