diff --git a/plugins/ember-vendor.ts b/plugins/ember-vendor.ts index c956251..9d3833e 100644 --- a/plugins/ember-vendor.ts +++ b/plugins/ember-vendor.ts @@ -13,8 +13,11 @@ const modeModulesPath = path.resolve( export function internalPackages(mode: string) { return [ Addon('ember & ember-source & @ember/*', mode) - .addAlias(/^ember$/, 'ember-source/dist/packages/ember') - .addAlias(/^ember\/version$/, 'ember-source/dist/packages/ember/version') + .addAlias(/^ember$/, nodePath('ember-source/dist/packages/ember')) + .addAlias( + /^ember\/version$/, + nodePath('ember-source/dist/packages/ember/version') + ) .addAliases( emberPackages().map((pkg) => ({ find: `@ember/${pkg}`, @@ -23,10 +26,10 @@ export function internalPackages(mode: string) { ), Addon('@glimmer/*', mode) - .addAlias( - '@glimmer/validator', - nodePath('@glimmer/validator/dist/modules/es2017') - ) + // .addAlias( + // '@glimmer/validator', + // nodePath('@glimmer/validator/dist/modules/es2017') + // ) .addAlias( '@glimmer/tracking/primitives/cache', nodePath( @@ -39,7 +42,7 @@ export function internalPackages(mode: string) { ) .addAlias( '@glimmer/component', - '@glimmer/component/addon/-private/component' + nodePath('@glimmer/component/addon/-private/component') ) .addAlias('@glimmer/env', compatPath('glimmer-env')) .addAliases( @@ -57,15 +60,15 @@ export function internalPackages(mode: string) { ), Addon('ember-component-manager', mode).addSelfAlias( - '@glimmer/component/addon/-private/ember-component-manager' + nodePath('@glimmer/component/addon/-private/ember-component-manager') ), Addon('@ember/test-helpers', mode).addSelfAlias( - '@ember/test-helpers/addon-test-support/@ember/test-helpers' + nodePath('@ember/test-helpers/addon-test-support/@ember/test-helpers') ), Addon('@ember/test-waiters', mode).addSelfAlias( - '@ember/test-waiters/addon/@ember/test-waiters' + nodePath('@ember/test-waiters/addon/@ember/test-waiters') ), Addon('ember-compatibility-helpers', mode).addSelfAlias( @@ -87,13 +90,16 @@ export function internalPackages(mode: string) { ), Addon('require', mode).addSelfAlias(compatPath('require/index.ts')), Addon('ember-template-compiler', mode).addSelfAlias( - 'node_modules/ember-source/dist/ember-template-compiler.js' + nodePath('ember-source/dist/ember-template-compiler.js') ), Addon('ember-testing', mode) - .addAlias(/^ember-testing$/, 'ember-source/dist/packages/ember-testing') + .addAlias( + /^ember-testing$/, + nodePath('ember-source/dist/packages/ember-testing') + ) .addAlias( /^ember-testing\//, - 'ember-source/dist/packages/ember-testing/' + nodePath('ember-source/dist/packages/ember-testing/') ), Addon('@embroider/macros', mode).addSelfAlias( compatPath('embroider-macros/index.ts') diff --git a/plugins/ember.ts b/plugins/ember.ts index 420c139..67ae17e 100644 --- a/plugins/ember.ts +++ b/plugins/ember.ts @@ -18,6 +18,16 @@ export function App(mode: string) { const isDev = addon.isDev; const enableSourceMaps = isDev; + addon.resolveExtensions([ + '.mjs', + '.js', + '.ts', + '.jsx', + '.tsx', + '.json', + '.hbs', + ]); + addon.babelPlugins = [ hbsResolver(isProd), gtsResolver(isProd), @@ -79,6 +89,7 @@ export function emberAppConfig( addons: EmberAddon[] ) { addons.forEach((el) => el.attachToConfig(definedConfig)); + // console.table(definedConfig.resolve.alias); return definedConfig; } @@ -94,9 +105,11 @@ function addonBabelConfig( class EmberAddon { name!: string; - aliases: unknown[] = []; + aliases: { find: unknown; replacement: unknown }[] = []; babelPlugins: unknown[] = []; mode: string; + defineConfig: Record = {}; + extensions: string[] = []; constructor(name: string, mode: string) { this.name = name; this.mode = mode; @@ -120,6 +133,14 @@ class EmberAddon { }); return this; } + resolveExtensions(extensions: string[]) { + this.extensions = Array.from(new Set([...this.extensions, ...extensions])); + return this; + } + extendDefineConfig(config: Record) { + this.defineConfig = { ...this.defineConfig, ...config }; + return this; + } needBabel( { removeLegacyLayout, @@ -172,12 +193,58 @@ class EmberAddon { }); return this; } - attachToConfig(config: UserConfig) { + fixConfig(config: UserConfig) { + const resolveExtensions = config?.resolve?.extensions ?? []; + const resolveAlias = config?.resolve?.alias ?? []; + const plugins = config?.plugins ?? []; + const define = config?.define ?? {}; + if (!config.resolve) { + config.resolve = { + extensions: [], + alias: [], + }; + } + config.resolve.extensions = resolveExtensions; + config.resolve.alias = resolveAlias; + config.plugins = plugins; + config.define = define; + + return config as UserConfig & { + resolve: { + extensions: string[]; + alias: { find: unknown; replacement: unknown }[]; + }; + plugins: unknown[]; + define: Record; + }; + } + attachToConfig(rawConfig: UserConfig) { + const config = this.fixConfig(rawConfig); + this.extensions.forEach((el) => { + if (!config.resolve.extensions.includes(el)) { + config.resolve.extensions.push(el); + } + }); this.aliases.forEach((el) => { - config?.resolve?.alias.push(el); + const existingAlias = config.resolve.alias.find((alias) => alias.find === el.find); + if (!existingAlias) { + config.resolve.alias.push(el); + } else { + throw new Error( + `Alias ${el.find} already exists, but imported by [${this.name}] addon. Please check your config. + Existing alias: ${existingAlias.replacement} + New alias: ${el.replacement} + ` + ); + } }); this.babelPlugins.forEach((el) => { - config?.plugins?.push(el); + config.plugins.push(el); + }); + Object.keys(this.defineConfig).forEach((el) => { + if (config.define) { + config.define[el] = this.defineConfig[el]; + } }); return this; } diff --git a/vite.config.ts b/vite.config.ts index 3c4ae86..2850b0b 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,7 +1,7 @@ import { defineConfig } from 'vite'; import { fileURLToPath, URL } from 'node:url'; import { resolve } from 'node:path'; -import { generateDefineConfig } from './compat/ember-data-private-build-infra/index.ts'; +import { generateDefineConfig } from './compat/ember-data-private-build-infra/index'; import { Addon as AddonConstructor, compatPath, @@ -44,33 +44,26 @@ export default defineConfig(({ mode }) => { preview: { port: 4200, }, - define: { - ENV_DEBUG: isProd ? false : true, - ENV_CI: false, - ...generateDefineConfig(isProd), - }, - resolve: { - extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.hbs'], - alias: [ - { - find: `@/tests/`, - replacement: fileURLToPath(new URL(`./tests/`, projectRoot)), - }, - ...localScopes().map((scope) => ({ - find: `@/${scope}`, - replacement: fileURLToPath(new URL(`./src/${scope}`, projectRoot)), - })), - ], - }, - plugins: [], }, [ - App(), + App() + .extendDefineConfig({ + ENV_DEBUG: isProd ? false : true, + ENV_CI: false, + }) + .addAlias(`@/tests/`, fileURLToPath(new URL(`./tests/`, projectRoot))) + .addAliases( + localScopes().map((scope) => ({ + find: `@/${scope}`, + replacement: fileURLToPath(new URL(`./src/${scope}`, projectRoot)), + })) + ), ...internalPackages(mode), Addon('@ember-data') .needBabel() + .extendDefineConfig(generateDefineConfig(isProd)) .addAliases( eDataPackages().map((pkg) => ({ find: `@ember-data/${pkg}`, @@ -108,11 +101,11 @@ export default defineConfig(({ mode }) => { Addon('ember-simple-auth') .addNestedAlias( 'use-session-setup-method', - './compat/ember-simple-auth/use-session-setup-method.ts' + compatPath('ember-simple-auth/use-session-setup-method.ts') ) .addAlias( /ember-simple-auth\/(?!(app|addon)\/)(.+)/, - 'ember-simple-auth/addon/$2' + nodePath('ember-simple-auth/addon/$2') ), ] );