From 1826a94ff751db1ff882ce1a38b4fa93797ba431 Mon Sep 17 00:00:00 2001 From: Dmitry Krasnoukhov Date: Fri, 13 Oct 2023 17:51:20 +0300 Subject: [PATCH 1/2] Allow for more flexible addon-dev appReexports --- .../addon-dev/src/rollup-app-reexports.ts | 15 ++++++------- packages/addon-dev/src/rollup.ts | 11 +++++++++- packages/router/package.json | 3 +-- .../scenarios/v2-addon-dev-typescript-test.ts | 21 +++++++++++++++++++ 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/packages/addon-dev/src/rollup-app-reexports.ts b/packages/addon-dev/src/rollup-app-reexports.ts index 036852367..daea185b4 100644 --- a/packages/addon-dev/src/rollup-app-reexports.ts +++ b/packages/addon-dev/src/rollup-app-reexports.ts @@ -8,6 +8,7 @@ export default function appReexports(opts: { to: string; include: string[]; mapFilename?: (filename: string) => string; + defaultExport?: string; }): Plugin { return { name: 'app-reexports', @@ -25,21 +26,21 @@ export default function appReexports(opts: { this.emitFile({ type: 'asset', fileName: `_app_/${appFilename}`, - source: `export { default } from "${pkg.name}/${addonFilename.slice( - 0, - -extname(addonFilename).length - )}";\n`, + source: `export ${opts.defaultExport} from "${ + pkg.name + }/${addonFilename.slice(0, -extname(addonFilename).length)}";\n`, }); } } let originalAppJS = pkg['ember-addon']?.['app-js']; - - let hasChanges = JSON.stringify(originalAppJS) !== JSON.stringify(appJS); + let newAppJs = Object.assign({}, originalAppJS || {}, appJS); + let hasChanges = + JSON.stringify(originalAppJS) !== JSON.stringify(newAppJs); // Don't cause a file i/o event unless something actually changed if (hasChanges) { pkg['ember-addon'] = Object.assign({}, pkg['ember-addon'], { - 'app-js': appJS, + 'app-js': newAppJs, }); writeJsonSync('package.json', pkg, { spaces: 2 }); } diff --git a/packages/addon-dev/src/rollup.ts b/packages/addon-dev/src/rollup.ts index d9c2de344..25297d593 100644 --- a/packages/addon-dev/src/rollup.ts +++ b/packages/addon-dev/src/rollup.ts @@ -1,3 +1,4 @@ +import { readJsonSync, writeJsonSync } from 'fs-extra'; import { default as hbs } from './rollup-hbs-plugin'; import { default as gjs } from './rollup-gjs-plugin'; import { default as publicEntrypoints } from './rollup-public-entrypoints'; @@ -16,6 +17,10 @@ export class Addon { constructor(params: { srcDir?: string; destDir?: string } = {}) { this.#srcDir = params.srcDir ?? 'src'; this.#destDir = params.destDir ?? 'dist'; + + let pkg = readJsonSync('package.json'); + delete pkg['ember-addon']['app-js']; + writeJsonSync('package.json', pkg, { spaces: 2 }); } // Given a list of globs describing modules in your srcDir, this generates @@ -23,13 +28,17 @@ export class Addon { // package.json metadata to list them all. appReexports( patterns: string[], - opts: { mapFilename?: (fileName: string) => string } = {} + opts: { + mapFilename?: (fileName: string) => string; + defaultExport?: string; + } = {} ): Plugin { return appReexports({ from: this.#srcDir, to: this.#destDir, include: patterns, mapFilename: opts.mapFilename, + defaultExport: opts.defaultExport || '{ default }', }); } diff --git a/packages/router/package.json b/packages/router/package.json index b81d2d7e8..84aeed424 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -73,8 +73,7 @@ "ember-addon": { "version": 2, "type": "addon", - "main": "addon-main.js", - "app-js": {} + "main": "addon-main.js" }, "exports": { ".": "./dist/index.js", diff --git a/tests/scenarios/v2-addon-dev-typescript-test.ts b/tests/scenarios/v2-addon-dev-typescript-test.ts index f0c65fc2a..03a811d0e 100644 --- a/tests/scenarios/v2-addon-dev-typescript-test.ts +++ b/tests/scenarios/v2-addon-dev-typescript-test.ts @@ -21,6 +21,9 @@ appScenarios addon.pkg.scripts = { build: 'node ./node_modules/rollup/dist/bin/rollup -c ./rollup.config.mjs', }; + addon.pkg['ember-addon']['app-js'] = { + './components/previously-added.js': './dist/_app_/components/previously-added.js', + }; merge(addon.files, { 'babel.config.json': ` @@ -91,6 +94,7 @@ appScenarios plugins: [ addon.publicEntrypoints([ 'components/**/*.js', + 'initializers/**/*.js', ]), addon.appReexports([ @@ -100,6 +104,9 @@ appScenarios ], { mapFilename: (name) => reexportMappings[name] || name, }), + addon.appReexports(['initializers/**/*.js'], { + defaultExport: '{ default, initialize }', + }), addon.dependencies(), @@ -167,6 +174,18 @@ appScenarios `, }, }, + initializers: { + 'demo.js': ` + export function initialize() { + // Wow, we're doing the init in the app + } + + export default { + name: 'demo', + initialize, + }; + `, + }, }, }); @@ -250,6 +269,7 @@ appScenarios './components/demo/index.js': './dist/_app_/components/demo/index.js', './components/demo/out.js': './dist/_app_/components/demo/out.js', './components/demo/namespace/namespace-me.js': './dist/_app_/components/demo/namespace/namespace-me.js', + './initializers/demo.js': './dist/_app_/initializers/demo.js', }); }); @@ -260,6 +280,7 @@ appScenarios './dist/_app_/components/demo/out.js': 'export { default } from "v2-addon/components/demo/out";\n', './dist/_app_/components/demo/namespace/namespace-me.js': 'export { default } from "v2-addon/components/demo/namespace-me";\n', + './dist/_app_/initializers/demo.js': 'export { default, initialize } from "v2-addon/initializers/demo";\n', }; assert.strictEqual( From de5f7a85c74038d8aac220d4bf8326007f18111d Mon Sep 17 00:00:00 2001 From: Dmitry Krasnoukhov Date: Fri, 20 Oct 2023 10:14:06 +0300 Subject: [PATCH 2/2] Address feedback --- .../addon-dev/src/rollup-app-reexports.ts | 17 +++++++++----- packages/addon-dev/src/rollup.ts | 9 ++------ packages/router/package.json | 3 ++- .../scenarios/v2-addon-dev-typescript-test.ts | 22 ++++++++++++++++--- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/packages/addon-dev/src/rollup-app-reexports.ts b/packages/addon-dev/src/rollup-app-reexports.ts index daea185b4..4f5750141 100644 --- a/packages/addon-dev/src/rollup-app-reexports.ts +++ b/packages/addon-dev/src/rollup-app-reexports.ts @@ -8,7 +8,7 @@ export default function appReexports(opts: { to: string; include: string[]; mapFilename?: (filename: string) => string; - defaultExport?: string; + exports?: (filename: string) => string[] | string | undefined; }): Plugin { return { name: 'app-reexports', @@ -17,6 +17,12 @@ export default function appReexports(opts: { let appJS: Record = {}; for (let addonFilename of Object.keys(bundle)) { let appFilename = opts.mapFilename?.(addonFilename) ?? addonFilename; + let appExports = opts.exports?.(addonFilename) || ['default']; + + let computedExports = + typeof appExports === 'string' + ? appExports + : `{ ${appExports.join(', ')} }`; if ( opts.include.some((glob) => minimatch(addonFilename, glob)) && @@ -26,21 +32,20 @@ export default function appReexports(opts: { this.emitFile({ type: 'asset', fileName: `_app_/${appFilename}`, - source: `export ${opts.defaultExport} from "${ + source: `export ${computedExports} from "${ pkg.name }/${addonFilename.slice(0, -extname(addonFilename).length)}";\n`, }); } } let originalAppJS = pkg['ember-addon']?.['app-js']; - let newAppJs = Object.assign({}, originalAppJS || {}, appJS); - let hasChanges = - JSON.stringify(originalAppJS) !== JSON.stringify(newAppJs); + + let hasChanges = JSON.stringify(originalAppJS) !== JSON.stringify(appJS); // Don't cause a file i/o event unless something actually changed if (hasChanges) { pkg['ember-addon'] = Object.assign({}, pkg['ember-addon'], { - 'app-js': newAppJs, + 'app-js': appJS, }); writeJsonSync('package.json', pkg, { spaces: 2 }); } diff --git a/packages/addon-dev/src/rollup.ts b/packages/addon-dev/src/rollup.ts index 25297d593..a24b5e40f 100644 --- a/packages/addon-dev/src/rollup.ts +++ b/packages/addon-dev/src/rollup.ts @@ -1,4 +1,3 @@ -import { readJsonSync, writeJsonSync } from 'fs-extra'; import { default as hbs } from './rollup-hbs-plugin'; import { default as gjs } from './rollup-gjs-plugin'; import { default as publicEntrypoints } from './rollup-public-entrypoints'; @@ -17,10 +16,6 @@ export class Addon { constructor(params: { srcDir?: string; destDir?: string } = {}) { this.#srcDir = params.srcDir ?? 'src'; this.#destDir = params.destDir ?? 'dist'; - - let pkg = readJsonSync('package.json'); - delete pkg['ember-addon']['app-js']; - writeJsonSync('package.json', pkg, { spaces: 2 }); } // Given a list of globs describing modules in your srcDir, this generates @@ -30,7 +25,7 @@ export class Addon { patterns: string[], opts: { mapFilename?: (fileName: string) => string; - defaultExport?: string; + exports?: (filename: string) => string[] | string | undefined; } = {} ): Plugin { return appReexports({ @@ -38,7 +33,7 @@ export class Addon { to: this.#destDir, include: patterns, mapFilename: opts.mapFilename, - defaultExport: opts.defaultExport || '{ default }', + exports: opts.exports, }); } diff --git a/packages/router/package.json b/packages/router/package.json index 84aeed424..b81d2d7e8 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -73,7 +73,8 @@ "ember-addon": { "version": 2, "type": "addon", - "main": "addon-main.js" + "main": "addon-main.js", + "app-js": {} }, "exports": { ".": "./dist/index.js", diff --git a/tests/scenarios/v2-addon-dev-typescript-test.ts b/tests/scenarios/v2-addon-dev-typescript-test.ts index 03a811d0e..07c1f9cc3 100644 --- a/tests/scenarios/v2-addon-dev-typescript-test.ts +++ b/tests/scenarios/v2-addon-dev-typescript-test.ts @@ -95,17 +95,24 @@ appScenarios addon.publicEntrypoints([ 'components/**/*.js', 'initializers/**/*.js', + 'utils/**/*.js', ]), addon.appReexports([ 'components/demo/index.js', 'components/demo/out.js', 'components/demo/namespace-me.js', + 'initializers/**/*.js', + 'utils/**/*.js', ], { mapFilename: (name) => reexportMappings[name] || name, - }), - addon.appReexports(['initializers/**/*.js'], { - defaultExport: '{ default, initialize }', + exports: (name) => { + if (name.startsWith('initializers/')) { + return ['default', 'initialize']; + } else if (name.startsWith('utils/')) { + return '*'; + } + } }), addon.dependencies(), @@ -186,6 +193,13 @@ appScenarios }; `, }, + utils: { + 'demo-util.js': ` + export function demoUtil() { + return 42; + } + `, + }, }, }); @@ -270,6 +284,7 @@ appScenarios './components/demo/out.js': './dist/_app_/components/demo/out.js', './components/demo/namespace/namespace-me.js': './dist/_app_/components/demo/namespace/namespace-me.js', './initializers/demo.js': './dist/_app_/initializers/demo.js', + './utils/demo-util.js': './dist/_app_/utils/demo-util.js', }); }); @@ -281,6 +296,7 @@ appScenarios './dist/_app_/components/demo/namespace/namespace-me.js': 'export { default } from "v2-addon/components/demo/namespace-me";\n', './dist/_app_/initializers/demo.js': 'export { default, initialize } from "v2-addon/initializers/demo";\n', + './dist/_app_/utils/demo-util.js': 'export * from "v2-addon/utils/demo-util";\n', }; assert.strictEqual(