Skip to content

Commit

Permalink
feat(new app-boot): implement an error message to help moving custom …
Browse files Browse the repository at this point in the history
…app-boot
  • Loading branch information
BlueCutOfficial committed Jun 13, 2024
1 parent 60779b4 commit 08e33e7
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 3 deletions.
41 changes: 39 additions & 2 deletions packages/compat/src/compat-app-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -482,10 +482,14 @@ export class CompatAppBuilder {
writeFileSync(join(this.root, 'package.json'), JSON.stringify(pkg, null, 2), 'utf8');

let resolverConfig = this.resolverConfig(appFiles);
let config = this.configTree.readConfig();
let contentForConfig = this.contentForTree.readContents();

this.addResolverConfig(resolverConfig);
this.addContentForConfig(this.contentForTree.readContents());
this.addEmberEnvConfig(this.configTree.readConfig().EmberENV);
this.addContentForConfig(contentForConfig);
this.addEmberEnvConfig(config.EmberENV);
this.addAppBoot(this.compatApp.appBoot.readAppBoot());
this.outputAppBootError(config.modulePrefix, config.APP, contentForConfig);
let babelConfig = await this.babelConfig(resolverConfig);
this.addBabelConfig(babelConfig);
this.addMacrosConfig(this.compatApp.macrosConfig.babelPluginConfig()[0]);
Expand Down Expand Up @@ -601,6 +605,39 @@ export class CompatAppBuilder {
private addAppBoot(appBoot?: string) {
writeFileSync(join(locateEmbroiderWorkingDir(this.compatApp.root), 'ember-app-boot.js'), appBoot ?? '');
}

// Classic addons providing custom content-for "app-boot" is no longer supported.
// The purpose of this error message is to help developers to move the classic addons code.
// Developers can deactivate it with useAddonAppBoot build option.
private outputAppBootError(modulePrefix: string, appConfig: any, contentForConfig: any) {
if (!this.compatApp.options.useAddonAppBoot) {
return;
}

// This is the default script provided by
// https://github.com/ember-cli/ember-cli/blob/master/lib/utilities/ember-app-utils.js#L103
const defaultAppBoot = `
if (!runningTests) {
require("${modulePrefix}/app")["default"].create(${JSON.stringify(appConfig || {})});
}
`.replace(/\s/g, '');

const appBoot = contentForConfig['/index.html']['app-boot'];
const diff = appBoot.replace(/\s/g, '').replace(defaultAppBoot, '');

if (diff.length) {
throw new Error(`
Your app uses at least one classic addon that provides content-for 'app-boot'. This is no longer supported.
With Embroider, you have full control over the app-boot script, so classic addons no longer need to modify it under the hood.
The following code is used for your app boot:
${appBoot}
1. If you want to keep the same behavior, copy and paste it to your /app/app-boot.js:
2. Once /app/app-boot.js has the content you need, remove the present error by setting "useAddonAppBoot" to false in the build options.
`);
}
}
}

function defaultAddonPackageRules(): PackageRules[] {
Expand Down
7 changes: 7 additions & 0 deletions packages/compat/src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ export default interface Options extends CoreOptions {
// 'body-footer', 'test-body-footer'. You need to use this config only to extend
// this list.
availableContentForTypes?: string[];

// Allows you to cancel the warning that at least one classic addon provides
// content-for 'app-boot'. This warning brings awareness for developers
// switching to Embroider, but is no longer necessary once content-for
// 'app-boot' code has been properly moved to the app-side.
useAddonAppBoot?: boolean;
}

const defaults = Object.assign(coreWithDefaults(), {
Expand All @@ -114,6 +120,7 @@ const defaults = Object.assign(coreWithDefaults(), {
packageRules: [],
allowUnsafeDynamicComponents: false,
availableContentForTypes: [],
useAddonAppBoot: true,
});

export function optionsWithDefaults(options?: Options): Required<Options> {
Expand Down
1 change: 1 addition & 0 deletions tests/fixtures/macro-sample-addon/ember-cli-build.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module.exports = function(defaults) {
*/

return maybeEmbroider(app, {
useAddonAppBoot: false,
skipBabel: [
{
package: 'qunit',
Expand Down
4 changes: 3 additions & 1 deletion tests/fixtures/macro-test/ember-cli-build.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,7 @@ module.exports = function (defaults) {
app.import('vendor/prepend/four.js', { prepend: true });
app.import('vendor/prepend/order.js', { prepend: true });

return maybeEmbroider(app);
return maybeEmbroider(app, {
useAddonAppBoot: false,
});
};
36 changes: 36 additions & 0 deletions tests/scenarios/macro-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,3 +285,39 @@ dummyAppScenarios
});
});
});

dummyAppScenarios
.map('macro-sample-addon-useAddonAppBoot', project => {
dummyAppScenarioSetup(project);
project.mergeFiles({
'ember-cli-build.js': `
'use strict';
const EmberAddon = require('ember-cli/lib/broccoli/ember-addon');
const { maybeEmbroider } = require('@embroider/test-setup');
module.exports = function(defaults) {
let app = new EmberAddon(defaults, {});
return maybeEmbroider(app, {
useAddonAppBoot: true,
});
};
`,
});
})
.forEachScenario(scenario => {
Qmodule(scenario.name, function (hooks) {
let addon: PreparedApp;

hooks.before(async () => {
addon = await scenario.prepare();
});

test(`pnpm test`, async function (assert) {
let result = await addon.execute('pnpm test');
assert.equal(result.exitCode, 1, 'tests exit with errors');
assert.true(
result.output.includes(`Your app uses at least one classic addon that provides content-for 'app-boot'.`),
'the output contains the error message about migrating custom app-boot code'
);
});
});
});

0 comments on commit 08e33e7

Please sign in to comment.