From 76514079e7f0bfa13b92f562b1f0dce51d4ea347 Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Fri, 22 Dec 2023 14:52:41 -0500 Subject: [PATCH 1/3] Don't rely on htmlbars internals I'm working on a cleanup in ember-cli-htmlbars that is blocked on embroider touching some internals. --- packages/compat/src/compat-app.ts | 39 +++------------- .../src/prepare-htmlbars-ast-plugins.ts | 35 +++------------ packages/compat/src/v1-addon.ts | 44 +++++++++---------- types/ember-cli-htmlbars/index.d.ts | 22 ---------- types/ember-cli-htmlbars/package.json | 8 ---- 5 files changed, 32 insertions(+), 116 deletions(-) delete mode 100644 types/ember-cli-htmlbars/index.d.ts delete mode 100644 types/ember-cli-htmlbars/package.json diff --git a/packages/compat/src/compat-app.ts b/packages/compat/src/compat-app.ts index 65432529a..9cfd8c425 100644 --- a/packages/compat/src/compat-app.ts +++ b/packages/compat/src/compat-app.ts @@ -12,13 +12,7 @@ import { WatchedDir } from 'broccoli-source'; import resolve from 'resolve'; import { V1Config, WriteV1Config } from './v1-config'; import { WriteV1AppBoot, ReadV1AppBoot } from './v1-appboot'; -import type { - AddonMeta, - EmberAppInstance, - OutputFileToInputFileMap, - PackageInfo, - AddonInstance, -} from '@embroider/core'; +import type { AddonMeta, EmberAppInstance, OutputFileToInputFileMap, PackageInfo } from '@embroider/core'; import { writeJSONSync, ensureDirSync, copySync, readdirSync, pathExistsSync, existsSync } from 'fs-extra'; import AddToTree from './add-to-tree'; import DummyPackage from './dummy-package'; @@ -29,17 +23,12 @@ import Concat from 'broccoli-concat'; import mapKeys from 'lodash/mapKeys'; import SynthesizeTemplateOnlyComponents from './synthesize-template-only-components'; import { isEmberAutoImportDynamic, isInlinePrecompilePlugin } from './detect-babel-plugins'; -import prepHtmlbarsAstPluginsForUnwrap from './prepare-htmlbars-ast-plugins'; +import loadAstPlugins from './prepare-htmlbars-ast-plugins'; import { readFileSync } from 'fs'; -import type { Options as HTMLBarsOptions } from 'ember-cli-htmlbars'; import semver from 'semver'; import type { Transform } from 'babel-plugin-ember-template-compilation'; import { CompatAppBuilder } from './compat-app-builder'; -type EmberCliHTMLBarsAddon = AddonInstance & { - htmlbarsOptions(): HTMLBarsOptions; -}; - interface Group { outputFiles: OutputFileToInputFileMap; implicitKey: '_implicitStyles' | '_implicitScripts'; @@ -585,25 +574,11 @@ export default class CompatApp { } get htmlbarsPlugins(): Transform[] { - let addon = this.legacyEmberAppInstance.project.addons.find( - (a: AddonInstance) => a.name === 'ember-cli-htmlbars' - ) as unknown as EmberCliHTMLBarsAddon; - let options = addon.htmlbarsOptions(); - if (options?.plugins?.ast) { - // even if the app was using @embroider/macros, we drop it from the config - // here in favor of our globally-configured one. - options.plugins.ast = options.plugins.ast.filter((p: any) => !isEmbroiderMacrosPlugin(p)); - prepHtmlbarsAstPluginsForUnwrap(this.legacyEmberAppInstance.registry); - - // classically, this list was backwards for silly historic reasons. But - // we're the compatibility system, so we're putting it back into - // reasonable order. - options.plugins.ast.reverse(); - - return options.plugins.ast; - } else { - return []; - } + let plugins = loadAstPlugins(this.legacyEmberAppInstance.registry); + // even if the app was using @embroider/macros, we drop it from the config + // here in favor of our globally-configured one. + plugins = plugins.filter((p: any) => !isEmbroiderMacrosPlugin(p)); + return plugins; } // our own appTree. Not to be confused with the one that combines the app js diff --git a/packages/compat/src/prepare-htmlbars-ast-plugins.ts b/packages/compat/src/prepare-htmlbars-ast-plugins.ts index 092bf5c59..004641df5 100644 --- a/packages/compat/src/prepare-htmlbars-ast-plugins.ts +++ b/packages/compat/src/prepare-htmlbars-ast-plugins.ts @@ -1,32 +1,7 @@ -import { join } from 'path'; +import type { Transform } from 'babel-plugin-ember-template-compilation'; -export default function prepHtmlbarsAstPluginsForUnwrap(registry: any): void { - for (let wrapper of registry.load('htmlbars-ast-plugin')) { - const { plugin, parallelBabel, baseDir, cacheKey } = wrapper; - if (plugin) { - // if the parallelBabel options were set on the wrapper, but not on the plugin, add it - if (parallelBabel && !plugin.parallelBabel) { - plugin.parallelBabel = { - requireFile: join(__dirname, 'htmlbars-unwrapper.js'), - buildUsing: 'unwrapPlugin', - params: parallelBabel, - }; - } - - // NOTE: `_parallelBabel` (not `parallelBabel`) is expected by broccoli-babel-transpiler - if (plugin.parallelBabel && !plugin._parallelBabel) { - plugin._parallelBabel = plugin.parallelBabel; - } - - // if the baseDir is set on the wrapper, but not on the plugin, add it - if (baseDir && !plugin.baseDir) { - plugin.baseDir = baseDir; - } - - // if the cacheKey is set on the wrapper, but not on the plugin, add it - if (cacheKey && !plugin.cacheKey) { - plugin.cacheKey = cacheKey; - } - } - } +export default function loadAstPlugins(registry: any): Transform[] { + let plugins = registry.load('htmlbars-ast-plugin').map((wrapper: any) => wrapper.plugin); + plugins.reverse(); + return plugins; } diff --git a/packages/compat/src/v1-addon.ts b/packages/compat/src/v1-addon.ts index eda31fa79..3425db257 100644 --- a/packages/compat/src/v1-addon.ts +++ b/packages/compat/src/v1-addon.ts @@ -13,11 +13,10 @@ import semver from 'semver'; import rewriteAddonTree from './rewrite-addon-tree'; import { mergeWithAppend } from './merges'; import type { AddonMeta, PackageCache, AddonInstance, AddonTreePath } from '@embroider/core'; -import { debug } from '@embroider/core'; +import { debug, findTopmostAddon } from '@embroider/core'; import type Options from './options'; import walkSync from 'walk-sync'; import ObserveTree from './observe-tree'; -import type { Options as HTMLBarsOptions } from 'ember-cli-htmlbars'; import { isEmbroiderMacrosPlugin } from '@embroider/macros/src/node'; import type { TransformOptions, PluginItem } from '@babel/core'; import modulesCompat from './modules-compat'; @@ -31,7 +30,7 @@ import { } from './detect-babel-plugins'; import HbsToJSBroccoliPlugin from './hbs-to-js-broccoli-plugin'; import { fromPairs } from 'lodash'; -import prepHtmlbarsAstPluginsForUnwrap from './prepare-htmlbars-ast-plugins'; +import loadAstPlugins from './prepare-htmlbars-ast-plugins'; import getRealAddon from './get-real-addon'; import type { Options as EtcOptions } from 'babel-plugin-ember-template-compilation'; import type CompatApp from './compat-app'; @@ -116,27 +115,24 @@ export default class V1Addon { // this is only defined when there are custom AST transforms that need it @Memoize() private get templateCompilerBabelPlugin(): PluginItem | undefined { - let htmlbars = this.addonInstance.addons.find(a => a.name === 'ember-cli-htmlbars'); - if (htmlbars) { - let options = (htmlbars as any).htmlbarsOptions() as HTMLBarsOptions; - if (options?.plugins?.ast) { - // our macros don't run here in stage1 - options.plugins.ast = options.plugins.ast.filter((p: any) => !isEmbroiderMacrosPlugin(p)); - prepHtmlbarsAstPluginsForUnwrap(this.addonInstance.registry); - if (options.plugins.ast.length > 0) { - let opts: EtcOptions = { - compilerPath: options.templateCompilerPath, - targetFormat: 'hbs', - enableLegacyModules: [ - 'ember-cli-htmlbars', - 'ember-cli-htmlbars-inline-precompile', - 'htmlbars-inline-precompile', - ], - transforms: options.plugins.ast as any, - }; - return [require.resolve('babel-plugin-ember-template-compilation'), opts]; - } - } + let plugins = loadAstPlugins(this.addonInstance.registry); + // our macros don't run here in stage1 + plugins = plugins.filter((p: any) => !isEmbroiderMacrosPlugin(p)); + if (plugins.length > 0) { + let compilerPath = require.resolve('ember-source/dist/ember-template-compiler.js', { + paths: [findTopmostAddon(this.addonInstance).parent.root], + }); + let opts: EtcOptions = { + compilerPath, + targetFormat: 'hbs', + enableLegacyModules: [ + 'ember-cli-htmlbars', + 'ember-cli-htmlbars-inline-precompile', + 'htmlbars-inline-precompile', + ], + transforms: plugins, + }; + return [require.resolve('babel-plugin-ember-template-compilation'), opts]; } } diff --git a/types/ember-cli-htmlbars/index.d.ts b/types/ember-cli-htmlbars/index.d.ts deleted file mode 100644 index c1bbb7ebc..000000000 --- a/types/ember-cli-htmlbars/index.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -declare module 'ember-cli-htmlbars' { - import Plugin from 'broccoli-plugin'; - import { Node } from 'broccoli-node-api'; - - export interface Options { - name?: string; - plugins?: { - ast?: never[]; - [type: string]: unknown[]; - }; - templateCompiler: unknown; - templateCompilerPath: string; - }; - - - export default class HTMLBarsTransform extends Plugin { - constructor(inputTree: Node, options: Options); - build(): Promise; - protected cacheKeyProcessString(contents: string, relativePath: string): string; - protected targetExtension: string | null; - } -} diff --git a/types/ember-cli-htmlbars/package.json b/types/ember-cli-htmlbars/package.json deleted file mode 100644 index 7c7f0b53b..000000000 --- a/types/ember-cli-htmlbars/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "@types/ember-cli-htmlbars", - "version": "0.0.0", - "dependencies": { - "broccoli-plugin": "^4.0.1" - }, - "private": true -} From ed5e09c5c5df1476c83cad075321ee787d08bc48 Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Sat, 23 Dec 2023 11:48:07 -0500 Subject: [PATCH 2/3] keep the messier old parallelBabel hacks in order to keep working with older htmlbars --- .../src/prepare-htmlbars-ast-plugins.ts | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/compat/src/prepare-htmlbars-ast-plugins.ts b/packages/compat/src/prepare-htmlbars-ast-plugins.ts index 004641df5..9e787c0f4 100644 --- a/packages/compat/src/prepare-htmlbars-ast-plugins.ts +++ b/packages/compat/src/prepare-htmlbars-ast-plugins.ts @@ -1,7 +1,37 @@ import type { Transform } from 'babel-plugin-ember-template-compilation'; +import { join } from 'path'; export default function loadAstPlugins(registry: any): Transform[] { - let plugins = registry.load('htmlbars-ast-plugin').map((wrapper: any) => wrapper.plugin); + let wrappers = registry.load('htmlbars-ast-plugin'); + for (let wrapper of wrappers) { + const { plugin, parallelBabel, baseDir, cacheKey } = wrapper; + if (plugin) { + // if the parallelBabel options were set on the wrapper, but not on the plugin, add it + if (parallelBabel && !plugin.parallelBabel) { + plugin.parallelBabel = { + requireFile: join(__dirname, 'htmlbars-unwrapper.js'), + buildUsing: 'unwrapPlugin', + params: parallelBabel, + }; + } + + // NOTE: `_parallelBabel` (not `parallelBabel`) is expected by broccoli-babel-transpiler + if (plugin.parallelBabel && !plugin._parallelBabel) { + plugin._parallelBabel = plugin.parallelBabel; + } + + // if the baseDir is set on the wrapper, but not on the plugin, add it + if (baseDir && !plugin.baseDir) { + plugin.baseDir = baseDir; + } + + // if the cacheKey is set on the wrapper, but not on the plugin, add it + if (cacheKey && !plugin.cacheKey) { + plugin.cacheKey = cacheKey; + } + } + } + let plugins = wrappers.map((wrapper: any) => wrapper.plugin); plugins.reverse(); return plugins; } From 3b02398d3b35bbc77ab17094d6e51503e5354e35 Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Sat, 23 Dec 2023 11:49:21 -0500 Subject: [PATCH 3/3] adding comment --- packages/compat/src/prepare-htmlbars-ast-plugins.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/compat/src/prepare-htmlbars-ast-plugins.ts b/packages/compat/src/prepare-htmlbars-ast-plugins.ts index 9e787c0f4..3f55747d6 100644 --- a/packages/compat/src/prepare-htmlbars-ast-plugins.ts +++ b/packages/compat/src/prepare-htmlbars-ast-plugins.ts @@ -32,6 +32,10 @@ export default function loadAstPlugins(registry: any): Transform[] { } } let plugins = wrappers.map((wrapper: any) => wrapper.plugin); + + // the plugins in the registry historically run in backwards order for dumb + // reasons. Embroider keeps them in sensible order, so here is where we do the + // compatibility switch. plugins.reverse(); return plugins; }