From bbf7f02265ec902005c5c5a5c44cfe09b80be4db Mon Sep 17 00:00:00 2001 From: Marine Dunstetter Date: Fri, 24 May 2024 14:38:51 +0200 Subject: [PATCH 1/6] feat(new config module): stop rewriting the config/environment in the rewritten-app --- packages/compat/src/compat-app.ts | 10 +------ packages/compat/src/v1-config.ts | 49 +------------------------------ 2 files changed, 2 insertions(+), 57 deletions(-) diff --git a/packages/compat/src/compat-app.ts b/packages/compat/src/compat-app.ts index 73c7d6579..b1731223f 100644 --- a/packages/compat/src/compat-app.ts +++ b/packages/compat/src/compat-app.ts @@ -11,7 +11,7 @@ import mergeTrees from 'broccoli-merge-trees'; import { WatchedDir } from 'broccoli-source'; import resolve from 'resolve'; import ContentForConfig from './content-for-config'; -import { V1Config, WriteV1Config } from './v1-config'; +import { V1Config } from './v1-config'; import { WriteV1AppBoot, ReadV1AppBoot } from './v1-appboot'; import type { AddonMeta, EmberAppInstance, OutputFileToInputFileMap, PackageInfo } from '@embroider/core'; import { writeJSONSync, ensureDirSync, copySync, pathExistsSync, existsSync, writeFileSync } from 'fs-extra'; @@ -690,13 +690,6 @@ export default class CompatApp { let appTree = this.appTree; let testsTree = this.testsTree; let lintTree = this.lintTree; - let config = new WriteV1Config(this.config, this.storeConfigInMeta, this.testConfig); - let patterns = this.configReplacePatterns; - let configReplaced = new this.configReplace(config, this.configTree, { - configPath: join('environments', `${this.legacyEmberAppInstance.env}.json`), - files: ['config/environment.js'], - patterns, - }); let trees: BroccoliNode[] = []; trees.push(appTree); @@ -704,7 +697,6 @@ export default class CompatApp { new SynthesizeTemplateOnlyComponents(appTree, { allowedPaths: ['components'], templateExtensions: ['.hbs'] }) ); - trees.push(configReplaced); if (testsTree) { trees.push(testsTree); } diff --git a/packages/compat/src/v1-config.ts b/packages/compat/src/v1-config.ts index 43344a66e..7e554bee9 100644 --- a/packages/compat/src/v1-config.ts +++ b/packages/compat/src/v1-config.ts @@ -1,7 +1,7 @@ import Plugin from 'broccoli-plugin'; import type { Node } from 'broccoli-node-api'; import { join } from 'path'; -import { readFileSync, outputFileSync } from 'fs-extra'; +import { readFileSync } from 'fs-extra'; export interface ConfigContents { modulePrefix: string; @@ -26,50 +26,3 @@ export class V1Config extends Plugin { return this.lastConfig; } } - -export class WriteV1Config extends Plugin { - private lastContents: string | undefined; - constructor(private inputTree: V1Config, private storeConfigInMeta: boolean, private testInputTree?: V1Config) { - super([inputTree, testInputTree as V1Config].filter(Boolean), { - persistentOutput: true, - needsCache: false, - }); - } - build() { - let filename = join(this.outputPath, 'config/environment.js'); - let contents; - if (this.storeConfigInMeta) { - contents = metaLoader(); - } else { - if (this.testInputTree) { - contents = ` - import { isTesting } from '@embroider/macros'; - let env; - if (isTesting()) { - env = ${JSON.stringify(this.testInputTree.readConfig())}; - } else { - env = ${JSON.stringify(this.inputTree.readConfig())}; - } - export default env; - `; - } else { - contents = `export default ${JSON.stringify(this.inputTree.readConfig())};`; - } - } - if (!this.lastContents || this.lastContents !== contents) { - outputFileSync(filename, contents); - } - this.lastContents = contents; - } -} - -function metaLoader() { - // Supporting config content as JS Module. - // Wrapping the content with immediate invoked function as - // replaced content for config-module was meant to support AMD module. - return ` - export default (function() { - {{content-for 'config-module'}} - })().default; - `; -} From 8beb58534a3bdeb8dbe7700c14c55249a5fefbb5 Mon Sep 17 00:00:00 2001 From: Marine Dunstetter Date: Wed, 29 May 2024 14:23:45 +0200 Subject: [PATCH 2/6] test(new config module): write the config that used to be generated for canary-macro-sample-addon scenario in the addon-template --- .../tests/dummy/app/config/environment.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 tests/addon-template/tests/dummy/app/config/environment.js diff --git a/tests/addon-template/tests/dummy/app/config/environment.js b/tests/addon-template/tests/dummy/app/config/environment.js new file mode 100644 index 000000000..21fe193fe --- /dev/null +++ b/tests/addon-template/tests/dummy/app/config/environment.js @@ -0,0 +1,19 @@ +// from https://github.com/ember-cli/ember-cli/blob/master/lib/broccoli/app-config-from-meta.js +export default (function() { + let config = function() { + let prefix = 'dummy'; + let metaName = prefix + '/config/environment'; + try { + let rawConfig = document.querySelector('meta[name="' + metaName + '"]').getAttribute('content'); + let config = JSON.parse(decodeURIComponent(rawConfig)); + let exports = { 'default': config }; + Object.defineProperty(exports, '__esModule', { value: true }); + return exports; + } + catch(err) { + throw new Error('Could not read config from meta tag with name "' + metaName + '".'); + } + }() + config.default.APP.fromConfigModule = 'hello new world'; + return config; +})().default; \ No newline at end of file From 6972b8e13a5d8eb449600d11491692abdc157817 Mon Sep 17 00:00:00 2001 From: Marine Dunstetter Date: Wed, 29 May 2024 18:49:10 +0200 Subject: [PATCH 3/6] feat(new config module): create a config-meta-loader package to read the config in the document --- .eslintignore | 2 ++ .eslintrc.js | 2 +- .prettierignore | 2 ++ package.json | 8 +++--- packages/config-meta-loader/.gitignore | 8 ++++++ packages/config-meta-loader/package.json | 28 +++++++++++++++++++ packages/config-meta-loader/src/index.ts | 11 ++++++++ packages/config-meta-loader/tsconfig.json | 22 +++++++++++++++ pnpm-lock.yaml | 9 ++++++ tests/addon-template/package.json | 1 + .../tests/dummy/app/config/environment.js | 2 +- tsconfig.json | 4 +++ 12 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 packages/config-meta-loader/.gitignore create mode 100644 packages/config-meta-loader/package.json create mode 100644 packages/config-meta-loader/src/index.ts create mode 100644 packages/config-meta-loader/tsconfig.json diff --git a/.eslintignore b/.eslintignore index 0d016f6ef..c4f71f068 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,6 +4,8 @@ /packages/shared-internals/**/*.d.ts /packages/compat/**/*.js /packages/compat/**/*.d.ts +/packages/config-meta-loader/**/*.js +/packages/config-meta-loader/**/*.d.ts /packages/macros/**/*.js /packages/macros/**/*.d.ts /packages/util/src/**/*.js diff --git a/.eslintrc.js b/.eslintrc.js index 0dd96cdf4..d90703fee 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -24,7 +24,7 @@ module.exports = { { files: ['**/*.ts'], parserOptions: { - project: './tsconfig.json', + project: true, }, rules: { '@typescript-eslint/consistent-type-imports': 'error', diff --git a/.prettierignore b/.prettierignore index 36849b71a..d12519ef0 100644 --- a/.prettierignore +++ b/.prettierignore @@ -13,6 +13,8 @@ /packages/shared-internals/**/*.d.ts /packages/compat/**/*.js /packages/compat/**/*.d.ts +/packages/config-meta-loader/**/*.js +/packages/config-meta-loader/**/*.d.ts /packages/macros/**/*.js /packages/macros/**/*.d.ts /packages/util/src/**/*.js diff --git a/package.json b/package.json index 82b424f4e..2cee911a2 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,8 @@ }, "scripts": { "clean": "git clean -x -f", - "compile": "tsc", - "dev": "tsc --watch", + "compile": "tsc -b", + "dev": "tsc -b --watch", "lint": "concurrently 'npm:lint:*(!fix)' --names 'lint:'", "lint:fix": "concurrently 'npm:lint:*:fix' --names 'fix:'", "lint:eslint": "eslint . --cache --report-unused-disable-directives", @@ -15,7 +15,7 @@ "lint:prettier": "prettier . -c", "lint:prettier:fix": "prettier . -w", "lint:router-types": "cd packages/router && pnpm lint:types", - "prepare": "tsc && pnpm build-v2-addons", + "prepare": "tsc -b && pnpm build-v2-addons", "build-v2-addons": "concurrently 'pnpm:build-v2-addons:*'", "build-v2-addons:router": "cd packages/router && pnpm build", "test": "cd tests/scenarios && pnpm test" @@ -71,4 +71,4 @@ }, "wildcardLabel": "unlabeled" } -} +} \ No newline at end of file diff --git a/packages/config-meta-loader/.gitignore b/packages/config-meta-loader/.gitignore new file mode 100644 index 000000000..575705668 --- /dev/null +++ b/packages/config-meta-loader/.gitignore @@ -0,0 +1,8 @@ +/node_modules +/src/**/*.js +/src/**/*.d.ts +/src/**/*.map +/*/tests/**/*.js +/*/tests/**/*.d.ts +/*/tests/**/*.map +*.tsbuildinfo \ No newline at end of file diff --git a/packages/config-meta-loader/package.json b/packages/config-meta-loader/package.json new file mode 100644 index 000000000..fc5446037 --- /dev/null +++ b/packages/config-meta-loader/package.json @@ -0,0 +1,28 @@ +{ + "name": "@embroider/config-meta-loader", + "version": "1.0.0", + "private": false, + "type": "module", + "description": "Read the config meta in the document. Inspired by ember-cli/lib/broccoli/app-config-from-meta.js", + "repository": { + "type": "git", + "url": "https://github.com/embroider-build/embroider.git", + "directory": "packages/config-meta-loader" + }, + "license": "MIT", + "author": "Marine Dunstetter", + "main": "src/index.js", + "files": [ + "src/**/*.js", + "src/**/*.d.ts", + "src/**/*.js.map" + ], + "scripts": {}, + "dependencies": {}, + "devDependencies": { + "typescript": "^5.4.5" + }, + "engines": { + "node": "12.* || 14.* || >= 16" + } +} diff --git a/packages/config-meta-loader/src/index.ts b/packages/config-meta-loader/src/index.ts new file mode 100644 index 000000000..bc48a4c1f --- /dev/null +++ b/packages/config-meta-loader/src/index.ts @@ -0,0 +1,11 @@ +// from https://github.com/ember-cli/ember-cli/blob/master/lib/broccoli/app-config-from-meta.js +export default function loadConfigFromMeta(prefix: string): any { + let metaName = `${prefix}/config/environment`; + try { + let rawConfig = document.querySelector(`meta[name="${metaName}"]`)!.getAttribute('content') ?? '{}'; + let config = JSON.parse(decodeURIComponent(rawConfig)); + return config; + } catch (err) { + return `Could not read config from meta tag with name "${metaName}".`; + } +} diff --git a/packages/config-meta-loader/tsconfig.json b/packages/config-meta-loader/tsconfig.json new file mode 100644 index 000000000..f18900345 --- /dev/null +++ b/packages/config-meta-loader/tsconfig.json @@ -0,0 +1,22 @@ +{ + "include": [ + "src/**/*.ts", + ], + "compilerOptions": { + "composite": true, + "target": "es2019", + "module": "ESNext", + "declaration": true, + "typeRoots": ["types", "node_modules/@types"], + "esModuleInterop": false, + "noUnusedLocals": true, + "noUnusedParameters": true, + "sourceMap": true, + "inlineSources": true, + "experimentalDecorators": true, + "allowUnreachableCode": false, + "strict": true, + "skipLibCheck": true, + "useUnknownInCatchVariables": false, + }, +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a8d0794dd..bb1ed7c42 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -367,6 +367,12 @@ importers: specifier: ^5.4.5 version: 5.4.5 + packages/config-meta-loader: + devDependencies: + typescript: + specifier: ^5.4.5 + version: 5.4.5 + packages/core: dependencies: '@babel/core': @@ -1310,6 +1316,9 @@ importers: tests/addon-template: dependencies: + '@embroider/config-meta-loader': + specifier: workspace:* + version: link:../../packages/config-meta-loader ember-cli-babel: specifier: ^7.26.11 version: 7.26.11 diff --git a/tests/addon-template/package.json b/tests/addon-template/package.json index f7d8b274c..2c813289d 100644 --- a/tests/addon-template/package.json +++ b/tests/addon-template/package.json @@ -27,6 +27,7 @@ "test:ember-compatibility": "ember try:each" }, "dependencies": { + "@embroider/config-meta-loader": "workspace:*", "ember-cli-babel": "^7.26.11", "ember-cli-htmlbars": "^6.1.0" }, diff --git a/tests/addon-template/tests/dummy/app/config/environment.js b/tests/addon-template/tests/dummy/app/config/environment.js index 21fe193fe..341cf533f 100644 --- a/tests/addon-template/tests/dummy/app/config/environment.js +++ b/tests/addon-template/tests/dummy/app/config/environment.js @@ -16,4 +16,4 @@ export default (function() { }() config.default.APP.fromConfigModule = 'hello new world'; return config; -})().default; \ No newline at end of file +})().default; diff --git a/tsconfig.json b/tsconfig.json index 382d5af75..2ba1b895e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -32,6 +32,10 @@ "test-packages/*/node_modules", "tmp", "tests/scenarios/output", + "packages/config-meta-loader/src", "packages/router/src" + ], + "references": [ + { "path": "packages/config-meta-loader" } ] } From 55ac7745cdca4c56a4531f45b6785c5953713a6d Mon Sep 17 00:00:00 2001 From: Marine Dunstetter Date: Thu, 30 May 2024 13:10:02 +0200 Subject: [PATCH 4/6] test(new config module): write the new config format for the different test templates --- pnpm-lock.yaml | 12 ++++++++++ .../tests/dummy/app/config/environment.js | 23 ++++--------------- tests/app-template/app/config/environment.js | 3 +++ tests/app-template/package.json | 1 + .../app/config/environment.ts | 3 +++ tests/ts-app-template-classic/package.json | 1 + .../ts-app-template/app/config/environment.ts | 3 +++ tests/ts-app-template/package.json | 1 + 8 files changed, 28 insertions(+), 19 deletions(-) create mode 100644 tests/app-template/app/config/environment.js create mode 100644 tests/ts-app-template-classic/app/config/environment.ts create mode 100644 tests/ts-app-template/app/config/environment.ts diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bb1ed7c42..078400094 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1473,6 +1473,9 @@ importers: '@embroider/compat': specifier: workspace:* version: link:../../packages/compat + '@embroider/config-meta-loader': + specifier: workspace:* + version: link:../../packages/config-meta-loader '@embroider/core': specifier: workspace:* version: link:../../packages/core @@ -1857,6 +1860,9 @@ importers: '@embroider/compat': specifier: workspace:* version: link:../../packages/compat + '@embroider/config-meta-loader': + specifier: workspace:* + version: link:../../packages/config-meta-loader '@embroider/core': specifier: workspace:* version: link:../../packages/core @@ -2016,6 +2022,9 @@ importers: '@embroider/compat': specifier: workspace:* version: link:../../packages/compat + '@embroider/config-meta-loader': + specifier: workspace:* + version: link:../../packages/config-meta-loader '@embroider/core': specifier: workspace:* version: link:../../packages/core @@ -8351,6 +8360,9 @@ packages: /ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependenciesMeta: + ajv: + optional: true dependencies: ajv: 8.13.0 diff --git a/tests/addon-template/tests/dummy/app/config/environment.js b/tests/addon-template/tests/dummy/app/config/environment.js index 341cf533f..f7fb3426f 100644 --- a/tests/addon-template/tests/dummy/app/config/environment.js +++ b/tests/addon-template/tests/dummy/app/config/environment.js @@ -1,19 +1,4 @@ -// from https://github.com/ember-cli/ember-cli/blob/master/lib/broccoli/app-config-from-meta.js -export default (function() { - let config = function() { - let prefix = 'dummy'; - let metaName = prefix + '/config/environment'; - try { - let rawConfig = document.querySelector('meta[name="' + metaName + '"]').getAttribute('content'); - let config = JSON.parse(decodeURIComponent(rawConfig)); - let exports = { 'default': config }; - Object.defineProperty(exports, '__esModule', { value: true }); - return exports; - } - catch(err) { - throw new Error('Could not read config from meta tag with name "' + metaName + '".'); - } - }() - config.default.APP.fromConfigModule = 'hello new world'; - return config; -})().default; +import loadConfigFromMeta from '@embroider/config-meta-loader'; + +export default loadConfigFromMeta('dummy'); +// config.APP.fromConfigModule = 'hello new world'; diff --git a/tests/app-template/app/config/environment.js b/tests/app-template/app/config/environment.js new file mode 100644 index 000000000..7f4085e51 --- /dev/null +++ b/tests/app-template/app/config/environment.js @@ -0,0 +1,3 @@ +import loadConfigFromMeta from '@embroider/config-meta-loader'; + +export default loadConfigFromMeta('app-template'); diff --git a/tests/app-template/package.json b/tests/app-template/package.json index 24c2391f0..82d970d53 100644 --- a/tests/app-template/package.json +++ b/tests/app-template/package.json @@ -32,6 +32,7 @@ "@ember/string": "^3.1.1", "@ember/test-helpers": "^3.0.3", "@embroider/compat": "workspace:*", + "@embroider/config-meta-loader": "workspace:*", "@embroider/core": "workspace:*", "@embroider/router": "workspace:*", "@embroider/test-setup": "workspace:*", diff --git a/tests/ts-app-template-classic/app/config/environment.ts b/tests/ts-app-template-classic/app/config/environment.ts new file mode 100644 index 000000000..061966012 --- /dev/null +++ b/tests/ts-app-template-classic/app/config/environment.ts @@ -0,0 +1,3 @@ +import loadConfigFromMeta from '@embroider/config-meta-loader'; + +export default loadConfigFromMeta('ts-app-template'); diff --git a/tests/ts-app-template-classic/package.json b/tests/ts-app-template-classic/package.json index ff435e127..81a5974f5 100644 --- a/tests/ts-app-template-classic/package.json +++ b/tests/ts-app-template-classic/package.json @@ -32,6 +32,7 @@ "@ember/string": "^3.1.1", "@ember/test-helpers": "^3.2.0", "@embroider/compat": "workspace:*", + "@embroider/config-meta-loader": "workspace:*", "@embroider/core": "workspace:*", "@embroider/router": "workspace:*", "@embroider/test-setup": "workspace:*", diff --git a/tests/ts-app-template/app/config/environment.ts b/tests/ts-app-template/app/config/environment.ts new file mode 100644 index 000000000..061966012 --- /dev/null +++ b/tests/ts-app-template/app/config/environment.ts @@ -0,0 +1,3 @@ +import loadConfigFromMeta from '@embroider/config-meta-loader'; + +export default loadConfigFromMeta('ts-app-template'); diff --git a/tests/ts-app-template/package.json b/tests/ts-app-template/package.json index ff435e127..81a5974f5 100644 --- a/tests/ts-app-template/package.json +++ b/tests/ts-app-template/package.json @@ -32,6 +32,7 @@ "@ember/string": "^3.1.1", "@ember/test-helpers": "^3.2.0", "@embroider/compat": "workspace:*", + "@embroider/config-meta-loader": "workspace:*", "@embroider/core": "workspace:*", "@embroider/router": "workspace:*", "@embroider/test-setup": "workspace:*", From fd7360245c8ba4b80980ea6ef94a031542297054 Mon Sep 17 00:00:00 2001 From: Marine Dunstetter Date: Thu, 30 May 2024 15:02:09 +0200 Subject: [PATCH 5/6] test(new config module): maintain the macro-sample-addon scenario by moving the update of the config on fixture side --- tests/addon-template/tests/dummy/app/config/environment.js | 1 - .../tests/dummy/app/config/environment.js | 6 ++++++ tests/scenarios/macro-test.ts | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/macro-sample-addon/tests/dummy/app/config/environment.js diff --git a/tests/addon-template/tests/dummy/app/config/environment.js b/tests/addon-template/tests/dummy/app/config/environment.js index f7fb3426f..d43bbea4b 100644 --- a/tests/addon-template/tests/dummy/app/config/environment.js +++ b/tests/addon-template/tests/dummy/app/config/environment.js @@ -1,4 +1,3 @@ import loadConfigFromMeta from '@embroider/config-meta-loader'; export default loadConfigFromMeta('dummy'); -// config.APP.fromConfigModule = 'hello new world'; diff --git a/tests/fixtures/macro-sample-addon/tests/dummy/app/config/environment.js b/tests/fixtures/macro-sample-addon/tests/dummy/app/config/environment.js new file mode 100644 index 000000000..5757c9748 --- /dev/null +++ b/tests/fixtures/macro-sample-addon/tests/dummy/app/config/environment.js @@ -0,0 +1,6 @@ +import loadConfigFromMeta from '@embroider/config-meta-loader'; + +let config = loadConfigFromMeta('dummy'); +config.APP.fromConfigModule = 'hello new world'; + +export default config; diff --git a/tests/scenarios/macro-test.ts b/tests/scenarios/macro-test.ts index 98e8ca2a7..5b2c87369 100644 --- a/tests/scenarios/macro-test.ts +++ b/tests/scenarios/macro-test.ts @@ -213,6 +213,9 @@ function dummyAppScenarioSetup(project: Project) { this._super.included.apply(this, arguments); }, contentFor(type, config, contents) { + // This if block is used only by macro-sample-addon-classic, which does not build with Embroider. + // When building with Embroider, the responsibility for the config is moved to the app. + // Therefore, macro-sample-addon scenario defines 'fromConfigModule' differently using fixtures. if (type === 'config-module') { const originalContents = contents.join(''); contents.splice(0, contents.length); From 3c814acd506136bbd7ca5cd3c5b2e7c924fe76e6 Mon Sep 17 00:00:00 2001 From: Marine Dunstetter Date: Fri, 31 May 2024 09:43:46 +0200 Subject: [PATCH 6/6] test(new config module): skip canary-app-config-environment scenario while storeConfigInMeta is broken --- tests/scenarios/app-config-environment-test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/scenarios/app-config-environment-test.ts b/tests/scenarios/app-config-environment-test.ts index 73a7a733c..67a7d47c4 100644 --- a/tests/scenarios/app-config-environment-test.ts +++ b/tests/scenarios/app-config-environment-test.ts @@ -67,6 +67,10 @@ appScenarios }, }); }) + // PR https://github.com/embroider-build/embroider/pull/1953 breaks !storeConfigInMeta feature + // because the new format to retrieve the environment always reads the meta in the document. + // TODO: reactivate this test once !storeConfigInMeta is reimplemented for the new config format. + .skip('canary-app-config-environment') .forEachScenario(scenario => { Qmodule(scenario.name, function (hooks) { let app: PreparedApp;