From 361439c3ec75c48fb07951e21d9247ffc4b4c51a Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Thu, 3 Aug 2023 21:44:12 -0400 Subject: [PATCH 01/10] make addon a module Addon-main is cjs, it should have cjs extension Reproduction success Make separate scenario Test file must end with -test Need to update the app's ember-cli-babel Test is passing, now let's break it again... Break successful --- pnpm-lock.yaml | 28 ++- tests/scenarios/package.json | 2 + tests/scenarios/v2-addon-test.ts | 4 +- tests/scenarios/v2-addon-type-module-test.ts | 216 ++++++++++++++++++ .../{addon-main.js => addon-main.cjs} | 0 tests/v2-addon-template/package.json | 2 +- 6 files changed, 246 insertions(+), 6 deletions(-) create mode 100644 tests/scenarios/v2-addon-type-module-test.ts rename tests/v2-addon-template/{addon-main.js => addon-main.cjs} (100%) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5c86c0356..c2f8d67f0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1526,6 +1526,9 @@ importers: '@types/qunit': specifier: ^2.11.1 version: 2.19.10 + decorator-transforms: + specifier: ^1.0.1 + version: 1.0.1(@babel/core@7.24.5) ember-auto-import: specifier: ^2.6.3 version: 2.7.2 @@ -1662,6 +1665,9 @@ importers: ember-cli-4.4: specifier: npm:ember-cli@~4.4.0 version: /ember-cli@4.4.1(lodash@4.17.21) + ember-cli-babel-8: + specifier: npm:ember-cli-babel@^8.2.0 + version: /ember-cli-babel@8.2.0(@babel/core@7.24.5) ember-cli-beta: specifier: npm:ember-cli@beta version: /ember-cli@5.9.0-beta.1 @@ -2461,6 +2467,16 @@ packages: '@babel/core': 7.24.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.5 + /@babel/plugin-syntax-decorators@7.23.3(@babel/core@7.24.5): + resolution: {integrity: sha512-cf7Niq4/+/juY67E0PbgH0TDhLQ5J7zS8C/Q5FFx+DWyrRa9sUQdTXkjqKu8zGvuqr7vw1muKiukseihU+PJDA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.5(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.24.5 + dev: false + /@babel/plugin-syntax-decorators@7.24.1(@babel/core@7.24.5): resolution: {integrity: sha512-05RJdO/cCrtVWuAaSn1tS3bH8jbsJa/Y1uD186u6J4C/1mnHFxseeuWpsqr9anvo7TUulev7tm7GDwRV+VuhDw==} engines: {node: '>=6.9.0'} @@ -7225,9 +7241,6 @@ packages: /ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} - peerDependenciesMeta: - ajv: - optional: true dependencies: ajv: 8.13.0 @@ -10414,6 +10427,15 @@ packages: mimic-response: 1.0.1 dev: true + /decorator-transforms@1.0.1(@babel/core@7.24.5): + resolution: {integrity: sha512-ZOaiw4tqiyhtqiMKCNzjS+nGsYPZltToqRAFc5rOUcc4u8d7MTlgelw1qXfL6ieg2l6xZcz6lTZ5M94Ohnk2xA==} + dependencies: + '@babel/plugin-syntax-decorators': 7.23.3(@babel/core@7.24.5) + babel-import-util: 2.1.1 + transitivePeerDependencies: + - '@babel/core' + dev: false + /dedent@1.5.3: resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} peerDependencies: diff --git a/tests/scenarios/package.json b/tests/scenarios/package.json index e30a5538e..38108851f 100644 --- a/tests/scenarios/package.json +++ b/tests/scenarios/package.json @@ -10,6 +10,7 @@ "@embroider/test-support": "workspace:*", "@embroider/webpack": "workspace:*", "@types/qunit": "^2.11.1", + "decorator-transforms": "^1.0.1", "ember-auto-import": "^2.6.3", "fastboot": "^4.1.1", "fs-extra": "^10.0.0", @@ -67,6 +68,7 @@ "ember-cli-beta": "npm:ember-cli@beta", "ember-cli-fastboot": "^4.1.1", "ember-cli-latest": "npm:ember-cli@latest", + "ember-cli-babel-8": "npm:ember-cli-babel@^8.2.0", "ember-composable-helpers": "^4.4.1", "ember-data": "~3.28.0", "ember-data-4.4": "npm:ember-data@~4.4.0", diff --git a/tests/scenarios/v2-addon-test.ts b/tests/scenarios/v2-addon-test.ts index 4c18982cb..f67fe825d 100644 --- a/tests/scenarios/v2-addon-test.ts +++ b/tests/scenarios/v2-addon-test.ts @@ -32,9 +32,9 @@ appScenarios 'example-component.css': '/* not empty */ h1 { color: red }', }, 'import-from-npm.js': ` - export default async function() { + export default async function() { let { message } = await import('third-party'); - return message() + return message() } `, }); diff --git a/tests/scenarios/v2-addon-type-module-test.ts b/tests/scenarios/v2-addon-type-module-test.ts new file mode 100644 index 000000000..bf7ebe6a2 --- /dev/null +++ b/tests/scenarios/v2-addon-type-module-test.ts @@ -0,0 +1,216 @@ +import path from 'path'; +import { appScenarios, baseV2Addon } from './scenarios'; +import { PreparedApp } from 'scenario-tester'; +import QUnit from 'qunit'; +import merge from 'lodash/merge'; +import { pathExistsSync, readJsonSync, readFileSync } from 'fs-extra'; + +const { module: Qmodule, test } = QUnit; + +appScenarios + .only('release') + .map('v2-addon-as-type-module', async project => { + let addon = baseV2Addon(); + addon.pkg.name = 'v2-addon'; + addon.pkg.type = 'module'; + addon.pkg.files = ['dist']; + addon.pkg.exports = { + './*': './dist/*.js', + './addon-main.cjs': './addon-main.cjs', + // needed for our "inDependency" function defined in this test + './package.json': './package.json', + }; + addon.pkg.scripts = { + build: 'node ./node_modules/rollup/dist/bin/rollup -c ./rollup.config.mjs', + }; + + merge(addon.files, { + 'babel.config.json': ` + { + "plugins": [ + ["babel-plugin-ember-template-compilation", { + "targetFormat": "hbs", + "transforms": [] + }], + ["module:decorator-transforms", { "runtime": { "import": "decorator-transforms/runtime" } }] + ] + } + `, + 'rollup.config.mjs': ` + import { Addon } from '@embroider/addon-dev/rollup'; + import { babel } from '@rollup/plugin-babel'; + + const addon = new Addon({ + srcDir: 'src', + destDir: 'dist', + }); + + export default { + output: addon.output(), + plugins: [ + addon.publicEntrypoints(['**/*.js']), + addon.appReexports(['components/*.js']), + addon.dependencies(), + babel({ extensions: ['.js', '.gjs', '.ts', '.gts'], babelHelpers: 'bundled' }), + addon.gjs(), + addon.hbs(), + addon.keepAssets(["**/*.css"]), + addon.clean(), + ], + }; + + `, + src: { + components: { + 'styles.css': `button { font-weight: bold; color: blue; }`, + 'demo.gjs': ` + import Component from '@glimmer/component'; + import { tracked } from '@glimmer/tracking'; + import { on } from '@ember/modifier'; + + import { importSync, isDevelopingApp, macroCondition } from '@embroider/macros'; + + if (macroCondition(isDevelopingApp())) { + importSync('./styles.css'); + } + + export default class ExampleComponent extends Component { + @tracked active = false; + + flip = () => (this.active = !this.active); + + + } + `, + }, + }, + }); + + addon.linkDependency('@embroider/addon-shim', { baseDir: __dirname }); + addon.linkDependency('@embroider/addon-dev', { baseDir: __dirname }); + addon.linkDependency('@babel/runtime', { baseDir: __dirname }); + addon.linkDevDependency('@babel/core', { baseDir: __dirname }); + addon.linkDevDependency('@rollup/plugin-babel', { baseDir: __dirname }); + addon.linkDependency('decorator-transforms', { baseDir: __dirname }); + addon.linkDevDependency('rollup', { baseDir: __dirname }); + + project.addDevDependency(addon); + project.linkDevDependency('ember-cli-babel', { baseDir: __dirname, resolveName: 'ember-cli-babel-8' }); + project.linkDevDependency('@embroider/macros', { baseDir: __dirname }); + + merge(project.files, { + tests: { + // the app is not set up with typescript + 'the-test.js': ` + import { click, render } from '@ember/test-helpers'; + import { hbs } from 'ember-cli-htmlbars'; + import { module, test } from 'qunit'; + import { setupRenderingTest } from 'ember-qunit'; + + module('v2 addon tests', function (hooks) { + setupRenderingTest(hooks); + + test('', async function (assert) { + await render(hbs\`\`); + + assert.dom('out').containsText('false'); + + await click('button'); + + assert.dom('out').containsText('true'); + }); + }); + `, + }, + 'ember-cli-build.js': ` + 'use strict'; + + const EmberApp = require('ember-cli/lib/broccoli/ember-app'); + + module.exports = function (defaults) { + let app = new EmberApp(defaults, { + }); + + const { compatBuild, recommendedOptions } = require('@embroider/compat'); + + const Webpack = require('@embroider/webpack').Webpack; + return compatBuild(app, Webpack, { + ...recommendedOptions.optimized, + skipBabel: [ + { package: 'qunit' }, + ], + }); + }; + `, + }); + }) + .forEachScenario(scenario => { + Qmodule(scenario.name, function (hooks) { + let app: PreparedApp; + + hooks.before(async () => { + app = await scenario.prepare(); + let result = await inDependency(app, 'v2-addon').execute('pnpm build'); + if (result.exitCode !== 0) { + throw new Error(result.output); + } + }); + + Qmodule('The addon', function () { + test('output directories exist', async function (assert) { + let { dir } = inDependency(app, 'v2-addon'); + assert.strictEqual(pathExistsSync(path.join(dir, 'dist')), true, 'dist/'); + assert.strictEqual(pathExistsSync(path.join(dir, 'dist', '_app_')), true, 'dist/_app_'); + }); + + test('package.json is modified appropriately', async function (assert) { + let { dir } = inDependency(app, 'v2-addon'); + let reExports = readJsonSync(path.join(dir, 'package.json'))['ember-addon']['app-js']; + + assert.deepEqual(reExports, { + './components/demo.js': './dist/_app_/components/demo.js', + }); + }); + + test('the addon was built successfully', async function (assert) { + let { dir } = inDependency(app, 'v2-addon'); + let expectedModules = { + './dist/_app_/components/demo.js': 'export { default } from "v2-addon/components/demo";\n', + }; + + assert.strictEqual( + Object.keys(readJsonSync(path.join(dir, 'package.json'))['ember-addon']['app-js']).length, + Object.keys(expectedModules).length + ); + + for (let [pathName, moduleContents] of Object.entries(expectedModules)) { + let filePath = path.join(dir, pathName); + assert.deepEqual(pathExistsSync(filePath), true, `pathExists: ${pathName}`); + assert.strictEqual( + readFileSync(filePath, { encoding: 'utf8' }), + moduleContents, + `has correct reexport: ${pathName}` + ); + } + }); + }); + + Qmodule('Consuming app', function () { + test(`pnpm test`, async function (assert) { + let result = await app.execute('pnpm test'); + assert.equal(result.exitCode, 0, result.output); + }); + }); + }); + }); + +// https://github.com/ef4/scenario-tester/issues/5 +function inDependency(app: PreparedApp, dependencyName: string): PreparedApp { + return new PreparedApp(path.dirname(require.resolve(`${dependencyName}/package.json`, { paths: [app.dir] }))); +} diff --git a/tests/v2-addon-template/addon-main.js b/tests/v2-addon-template/addon-main.cjs similarity index 100% rename from tests/v2-addon-template/addon-main.js rename to tests/v2-addon-template/addon-main.cjs diff --git a/tests/v2-addon-template/package.json b/tests/v2-addon-template/package.json index 8fe72de7d..c87ddcc83 100644 --- a/tests/v2-addon-template/package.json +++ b/tests/v2-addon-template/package.json @@ -12,7 +12,7 @@ "type": "addon", "version": 2, "app-js": {}, - "main": "addon-main.js" + "main": "addon-main.cjs" }, "exports": { "./*": "./*" From 345dfc61631c87cd4ba4c3d5603d9b9754c35ab0 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Tue, 7 May 2024 10:06:44 -0400 Subject: [PATCH 02/10] Reduce test to just es-compat resolving --- tests/scenarios/v2-addon-type-module-test.ts | 102 +++---------------- 1 file changed, 13 insertions(+), 89 deletions(-) diff --git a/tests/scenarios/v2-addon-type-module-test.ts b/tests/scenarios/v2-addon-type-module-test.ts index bf7ebe6a2..b083afa7a 100644 --- a/tests/scenarios/v2-addon-type-module-test.ts +++ b/tests/scenarios/v2-addon-type-module-test.ts @@ -3,7 +3,7 @@ import { appScenarios, baseV2Addon } from './scenarios'; import { PreparedApp } from 'scenario-tester'; import QUnit from 'qunit'; import merge from 'lodash/merge'; -import { pathExistsSync, readJsonSync, readFileSync } from 'fs-extra'; +import { pathExistsSync } from 'fs-extra'; const { module: Qmodule, test } = QUnit; @@ -25,17 +25,6 @@ appScenarios }; merge(addon.files, { - 'babel.config.json': ` - { - "plugins": [ - ["babel-plugin-ember-template-compilation", { - "targetFormat": "hbs", - "transforms": [] - }], - ["module:decorator-transforms", { "runtime": { "import": "decorator-transforms/runtime" } }] - ] - } - `, 'rollup.config.mjs': ` import { Addon } from '@embroider/addon-dev/rollup'; import { babel } from '@rollup/plugin-babel'; @@ -49,46 +38,24 @@ appScenarios output: addon.output(), plugins: [ addon.publicEntrypoints(['**/*.js']), - addon.appReexports(['components/*.js']), addon.dependencies(), - babel({ extensions: ['.js', '.gjs', '.ts', '.gts'], babelHelpers: 'bundled' }), - addon.gjs(), - addon.hbs(), - addon.keepAssets(["**/*.css"]), + babel({ extensions: ['.js'], babelHelpers: 'bundled' }), addon.clean(), ], }; `, src: { - components: { - 'styles.css': `button { font-weight: bold; color: blue; }`, - 'demo.gjs': ` - import Component from '@glimmer/component'; - import { tracked } from '@glimmer/tracking'; - import { on } from '@ember/modifier'; - - import { importSync, isDevelopingApp, macroCondition } from '@embroider/macros'; - - if (macroCondition(isDevelopingApp())) { - importSync('./styles.css'); - } - - export default class ExampleComponent extends Component { - @tracked active = false; - - flip = () => (this.active = !this.active); + 'index.js': ` + import { importSync, isDevelopingApp, macroCondition } from '@embroider/macros'; - - } - `, - }, + if (macroCondition(isDevelopingApp())) { + // value will be asserted in the test + foo = 'macro' + } + `, }, }); @@ -97,7 +64,6 @@ appScenarios addon.linkDependency('@babel/runtime', { baseDir: __dirname }); addon.linkDevDependency('@babel/core', { baseDir: __dirname }); addon.linkDevDependency('@rollup/plugin-babel', { baseDir: __dirname }); - addon.linkDependency('decorator-transforms', { baseDir: __dirname }); addon.linkDevDependency('rollup', { baseDir: __dirname }); project.addDevDependency(addon); @@ -108,22 +74,12 @@ appScenarios tests: { // the app is not set up with typescript 'the-test.js': ` - import { click, render } from '@ember/test-helpers'; - import { hbs } from 'ember-cli-htmlbars'; import { module, test } from 'qunit'; - import { setupRenderingTest } from 'ember-qunit'; + import { foo } from 'v2-addon'; module('v2 addon tests', function (hooks) { - setupRenderingTest(hooks); - - test('', async function (assert) { - await render(hbs\`\`); - - assert.dom('out').containsText('false'); - - await click('button'); - - assert.dom('out').containsText('true'); + test('macros ran', async function (assert) { + assert.strictEqual(foo, 'macro'); }); }); `, @@ -166,38 +122,6 @@ appScenarios test('output directories exist', async function (assert) { let { dir } = inDependency(app, 'v2-addon'); assert.strictEqual(pathExistsSync(path.join(dir, 'dist')), true, 'dist/'); - assert.strictEqual(pathExistsSync(path.join(dir, 'dist', '_app_')), true, 'dist/_app_'); - }); - - test('package.json is modified appropriately', async function (assert) { - let { dir } = inDependency(app, 'v2-addon'); - let reExports = readJsonSync(path.join(dir, 'package.json'))['ember-addon']['app-js']; - - assert.deepEqual(reExports, { - './components/demo.js': './dist/_app_/components/demo.js', - }); - }); - - test('the addon was built successfully', async function (assert) { - let { dir } = inDependency(app, 'v2-addon'); - let expectedModules = { - './dist/_app_/components/demo.js': 'export { default } from "v2-addon/components/demo";\n', - }; - - assert.strictEqual( - Object.keys(readJsonSync(path.join(dir, 'package.json'))['ember-addon']['app-js']).length, - Object.keys(expectedModules).length - ); - - for (let [pathName, moduleContents] of Object.entries(expectedModules)) { - let filePath = path.join(dir, pathName); - assert.deepEqual(pathExistsSync(filePath), true, `pathExists: ${pathName}`); - assert.strictEqual( - readFileSync(filePath, { encoding: 'utf8' }), - moduleContents, - `has correct reexport: ${pathName}` - ); - } }); }); From f716780734f335478f3cf37ac5385da1a31dae3b Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Tue, 7 May 2024 10:39:51 -0400 Subject: [PATCH 03/10] Passes (incorrectly) --- tests/scenarios/v2-addon-type-module-test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/scenarios/v2-addon-type-module-test.ts b/tests/scenarios/v2-addon-type-module-test.ts index b083afa7a..5b7630b93 100644 --- a/tests/scenarios/v2-addon-type-module-test.ts +++ b/tests/scenarios/v2-addon-type-module-test.ts @@ -15,6 +15,7 @@ appScenarios addon.pkg.type = 'module'; addon.pkg.files = ['dist']; addon.pkg.exports = { + '.': './dist/index.js', './*': './dist/*.js', './addon-main.cjs': './addon-main.cjs', // needed for our "inDependency" function defined in this test From b31507609e1365b0bdc7a2d41ef31f7c910b8e9c Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Tue, 7 May 2024 10:40:46 -0400 Subject: [PATCH 04/10] fails (correctly) --- tests/scenarios/v2-addon-type-module-test.ts | 103 ++++++++++++++++--- 1 file changed, 89 insertions(+), 14 deletions(-) diff --git a/tests/scenarios/v2-addon-type-module-test.ts b/tests/scenarios/v2-addon-type-module-test.ts index 5b7630b93..bf7ebe6a2 100644 --- a/tests/scenarios/v2-addon-type-module-test.ts +++ b/tests/scenarios/v2-addon-type-module-test.ts @@ -3,7 +3,7 @@ import { appScenarios, baseV2Addon } from './scenarios'; import { PreparedApp } from 'scenario-tester'; import QUnit from 'qunit'; import merge from 'lodash/merge'; -import { pathExistsSync } from 'fs-extra'; +import { pathExistsSync, readJsonSync, readFileSync } from 'fs-extra'; const { module: Qmodule, test } = QUnit; @@ -15,7 +15,6 @@ appScenarios addon.pkg.type = 'module'; addon.pkg.files = ['dist']; addon.pkg.exports = { - '.': './dist/index.js', './*': './dist/*.js', './addon-main.cjs': './addon-main.cjs', // needed for our "inDependency" function defined in this test @@ -26,6 +25,17 @@ appScenarios }; merge(addon.files, { + 'babel.config.json': ` + { + "plugins": [ + ["babel-plugin-ember-template-compilation", { + "targetFormat": "hbs", + "transforms": [] + }], + ["module:decorator-transforms", { "runtime": { "import": "decorator-transforms/runtime" } }] + ] + } + `, 'rollup.config.mjs': ` import { Addon } from '@embroider/addon-dev/rollup'; import { babel } from '@rollup/plugin-babel'; @@ -39,24 +49,46 @@ appScenarios output: addon.output(), plugins: [ addon.publicEntrypoints(['**/*.js']), + addon.appReexports(['components/*.js']), addon.dependencies(), - babel({ extensions: ['.js'], babelHelpers: 'bundled' }), + babel({ extensions: ['.js', '.gjs', '.ts', '.gts'], babelHelpers: 'bundled' }), + addon.gjs(), + addon.hbs(), + addon.keepAssets(["**/*.css"]), addon.clean(), ], }; `, src: { - 'index.js': ` - import { importSync, isDevelopingApp, macroCondition } from '@embroider/macros'; + components: { + 'styles.css': `button { font-weight: bold; color: blue; }`, + 'demo.gjs': ` + import Component from '@glimmer/component'; + import { tracked } from '@glimmer/tracking'; + import { on } from '@ember/modifier'; - export let foo = 'module'; + import { importSync, isDevelopingApp, macroCondition } from '@embroider/macros'; - if (macroCondition(isDevelopingApp())) { - // value will be asserted in the test - foo = 'macro' - } - `, + if (macroCondition(isDevelopingApp())) { + importSync('./styles.css'); + } + + export default class ExampleComponent extends Component { + @tracked active = false; + + flip = () => (this.active = !this.active); + + + } + `, + }, }, }); @@ -65,6 +97,7 @@ appScenarios addon.linkDependency('@babel/runtime', { baseDir: __dirname }); addon.linkDevDependency('@babel/core', { baseDir: __dirname }); addon.linkDevDependency('@rollup/plugin-babel', { baseDir: __dirname }); + addon.linkDependency('decorator-transforms', { baseDir: __dirname }); addon.linkDevDependency('rollup', { baseDir: __dirname }); project.addDevDependency(addon); @@ -75,12 +108,22 @@ appScenarios tests: { // the app is not set up with typescript 'the-test.js': ` + import { click, render } from '@ember/test-helpers'; + import { hbs } from 'ember-cli-htmlbars'; import { module, test } from 'qunit'; - import { foo } from 'v2-addon'; + import { setupRenderingTest } from 'ember-qunit'; module('v2 addon tests', function (hooks) { - test('macros ran', async function (assert) { - assert.strictEqual(foo, 'macro'); + setupRenderingTest(hooks); + + test('', async function (assert) { + await render(hbs\`\`); + + assert.dom('out').containsText('false'); + + await click('button'); + + assert.dom('out').containsText('true'); }); }); `, @@ -123,6 +166,38 @@ appScenarios test('output directories exist', async function (assert) { let { dir } = inDependency(app, 'v2-addon'); assert.strictEqual(pathExistsSync(path.join(dir, 'dist')), true, 'dist/'); + assert.strictEqual(pathExistsSync(path.join(dir, 'dist', '_app_')), true, 'dist/_app_'); + }); + + test('package.json is modified appropriately', async function (assert) { + let { dir } = inDependency(app, 'v2-addon'); + let reExports = readJsonSync(path.join(dir, 'package.json'))['ember-addon']['app-js']; + + assert.deepEqual(reExports, { + './components/demo.js': './dist/_app_/components/demo.js', + }); + }); + + test('the addon was built successfully', async function (assert) { + let { dir } = inDependency(app, 'v2-addon'); + let expectedModules = { + './dist/_app_/components/demo.js': 'export { default } from "v2-addon/components/demo";\n', + }; + + assert.strictEqual( + Object.keys(readJsonSync(path.join(dir, 'package.json'))['ember-addon']['app-js']).length, + Object.keys(expectedModules).length + ); + + for (let [pathName, moduleContents] of Object.entries(expectedModules)) { + let filePath = path.join(dir, pathName); + assert.deepEqual(pathExistsSync(filePath), true, `pathExists: ${pathName}`); + assert.strictEqual( + readFileSync(filePath, { encoding: 'utf8' }), + moduleContents, + `has correct reexport: ${pathName}` + ); + } }); }); From c63f5d52da977d4b194150411ced55b2f9f21c85 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Tue, 7 May 2024 17:38:20 -0400 Subject: [PATCH 05/10] Minimal test, pre fix --- tests/scenarios/v2-addon-type-module-test.ts | 155 ++----------------- 1 file changed, 16 insertions(+), 139 deletions(-) diff --git a/tests/scenarios/v2-addon-type-module-test.ts b/tests/scenarios/v2-addon-type-module-test.ts index bf7ebe6a2..44c59136d 100644 --- a/tests/scenarios/v2-addon-type-module-test.ts +++ b/tests/scenarios/v2-addon-type-module-test.ts @@ -1,9 +1,7 @@ -import path from 'path'; import { appScenarios, baseV2Addon } from './scenarios'; import { PreparedApp } from 'scenario-tester'; import QUnit from 'qunit'; import merge from 'lodash/merge'; -import { pathExistsSync, readJsonSync, readFileSync } from 'fs-extra'; const { module: Qmodule, test } = QUnit; @@ -13,92 +11,29 @@ appScenarios let addon = baseV2Addon(); addon.pkg.name = 'v2-addon'; addon.pkg.type = 'module'; - addon.pkg.files = ['dist']; + addon.pkg.files = ['src']; addon.pkg.exports = { - './*': './dist/*.js', + './*': './src/*.js', './addon-main.cjs': './addon-main.cjs', - // needed for our "inDependency" function defined in this test - './package.json': './package.json', - }; - addon.pkg.scripts = { - build: 'node ./node_modules/rollup/dist/bin/rollup -c ./rollup.config.mjs', }; merge(addon.files, { - 'babel.config.json': ` - { - "plugins": [ - ["babel-plugin-ember-template-compilation", { - "targetFormat": "hbs", - "transforms": [] - }], - ["module:decorator-transforms", { "runtime": { "import": "decorator-transforms/runtime" } }] - ] - } - `, - 'rollup.config.mjs': ` - import { Addon } from '@embroider/addon-dev/rollup'; - import { babel } from '@rollup/plugin-babel'; - - const addon = new Addon({ - srcDir: 'src', - destDir: 'dist', - }); - - export default { - output: addon.output(), - plugins: [ - addon.publicEntrypoints(['**/*.js']), - addon.appReexports(['components/*.js']), - addon.dependencies(), - babel({ extensions: ['.js', '.gjs', '.ts', '.gts'], babelHelpers: 'bundled' }), - addon.gjs(), - addon.hbs(), - addon.keepAssets(["**/*.css"]), - addon.clean(), - ], - }; - - `, src: { - components: { - 'styles.css': `button { font-weight: bold; color: blue; }`, - 'demo.gjs': ` - import Component from '@glimmer/component'; - import { tracked } from '@glimmer/tracking'; - import { on } from '@ember/modifier'; - - import { importSync, isDevelopingApp, macroCondition } from '@embroider/macros'; - - if (macroCondition(isDevelopingApp())) { - importSync('./styles.css'); - } - - export default class ExampleComponent extends Component { - @tracked active = false; - - flip = () => (this.active = !this.active); - - - } - `, - }, + 'side-effecting.js': `window.__secret_side_effect = 'hello';`, + /** + * NOTE: importSync shouldn't be used like this in practice, + * as it's meant for compatibility and macroCondition imports before we have + * support for top-level await. + */ + 'demo.js': ` + import { importSync } from '@embroider/macros'; + + importSync('./side-effecting.js'); + `, }, }); addon.linkDependency('@embroider/addon-shim', { baseDir: __dirname }); - addon.linkDependency('@embroider/addon-dev', { baseDir: __dirname }); - addon.linkDependency('@babel/runtime', { baseDir: __dirname }); - addon.linkDevDependency('@babel/core', { baseDir: __dirname }); - addon.linkDevDependency('@rollup/plugin-babel', { baseDir: __dirname }); - addon.linkDependency('decorator-transforms', { baseDir: __dirname }); - addon.linkDevDependency('rollup', { baseDir: __dirname }); project.addDevDependency(addon); project.linkDevDependency('ember-cli-babel', { baseDir: __dirname, resolveName: 'ember-cli-babel-8' }); @@ -108,22 +43,12 @@ appScenarios tests: { // the app is not set up with typescript 'the-test.js': ` - import { click, render } from '@ember/test-helpers'; - import { hbs } from 'ember-cli-htmlbars'; import { module, test } from 'qunit'; - import { setupRenderingTest } from 'ember-qunit'; + import 'v2-addon/demo'; module('v2 addon tests', function (hooks) { - setupRenderingTest(hooks); - - test('', async function (assert) { - await render(hbs\`\`); - - assert.dom('out').containsText('false'); - - await click('button'); - - assert.dom('out').containsText('true'); + test('macro condition runs without error', async function (assert) { + assert.strictEqual(window.__secret_side_effect, 'hello'); }); }); `, @@ -156,49 +81,6 @@ appScenarios hooks.before(async () => { app = await scenario.prepare(); - let result = await inDependency(app, 'v2-addon').execute('pnpm build'); - if (result.exitCode !== 0) { - throw new Error(result.output); - } - }); - - Qmodule('The addon', function () { - test('output directories exist', async function (assert) { - let { dir } = inDependency(app, 'v2-addon'); - assert.strictEqual(pathExistsSync(path.join(dir, 'dist')), true, 'dist/'); - assert.strictEqual(pathExistsSync(path.join(dir, 'dist', '_app_')), true, 'dist/_app_'); - }); - - test('package.json is modified appropriately', async function (assert) { - let { dir } = inDependency(app, 'v2-addon'); - let reExports = readJsonSync(path.join(dir, 'package.json'))['ember-addon']['app-js']; - - assert.deepEqual(reExports, { - './components/demo.js': './dist/_app_/components/demo.js', - }); - }); - - test('the addon was built successfully', async function (assert) { - let { dir } = inDependency(app, 'v2-addon'); - let expectedModules = { - './dist/_app_/components/demo.js': 'export { default } from "v2-addon/components/demo";\n', - }; - - assert.strictEqual( - Object.keys(readJsonSync(path.join(dir, 'package.json'))['ember-addon']['app-js']).length, - Object.keys(expectedModules).length - ); - - for (let [pathName, moduleContents] of Object.entries(expectedModules)) { - let filePath = path.join(dir, pathName); - assert.deepEqual(pathExistsSync(filePath), true, `pathExists: ${pathName}`); - assert.strictEqual( - readFileSync(filePath, { encoding: 'utf8' }), - moduleContents, - `has correct reexport: ${pathName}` - ); - } - }); }); Qmodule('Consuming app', function () { @@ -209,8 +91,3 @@ appScenarios }); }); }); - -// https://github.com/ef4/scenario-tester/issues/5 -function inDependency(app: PreparedApp, dependencyName: string): PreparedApp { - return new PreparedApp(path.dirname(require.resolve(`${dependencyName}/package.json`, { paths: [app.dir] }))); -} From c93b19c12b567f45d3e2e53cbdea1e1df2d22c7f Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Tue, 7 May 2024 17:44:47 -0400 Subject: [PATCH 06/10] lint:fix --- tests/scenarios/v2-addon-type-module-test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scenarios/v2-addon-type-module-test.ts b/tests/scenarios/v2-addon-type-module-test.ts index 44c59136d..59387ca2b 100644 --- a/tests/scenarios/v2-addon-type-module-test.ts +++ b/tests/scenarios/v2-addon-type-module-test.ts @@ -1,5 +1,5 @@ import { appScenarios, baseV2Addon } from './scenarios'; -import { PreparedApp } from 'scenario-tester'; +import type { PreparedApp } from 'scenario-tester'; import QUnit from 'qunit'; import merge from 'lodash/merge'; From 09dbe5500178aa7fd8cbd7cbfa41c6cbc818a7ce Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Tue, 7 May 2024 17:46:42 -0400 Subject: [PATCH 07/10] Reduce diff from origin/stable --- pnpm-lock.yaml | 28 ++----------------- tests/scenarios/package.json | 2 -- tests/scenarios/v2-addon-test.ts | 4 +-- .../{addon-main.cjs => addon-main.js} | 0 tests/v2-addon-template/package.json | 2 +- 5 files changed, 6 insertions(+), 30 deletions(-) rename tests/v2-addon-template/{addon-main.cjs => addon-main.js} (100%) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c2f8d67f0..5c86c0356 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1526,9 +1526,6 @@ importers: '@types/qunit': specifier: ^2.11.1 version: 2.19.10 - decorator-transforms: - specifier: ^1.0.1 - version: 1.0.1(@babel/core@7.24.5) ember-auto-import: specifier: ^2.6.3 version: 2.7.2 @@ -1665,9 +1662,6 @@ importers: ember-cli-4.4: specifier: npm:ember-cli@~4.4.0 version: /ember-cli@4.4.1(lodash@4.17.21) - ember-cli-babel-8: - specifier: npm:ember-cli-babel@^8.2.0 - version: /ember-cli-babel@8.2.0(@babel/core@7.24.5) ember-cli-beta: specifier: npm:ember-cli@beta version: /ember-cli@5.9.0-beta.1 @@ -2467,16 +2461,6 @@ packages: '@babel/core': 7.24.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.5 - /@babel/plugin-syntax-decorators@7.23.3(@babel/core@7.24.5): - resolution: {integrity: sha512-cf7Niq4/+/juY67E0PbgH0TDhLQ5J7zS8C/Q5FFx+DWyrRa9sUQdTXkjqKu8zGvuqr7vw1muKiukseihU+PJDA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.5(supports-color@8.1.1) - '@babel/helper-plugin-utils': 7.24.5 - dev: false - /@babel/plugin-syntax-decorators@7.24.1(@babel/core@7.24.5): resolution: {integrity: sha512-05RJdO/cCrtVWuAaSn1tS3bH8jbsJa/Y1uD186u6J4C/1mnHFxseeuWpsqr9anvo7TUulev7tm7GDwRV+VuhDw==} engines: {node: '>=6.9.0'} @@ -7241,6 +7225,9 @@ packages: /ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependenciesMeta: + ajv: + optional: true dependencies: ajv: 8.13.0 @@ -10427,15 +10414,6 @@ packages: mimic-response: 1.0.1 dev: true - /decorator-transforms@1.0.1(@babel/core@7.24.5): - resolution: {integrity: sha512-ZOaiw4tqiyhtqiMKCNzjS+nGsYPZltToqRAFc5rOUcc4u8d7MTlgelw1qXfL6ieg2l6xZcz6lTZ5M94Ohnk2xA==} - dependencies: - '@babel/plugin-syntax-decorators': 7.23.3(@babel/core@7.24.5) - babel-import-util: 2.1.1 - transitivePeerDependencies: - - '@babel/core' - dev: false - /dedent@1.5.3: resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} peerDependencies: diff --git a/tests/scenarios/package.json b/tests/scenarios/package.json index 38108851f..e30a5538e 100644 --- a/tests/scenarios/package.json +++ b/tests/scenarios/package.json @@ -10,7 +10,6 @@ "@embroider/test-support": "workspace:*", "@embroider/webpack": "workspace:*", "@types/qunit": "^2.11.1", - "decorator-transforms": "^1.0.1", "ember-auto-import": "^2.6.3", "fastboot": "^4.1.1", "fs-extra": "^10.0.0", @@ -68,7 +67,6 @@ "ember-cli-beta": "npm:ember-cli@beta", "ember-cli-fastboot": "^4.1.1", "ember-cli-latest": "npm:ember-cli@latest", - "ember-cli-babel-8": "npm:ember-cli-babel@^8.2.0", "ember-composable-helpers": "^4.4.1", "ember-data": "~3.28.0", "ember-data-4.4": "npm:ember-data@~4.4.0", diff --git a/tests/scenarios/v2-addon-test.ts b/tests/scenarios/v2-addon-test.ts index f67fe825d..4c18982cb 100644 --- a/tests/scenarios/v2-addon-test.ts +++ b/tests/scenarios/v2-addon-test.ts @@ -32,9 +32,9 @@ appScenarios 'example-component.css': '/* not empty */ h1 { color: red }', }, 'import-from-npm.js': ` - export default async function() { + export default async function() { let { message } = await import('third-party'); - return message() + return message() } `, }); diff --git a/tests/v2-addon-template/addon-main.cjs b/tests/v2-addon-template/addon-main.js similarity index 100% rename from tests/v2-addon-template/addon-main.cjs rename to tests/v2-addon-template/addon-main.js diff --git a/tests/v2-addon-template/package.json b/tests/v2-addon-template/package.json index c87ddcc83..8fe72de7d 100644 --- a/tests/v2-addon-template/package.json +++ b/tests/v2-addon-template/package.json @@ -12,7 +12,7 @@ "type": "addon", "version": 2, "app-js": {}, - "main": "addon-main.cjs" + "main": "addon-main.js" }, "exports": { "./*": "./*" From 3b16269e585d7ff8b9bf4297bee914de02292198 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Tue, 7 May 2024 18:06:44 -0400 Subject: [PATCH 08/10] The fix --- packages/macros/src/babel/macros-babel-plugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/macros/src/babel/macros-babel-plugin.ts b/packages/macros/src/babel/macros-babel-plugin.ts index f4494f740..fae17c860 100644 --- a/packages/macros/src/babel/macros-babel-plugin.ts +++ b/packages/macros/src/babel/macros-babel-plugin.ts @@ -135,7 +135,7 @@ export default function main(context: typeof Babel): unknown { let r = t.identifier('require'); state.generatedRequires.add(r); path.replaceWith( - t.callExpression(state.importUtil.import(path, state.pathToOurAddon('es-compat2'), 'default', 'esc'), [ + t.callExpression(state.importUtil.import(path, state.pathToOurAddon('es-compat2.js'), 'default', 'esc'), [ t.callExpression(r, path.node.arguments), ]) ); From abdf30cea77f638d65a397bb381cab671065e215 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Tue, 7 May 2024 18:13:52 -0400 Subject: [PATCH 09/10] addon-main MUST be cjs --- tests/scenarios/v2-addon-type-module-test.ts | 1 - tests/v2-addon-template/{addon-main.js => addon-main.cjs} | 0 tests/v2-addon-template/package.json | 2 +- 3 files changed, 1 insertion(+), 2 deletions(-) rename tests/v2-addon-template/{addon-main.js => addon-main.cjs} (100%) diff --git a/tests/scenarios/v2-addon-type-module-test.ts b/tests/scenarios/v2-addon-type-module-test.ts index 59387ca2b..d9d83fef5 100644 --- a/tests/scenarios/v2-addon-type-module-test.ts +++ b/tests/scenarios/v2-addon-type-module-test.ts @@ -36,7 +36,6 @@ appScenarios addon.linkDependency('@embroider/addon-shim', { baseDir: __dirname }); project.addDevDependency(addon); - project.linkDevDependency('ember-cli-babel', { baseDir: __dirname, resolveName: 'ember-cli-babel-8' }); project.linkDevDependency('@embroider/macros', { baseDir: __dirname }); merge(project.files, { diff --git a/tests/v2-addon-template/addon-main.js b/tests/v2-addon-template/addon-main.cjs similarity index 100% rename from tests/v2-addon-template/addon-main.js rename to tests/v2-addon-template/addon-main.cjs diff --git a/tests/v2-addon-template/package.json b/tests/v2-addon-template/package.json index 8fe72de7d..c87ddcc83 100644 --- a/tests/v2-addon-template/package.json +++ b/tests/v2-addon-template/package.json @@ -12,7 +12,7 @@ "type": "addon", "version": 2, "app-js": {}, - "main": "addon-main.js" + "main": "addon-main.cjs" }, "exports": { "./*": "./*" From 1e335442dac820c82da3508a7c41bdeef270a8ea Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Wed, 8 May 2024 16:59:44 -0400 Subject: [PATCH 10/10] use maybeEmbroider --- tests/scenarios/v2-addon-type-module-test.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/scenarios/v2-addon-type-module-test.ts b/tests/scenarios/v2-addon-type-module-test.ts index d9d83fef5..b12ae9cc3 100644 --- a/tests/scenarios/v2-addon-type-module-test.ts +++ b/tests/scenarios/v2-addon-type-module-test.ts @@ -63,11 +63,12 @@ appScenarios const { compatBuild, recommendedOptions } = require('@embroider/compat'); - const Webpack = require('@embroider/webpack').Webpack; - return compatBuild(app, Webpack, { - ...recommendedOptions.optimized, + const { maybeEmbroider } = require('@embroider/test-setup'); + return maybeEmbroider(app, { skipBabel: [ - { package: 'qunit' }, + { + package: 'qunit', + }, ], }); };