diff --git a/.gitignore b/.gitignore index 2ccbe465..f2c0271d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /node_modules/ +/my-app/ diff --git a/README.md b/README.md index cf8f804a..1fe9d061 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,46 @@ If you have an existing app that you would like to upgrade to use Vite consider ``` pnpm dlx ember-cli@latest new my-app-name -b @ember/app-blueprint --pnpm ``` + +## Options + +### `--no-compat` + +``` +pnpm dlx ember-cli@latest new my-app-name \ + --blueprint @ember/app-blueprint@alpha \ + --pnpm \ + --no-compat +``` + +Does the following: +- enables `type=module` in package.json (required for vite-ssr, and many ESM tools) +- makes the build and boot _MUCH FASTER_ + (in large apps, this can have your app's boot be up to 1 minute faster) +- removes `@embroider/compat` + - removes support for: + - hbs (both for component files, and testing) + - content-for (in the HTML files) + - v1 addons + - node-land config/environment.js +- removes `ember-cli` + - ember-cli brings in a ton of old dependencies, so removing it makes installs much faster + - downside though is that you no longer have scaffolding (`ember g`) -- however, you could use `pnpm dlx ember-cli g ...` (or `npx ember-cli g`) + +### `--minimal` + +``` +pnpm dlx ember-cli@latest new my-app-name \ + --blueprint @ember/app-blueprint@alpha \ + --pnpm \ + --minimal +``` + +Does the following +- everything listed under `--no-compat` +- Removes all linting, formatting, and testing support + - leaves you with a minimal app that you can use for demos, and PRing to other repositories that have multi-framework support (and probably use other testing tools for that multi-framework support) +- different defaults: + - warp-drive becomes _opt-in_ (pass `--warp-drive` if you want it -- normally requires `--no-warp-drive` to remove) + - ember-welcome-page becomes _opt-in_ (normally requires `--no-welcome` to remove) + diff --git a/conditional-files/minimal/app/templates/application.gts b/conditional-files/minimal/app/templates/application.gts new file mode 100644 index 00000000..dca7d7b7 --- /dev/null +++ b/conditional-files/minimal/app/templates/application.gts @@ -0,0 +1,7 @@ + + diff --git a/conditional-files/no-compat/_js_babel.config.mjs b/conditional-files/no-compat/_js_babel.config.mjs new file mode 100644 index 00000000..bb5b946c --- /dev/null +++ b/conditional-files/no-compat/_js_babel.config.mjs @@ -0,0 +1,38 @@ +import { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { buildMacros } from '@embroider/macros/babel'; + +const macros = buildMacros(); + +export default { + plugins: [ + [ + 'babel-plugin-ember-template-compilation', + { + compilerPath: 'ember-source/dist/ember-template-compiler.js', + transforms: [...macros.templateMacros], + }, + ], + [ + 'module:decorator-transforms', + { + runtime: { + import: import.meta.resolve('decorator-transforms/runtime-esm'), + }, + }, + ], + [ + '@babel/plugin-transform-runtime', + { + absoluteRuntime: dirname(fileURLToPath(import.meta.url)), + useESModules: true, + regenerator: false, + }, + ], + ...macros.babelMacros, + ], + + generatorOpts: { + compact: false, + }, +}; diff --git a/conditional-files/no-compat/_ts_babel.config.mjs b/conditional-files/no-compat/_ts_babel.config.mjs new file mode 100644 index 00000000..124ffe6a --- /dev/null +++ b/conditional-files/no-compat/_ts_babel.config.mjs @@ -0,0 +1,46 @@ +import { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { buildMacros } from '@embroider/macros/babel'; + +const macros = buildMacros(); + +export default { + plugins: [ + [ + '@babel/plugin-transform-typescript', + { + allExtensions: true, + onlyRemoveTypeImports: true, + allowDeclareFields: true, + }, + ], + [ + 'babel-plugin-ember-template-compilation', + { + compilerPath: 'ember-source/dist/ember-template-compiler.js', + transforms: [...macros.templateMacros()], + }, + ], + [ + 'module:decorator-transforms', + { + runtime: { + import: import.meta.resolve('decorator-transforms/runtime-esm'), + }, + }, + ], + [ + '@babel/plugin-transform-runtime', + { + absoluteRuntime: dirname(fileURLToPath(import.meta.url)), + useESModules: true, + regenerator: false, + }, + ], + ...macros.babelMacros(), + ], + + generatorOpts: { + compact: false, + }, +}; diff --git a/conditional-files/no-compat/app/app.ts b/conditional-files/no-compat/app/app.ts new file mode 100644 index 00000000..60c1f1c2 --- /dev/null +++ b/conditional-files/no-compat/app/app.ts @@ -0,0 +1,20 @@ +<% if (warpDrive) { %>import '@warp-drive/ember/install'; +<% } %>import Application from 'ember-strict-application-resolver'; +import config from '<%= modulePrefix %>/config/environment';<% if (notMinimal) { %> +import { importSync, isDevelopingApp, macroCondition } from '@embroider/macros';<% } %> +import setupInspector from '@embroider/legacy-inspector-support/ember-source-4.12'; + +<% if (notMinimal) { %> +if (macroCondition(isDevelopingApp())) { + importSync('./deprecation-workflow'); +} +<% } %> + + +export default class App extends Application { + modules = { + ...import.meta.glob('./router.*', { eager: true }), + ...import.meta.glob('./templates/**/*', { eager: true }), + ...import.meta.glob('./services/**/*', { eager: true }), + } +} diff --git a/conditional-files/no-compat/app/config/environment.ts b/conditional-files/no-compat/app/config/environment.ts new file mode 100644 index 00000000..f0360537 --- /dev/null +++ b/conditional-files/no-compat/app/config/environment.ts @@ -0,0 +1,41 @@ +<% if (notMinimal) { %> +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-expect-error +import { getGlobalConfig } from '@embroider/macros/src/addon/runtime'; +<% } %> + +interface Config { + isTesting?: boolean; + environment: string; + modulePrefix: string; + podModulePrefix?: string; + locationType: 'history' | 'hash' | 'none' | 'auto'; + rootURL: string; + EmberENV?: Record; + APP: Record & { rootElement?: string; autoboot?: boolean }; +} + +const ENV: Config = { + modulePrefix: '<%= name %>', + environment: import.meta.env.DEV ? 'development' : 'production', + rootURL: '/', + locationType: 'history', + EmberENV: {}, + APP: {}, +}; + +export default ENV; + +<% if (notMinimal) { %> +export function enterTestMode() { + ENV.locationType = 'none'; + ENV.APP.rootElement = '#ember-testing'; + ENV.APP.autoboot = false; + + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + const config = getGlobalConfig()['@embroider/macros']; + + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (config) config.isTesting = true; +} +<% } %> diff --git a/eslint.config.mjs b/eslint.config.mjs index 7f3a1fc2..3dbe8a43 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -27,6 +27,7 @@ export default [ { ignores: [ 'tests/fixtures/*', + 'files/vite.config.*', 'files/ember-cli-build.js', 'conditional-files/_js_*', 'conditional-files/_ts_*', diff --git a/files/app/templates/application.gts b/files/app/templates/application.gts index 0a4d1f9e..4727d1bc 100644 --- a/files/app/templates/application.gts +++ b/files/app/templates/application.gts @@ -1,6 +1,7 @@ import { pageTitle } from 'ember-page-title'; <% if (welcome) {%>import { WelcomePage } from 'ember-welcome-page';<% } %> +