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/app.ts b/conditional-files/minimal/app/app.ts new file mode 100644 index 00000000..caade888 --- /dev/null +++ b/conditional-files/minimal/app/app.ts @@ -0,0 +1,10 @@ +<% if (warpDrive) { %>import '@warp-drive/ember/install'; +<% } %>import Application from 'ember-strict-application-resolver'; + +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/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..3251e21a --- /dev/null +++ b/conditional-files/no-compat/_js_babel.config.mjs @@ -0,0 +1,47 @@ +import { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; +<% if (warpDrive) { %>import { setConfig } from '@warp-drive/core/build-config'; +<% } %>import { buildMacros } from '@embroider/macros/babel'; + +<% if (warpDrive) { %>const macros = buildMacros({ + configure: (config) => { + setConfig(config, { + // for universal apps this MUST be at least 5.6 + compatWith: '5.6', + }); + }, +}); +<% } else { %>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..d5b7b371 --- /dev/null +++ b/conditional-files/no-compat/_ts_babel.config.mjs @@ -0,0 +1,55 @@ +import { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; +<% if (warpDrive) { %>import { setConfig } from '@warp-drive/core/build-config'; +<% } %>import { buildMacros } from '@embroider/macros/babel'; + +<% if (warpDrive) { %>const macros = buildMacros({ + configure: (config) => { + setConfig(config, { + // for universal apps this MUST be at least 5.6 + compatWith: '5.6', + }); + }, +}); +<% } else { %>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..c2744931 --- /dev/null +++ b/conditional-files/no-compat/app/app.ts @@ -0,0 +1,18 @@ +<% if (warpDrive) { %>import '@warp-drive/ember/install';<% } %> +import Application from '@ember/application'; +import compatModules from '@embroider/virtual/compat-modules'; +import Resolver from 'ember-resolver'; +import config from '<%= modulePrefix %>/config/environment'; +import { importSync, isDevelopingApp, macroCondition } from '@embroider/macros'; +import setupInspector from '@embroider/legacy-inspector-support/ember-source-4.12'; + +if (macroCondition(isDevelopingApp())) { + importSync('./deprecation-workflow'); +} + +export default class App extends Application { + modulePrefix = config.modulePrefix; + podModulePrefix = config.podModulePrefix; + Resolver = Resolver.withModules(compatModules); + inspector = setupInspector(this); +} 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..7f0401b4 --- /dev/null +++ b/conditional-files/no-compat/app/config/environment.ts @@ -0,0 +1,38 @@ +<% if (notMinimal) { %><% if (typescript) { %>// 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; + + <% if (typescript) { %>// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call + <% } %>const config = getGlobalConfig()['@embroider/macros']; + + <% if (typescript) { %>// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + <% } %>if (config) config.isTesting = true; +} +<% } %> \ No newline at end of file diff --git a/eslint.config.mjs b/eslint.config.mjs index 7f3a1fc2..502d7326 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -26,10 +26,15 @@ export default [ eslintConfigPrettier, { ignores: [ + 'my-app/**', 'tests/fixtures/*', + 'files/vite.config.*', 'files/ember-cli-build.js', + 'files/testem.cjs', 'conditional-files/_js_*', 'conditional-files/_ts_*', + 'conditional-files/no-compat/_js_*', + 'conditional-files/no-compat/_ts_*', ], }, ]; diff --git a/files/app/templates/application.gts b/files/app/templates/application.gts index 0a4d1f9e..1b519415 100644 --- a/files/app/templates/application.gts +++ b/files/app/templates/application.gts @@ -1,5 +1,5 @@ -import { pageTitle } from 'ember-page-title'; -<% if (welcome) {%>import { WelcomePage } from 'ember-welcome-page';<% } %> +import { pageTitle } from 'ember-page-title';<% if (welcome) {%> +import { WelcomePage } from 'ember-welcome-page';<% } %>