ember.nvp 1.7.0 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/.release-plan.json +45 -13
  2. package/CHANGELOG.md +18 -0
  3. package/README.md +41 -28
  4. package/RELEASE.md +16 -14
  5. package/package.json +1 -1
  6. package/packages/build-tooling-utils/README.md +7 -12
  7. package/packages/build-tooling-utils/package.json +1 -1
  8. package/packages/build-tooling-utils/src/extensions.ts +4 -3
  9. package/packages/build-tooling-utils/src/maybe-babel.ts +18 -15
  10. package/packages/rolldown/README.md +105 -100
  11. package/packages/rolldown/index.ts +37 -24
  12. package/packages/rolldown/package.json +1 -1
  13. package/packages/rolldown/src/app-reexports.test.ts +4 -3
  14. package/packages/rolldown/src/app-reexports.ts +37 -27
  15. package/packages/rolldown/src/babel.test.ts +10 -5
  16. package/packages/rolldown/src/babel.ts +88 -69
  17. package/packages/rolldown/src/config.ts +21 -17
  18. package/packages/rolldown/src/dts.test.ts +42 -26
  19. package/packages/rolldown/src/externals.test.ts +16 -11
  20. package/packages/rolldown/src/externals.ts +18 -12
  21. package/packages/rolldown/src/isolated-declarations.ts +56 -43
  22. package/packages/rolldown/src/plugin-like.ts +18 -15
  23. package/packages/rolldown/src/published-types.test.ts +18 -13
  24. package/packages/rolldown/src/transform.test.ts +26 -17
  25. package/packages/rolldown/src/transform.ts +68 -48
  26. package/packages/vite/README.md +10 -11
  27. package/packages/vite/package.json +1 -1
  28. package/packages/vite/src/ember.ts +44 -36
  29. package/packages/vite/src/test-html.ts +13 -11
  30. package/src/bases/README.md +6 -3
  31. package/src/bases/minimal-app/app.test.ts +7 -4
  32. package/src/bases/minimal-app/files/app/app.ts +2 -3
  33. package/src/bases/minimal-app/files/app/router.ts +3 -3
  34. package/src/bases/minimal-app/index.js +10 -6
  35. package/src/bases/minimal-custom-element/files/README.md +16 -12
  36. package/src/bases/minimal-extension/files/README.md +13 -5
  37. package/src/bases/minimal-extension/files/app/app.ts +2 -3
  38. package/src/bases/minimal-extension/files/app/config.ts +5 -3
  39. package/src/bases/minimal-extension/index.js +16 -11
  40. package/src/bases/minimal-library/files/README.md +8 -7
  41. package/src/bases/minimal-library/index.js +21 -15
  42. package/src/cli/index.js +23 -18
  43. package/src/cli/questions/write.js +12 -10
  44. package/src/layers/are-the-types-wrong/index.js +4 -4
  45. package/src/layers/github-actions/index.js +7 -4
  46. package/src/layers/inspector-support/index.js +2 -2
  47. package/src/layers/qunit/index.js +18 -14
  48. package/src/layers/readme/index.js +2 -4
  49. package/src/layers/renovate/index.js +2 -1
  50. package/src/layers/typescript/index.js +12 -12
  51. package/src/layers/vitest/index.js +7 -3
  52. package/src/utils/babel.js +3 -2
  53. package/src/utils/buffer.js +2 -2
  54. package/src/utils/cli.js +4 -4
  55. package/src/utils/fs.js +23 -14
  56. package/src/utils/inspector-support.js +22 -19
  57. package/src/utils/npm.js +15 -12
  58. package/src/utils/project-type.js +19 -0
  59. package/src/utils/project.js +4 -13
  60. package/src/utils/remove-types.js +2 -4
  61. package/src/utils/rewrite-imports.js +43 -31
  62. package/src/utils/stage.js +44 -33
  63. package/src/utils/tsdown-config.js +6 -5
  64. package/src/utils/types.ts +9 -8
  65. package/test/ember.nvp/base-library.test.ts +6 -4
  66. package/test/ember.nvp/generator-replace-or-update.test.ts +6 -4
  67. package/test/ember.nvp/inspector-support.test.ts +4 -3
  68. package/test/ember.nvp/layer-inspector-support.test.ts +2 -3
  69. package/test/ember.nvp/layer-publish-checks.test.ts +2 -3
  70. package/test/ember.nvp/layer-qunit.test.ts +2 -2
  71. package/test/ember.nvp/layer-readme.test.ts +2 -2
  72. package/test/ember.nvp/layer-vitest.test.ts +16 -9
  73. package/test/ember.nvp/layers-load.test.ts +26 -0
  74. package/test/ember.nvp/library-src-fixtures.ts +7 -3
  75. package/test/ember.nvp/permutations/shared.ts +19 -12
  76. package/test/ember.nvp/publish-configs.test.ts +44 -31
  77. package/test/ember.nvp/rewrite-imports.test.ts +4 -3
  78. package/test/ember.nvp/scoped-css-library.test.ts +6 -4
  79. package/test/test-helpers/permutate.test.ts +3 -3
  80. package/test/test-helpers.ts +10 -6
@@ -19,14 +19,16 @@ function absolutePath(relativePath: string) {
19
19
  * Everything a project without its own babel config needs:
20
20
  *
21
21
  * - TypeScript stripping
22
- * - template compilation (wire format: vite serves/bundles for the
23
- * project's own ember-source, so the final compile happens here)
22
+ * - template compilation, to the wire format
23
+ * (vite serves and bundles for the project's own ember-source,
24
+ * so the final compile happens here)
24
25
  * - build macros, evaluated at build time
25
- * - decorator-transforms, with its runtime left as a bare specifier so it
26
- * resolves from the project (which depends on `decorator-transforms`)
26
+ * - decorator-transforms, with its runtime left as a bare specifier
27
+ * so it resolves from the project
28
+ * (the project depends on `decorator-transforms`)
27
29
  *
28
- * The plugins are named, not imported: babel resolves them from the
29
- * project, which carries them as its own dependencies.
30
+ * The plugins are named, not imported.
31
+ * babel resolves them from the project, which carries them as its own dependencies.
30
32
  */
31
33
  function defaultBabelPlugins() {
32
34
  const macros = buildMacros();
@@ -56,12 +58,14 @@ type BabelOptions =
56
58
  };
57
59
 
58
60
  /**
59
- * The project's babel config wins when it exists -- `babel.configFile`
60
- * selects which one (e.g. a test-only `config/test/babel.config.js`).
61
- * Without one (libraries), `defaultBabelPlugins` covers TypeScript,
62
- * templates, macros, and decorators, so no config file is required --
63
- * helpers are inlined because projects without a babel config don't
64
- * carry `@babel/runtime`.
61
+ * The project's babel config wins when it exists.
62
+ * `babel.configFile` selects which one (e.g. a test-only `config/test/babel.config.js`).
63
+ *
64
+ * Without one (libraries), `defaultBabelPlugins` covers TypeScript, templates, macros, and decorators,
65
+ * so no config file is required.
66
+ *
67
+ * Helpers are inlined in that case:
68
+ * projects without a babel config don't carry `@babel/runtime`.
65
69
  */
66
70
  function babelOptions(nvpConfig: Config): BabelOptions {
67
71
  const configFile = resolve(
@@ -83,9 +87,12 @@ function babelOptions(nvpConfig: Config): BabelOptions {
83
87
  /**
84
88
  * Additional opt-ins beyond maybeBabel's built-in list.
85
89
  *
86
- * These libraries ship code that still needs babel (ember-concurrency's
87
- * decorators, ember-scoped-css transforms, ember-intl's formatMessage macro),
88
- * and the `initializeRuntimeMacrosConfig` runtime call must be compiled away.
90
+ * These libraries ship code that still needs babel:
91
+ * - ember-concurrency's decorators
92
+ * - ember-scoped-css transforms
93
+ * - ember-intl's formatMessage macro
94
+ *
95
+ * The `initializeRuntimeMacrosConfig` runtime call must also be compiled away.
89
96
  */
90
97
  function babelFilter(nvpConfig: Config) {
91
98
  return {
@@ -120,9 +127,10 @@ interface Config {
120
127
  configFile?: string;
121
128
 
122
129
  /**
123
- * optional way to configure when babel is activateed.
124
- * by default, all transforming is oxc, except when babel is needed
125
- * (for things not currently implemented in oxc)
130
+ * optional way to configure when babel is activated.
131
+ *
132
+ * by default, all transforming is oxc,
133
+ * except when babel is needed (for things not currently implemented in oxc)
126
134
  */
127
135
  include?: {
128
136
  /**
@@ -154,10 +162,12 @@ export function ember(nvpConfig: Config = {}) {
154
162
  const filter = babelFilter(nvpConfig);
155
163
 
156
164
  /*
157
- * Plugins must be returned as top-level array entries — NOT pushed into
158
- * config.plugins inside a config() hook. Vite 8 extracts user plugins
159
- * *before* config hooks run, so anything added later is invisible to the
160
- * plugin container (resolveId, load, etc. hooks never fire).
165
+ * Plugins must be returned as top-level array entries,
166
+ * NOT pushed into config.plugins inside a config() hook.
167
+ *
168
+ * Vite 8 extracts user plugins *before* config hooks run,
169
+ * so anything added later is invisible to the plugin container
170
+ * (resolveId, load, etc. hooks never fire).
161
171
  */
162
172
  return [
163
173
  {
@@ -194,9 +204,8 @@ export function ember(nvpConfig: Config = {}) {
194
204
  resolver({ rolldown: true }),
195
205
  templateTag(),
196
206
 
197
- // Libraries will have precompileTemplate and macros, etc,
198
- // and we need to compile that away using this app's
199
- // template compiler
207
+ // Libraries ship precompileTemplate calls and macros.
208
+ // Both must compile away here, with this app's template compiler.
200
209
  maybeBabel({
201
210
  ...babel,
202
211
  parallel: nvpConfig.babel?.parallel,
@@ -231,14 +240,12 @@ function applyConfig(viteConfig: ResolvedConfig, env: ConfigEnv, nvpConfig: Conf
231
240
  }
232
241
 
233
242
  function dev(viteConfig: ResolvedConfig, nvpConfig: Config) {
234
- /**************************************
235
- *
243
+ /**
236
244
  * build config for tests
237
245
  *
238
- * NOTE: we can't minify because some tests
239
- * are checking x.constructor.name, which changes when minified
240
- *
241
- *************************************/
246
+ * NOTE: we can't minify.
247
+ * some tests check x.constructor.name, which changes when minified
248
+ */
242
249
  Object.assign(viteConfig.build, {
243
250
  sourcemap: true,
244
251
  cleanCssOptions: { sourceMap: true },
@@ -333,7 +340,8 @@ function prod(viteConfig: ResolvedConfig, nvpConfig: Config) {
333
340
  minify: true,
334
341
  cleanDir: true,
335
342
  /**
336
- * This is needed due to how we manage module state.
343
+ * Needed due to how we manage module state.
344
+ *
337
345
  * This can create waterfalls when too much top-level await is used.
338
346
  */
339
347
  strictExecutionOrder: true,
@@ -342,10 +350,10 @@ function prod(viteConfig: ResolvedConfig, nvpConfig: Config) {
342
350
  */
343
351
  codeSplitting: {
344
352
  /**
345
- * Kind of a shame this isn't automatic based on dynamic import usage
346
- * in vite8.
347
- * Kinda forces us to know every potential problem area of the app,
348
- * rather than rely on automatic optimizations based on import/module usage
353
+ * Kind of a shame this isn't automatic based on dynamic import usage in vite8.
354
+ *
355
+ * This forces us to know every potential problem area of the app,
356
+ * rather than rely on automatic optimizations based on import/module usage.
349
357
  */
350
358
  groups: [...(nvpConfig?.production?.codeSplittingGroups ?? [])],
351
359
  },
@@ -3,10 +3,10 @@ import { join } from "node:path";
3
3
  import type { ViteDevServer } from "vite";
4
4
 
5
5
  /**
6
- * Everything a QUnit + testem run needs, with no project-specific
7
- * references: root-relative specifiers keep it independent of where the
8
- * project keeps its files, and the globs pick up tests/** as well as
9
- * co-located `*-test` modules under src/**.
6
+ * Everything a QUnit + testem run needs, with no project-specific references.
7
+ *
8
+ * - root-relative specifiers keep it independent of where the project keeps its files
9
+ * - the globs pick up tests/** as well as co-located `*-test` modules under src/**
10
10
  */
11
11
  const DEFAULT_TEST_HTML = `<!doctype html>
12
12
  <html>
@@ -39,14 +39,16 @@ const DEFAULT_TEST_HTML = `<!doctype html>
39
39
  `;
40
40
 
41
41
  /**
42
- * Lets a project run its tests without maintaining a tests/index.html:
43
- * whenever that file is absent, this plugin answers for it -- `load`
44
- * supplies the html to the build (so `tests/index.html` still lands in
45
- * dist for testem), and the dev-server middleware serves it (through
46
- * `transformIndexHtml`, so the html goes through the same pipeline as an
47
- * on-disk file).
42
+ * Lets a project run its tests without maintaining a tests/index.html.
43
+ *
44
+ * Whenever that file is absent, this plugin answers for it:
45
+ * - `load` supplies the html to the build
46
+ * (so `tests/index.html` still lands in dist for testem)
47
+ * - the dev-server middleware serves it, through `transformIndexHtml`,
48
+ * so the html goes through the same pipeline as an on-disk file
48
49
  *
49
- * A tests/index.html on disk always wins; every hook here defers to it.
50
+ * A tests/index.html on disk always wins.
51
+ * Every hook here defers to it.
50
52
  */
51
53
  export function testHtml() {
52
54
  const htmlPath = join(process.cwd(), "tests", "index.html");
@@ -1,5 +1,8 @@
1
- Each of these base projects are _real_ projects that can be ran in these directories.
1
+ Each base is a _real_ project.
2
+ You can run it from its `files/` directory.
2
3
 
3
- For changing the name of a project, the code in the base layer's index.js should find all the places the name is used and swap it out (codemod style).
4
+ A base never uses a template language such as ejs:
5
+ that would make the base unrunnable.
4
6
 
5
- We don't want to use ejs, because it makes the base layers unrunnable.
7
+ To change the project name, the base's `index.js` finds every place the name is used,
8
+ and swaps it out (codemod style).
@@ -110,8 +110,9 @@ const DEBUG_MARKERS = {
110
110
 
111
111
  /**
112
112
  * Lives in app/services/ so that app.ts's eager
113
- * `import.meta.glob("./services/**\/*")` pulls it into the build
114
- * without needing to modify any generated files.
113
+ * `import.meta.glob("./services/**\/*")` pulls it into the build.
114
+ *
115
+ * No generated file needs to change.
115
116
  */
116
117
  const debugFixture = `
117
118
  import { assert, deprecate, warn } from "@ember/debug";
@@ -134,8 +135,10 @@ if (macroCondition(isDevelopingApp())) {
134
135
  `;
135
136
 
136
137
  /**
137
- * Only .js files -- the sourcemaps (.map) contain the original
138
- * source (with markers) even in production builds.
138
+ * Only .js files.
139
+ *
140
+ * The sourcemaps (.map) contain the original source (with markers),
141
+ * even in production builds.
139
142
  */
140
143
  async function builtJavaScript(project: Project): Promise<string> {
141
144
  let files = globSync("dist/**/*.js", { cwd: project.directory });
@@ -1,11 +1,10 @@
1
1
  /**
2
2
  * Looking for services that come from addons?
3
3
  *
4
+ * App-tree merging from libraries is not supported.
4
5
  * See: https://github.com/embroider-build/embroider/issues/2659
5
6
  *
6
- * We currently don't support app-tree merging from libraries.
7
- *
8
- * For services, I highly recommend looking in to either of
7
+ * For services, look in to either of:
9
8
  * - https://github.com/chancancode/ember-polaris-service-
10
9
  * - https://ember-primitives.pages.dev/6-utils/createService.md
11
10
  * - https://ember-primitives.pages.dev/6-utils/createAsyncService.md
@@ -10,10 +10,10 @@ export default class Router extends EmbroiderRouter {
10
10
  Router.map(function () {});
11
11
 
12
12
  /**
13
+ * Route bundles (lazy-loaded route groups) have no nice API yet.
14
+ *
13
15
  * Caveat:
14
16
  * - https://github.com/embroider-build/embroider/issues/2521
15
- * We don't yet have a way to do this in a nice way
16
- *
17
17
  */
18
18
  // function bundle(name: string, loader: () => Promise<{ default: unknown }>[]) {
19
19
  // return {
@@ -35,7 +35,7 @@ Router.map(function () {});
35
35
  // }
36
36
 
37
37
  /**
38
- * Examples from:
38
+ * Example usage, from:
39
39
  * - https://github.com/NullVoxPopuli/limber/blob/67e2f54bbe224052e38f9a9e566d704411e65e86/apps/repl/app/router.ts#L35
40
40
  */
41
41
  // (window as any)._embroiderRouteBundles_ = [
@@ -5,7 +5,7 @@ import { applyFolderTo } from "#utils/fs.js";
5
5
  import { removeConfiguredPlugin } from "#utils/babel.js";
6
6
 
7
7
  /**
8
- * Minimal Layer
8
+ * Minimal App Base
9
9
  *
10
10
  * Provides the absolute bare minimum for an Ember app:
11
11
  * - type: "module" in package.json
@@ -22,8 +22,10 @@ export default {
22
22
  /**
23
23
  * 1. Apply files
24
24
  * a. Remove TS if needed
25
- * 2. Remove TS deps/files if needed
26
- * 3. Update name(s)
25
+ * 2. Update name(s)
26
+ * 3. Remove TS deps/files if needed
27
+ * 4. Upgrade in-range dependencies
28
+ * 5. Update an existing babel config, if any
27
29
  *
28
30
  * @param {import('#utils/project.js').Project} project
29
31
  */
@@ -37,6 +39,8 @@ export default {
37
39
  };
38
40
 
39
41
  /**
42
+ * A JavaScript project's babel config must not reference the TS plugin.
43
+ *
40
44
  * @param {import('#utils/project.js').Project} project
41
45
  */
42
46
  async function updateBabelConfig(project) {
@@ -72,10 +76,10 @@ async function makeJavaScript(project) {
72
76
  if (await project.hasOrWantsLayer("typescript")) return;
73
77
 
74
78
  /**
75
- * We don't actually remove anything, because we want intellisense for JS
79
+ * Intellisense for JS needs some of these,
80
+ * but minimal means minimal.
76
81
  *
77
- * But perhaps for the sake of minimal, we do remoev it.
78
- * And we add a layer later for JSDoc ased TS or something
82
+ * A later layer for JSDoc-based TS can add them back.
79
83
  */
80
84
  await packageJson.removeDevDependencies(
81
85
  [
@@ -52,19 +52,22 @@ pnpm start
52
52
  ## Structure
53
53
 
54
54
  - `src/components/counter.gts` is the Ember component.
55
- - `src/element.ts` is the custom element. Its `connectedCallback` renders the component
56
- into the element with `renderComponent` from `@ember/renderer`. Its
57
- `disconnectedCallback` destroys that render.
58
- - `src/register.ts` defines the tag. Consumers import this file for its side effect.
59
- - `src/index.ts` is the public entry point. It exports the element class and the
60
- component.
55
+ - `src/element.ts` is the custom element.
56
+ Its `connectedCallback` renders the component with `renderComponent` from `@ember/renderer`.
57
+ Its `disconnectedCallback` destroys that render.
58
+ - `src/register.ts` defines the tag.
59
+ Consumers import this file for its side effect.
60
+ - `src/index.ts` is the public entry point.
61
+ It exports the element class and the component.
61
62
  - `dist/` is the built output that gets published (git-ignored).
62
63
 
63
64
  ### Reactive attributes
64
65
 
65
- The element lists its attributes in `observedAttributes`. Each attribute change writes
66
- to a tracked object. The component reads its args from that object, so the DOM updates
67
- on the next render. To add an attribute:
66
+ The element lists its attributes in `observedAttributes`.
67
+ Each attribute change writes to a tracked object.
68
+ The component reads its args from that object, so the DOM updates on the next render.
69
+
70
+ To add an attribute:
68
71
 
69
72
  1. Add its name to `observedAttributes`.
70
73
  2. Give it a default value in the tracked object.
@@ -77,9 +80,10 @@ so every exported value needs an explicit type annotation.
77
80
 
78
81
  ### Development or production ember
79
82
 
80
- The build bundles the production build of ember. To bundle the development build,
81
- with assertions and deprecation messages, add the `development` condition in
82
- `tsdown.config.js`:
83
+ The build bundles the production build of ember.
84
+
85
+ To bundle the development build (assertions and deprecation messages),
86
+ add the `development` condition in `tsdown.config.js`:
83
87
 
84
88
  ```js
85
89
  inputOptions: { resolve: { conditionNames: ["development"] } },
@@ -4,18 +4,21 @@ A [Manifest V3](https://developer.chrome.com/docs/extensions/develop/migrate/wha
4
4
 
5
5
  ## Developing
6
6
 
7
- The popup is a regular web page, so the fastest feedback loop is the vite dev server in a normal browser tab:
7
+ The popup is a regular web page.
8
+ The fastest feedback loop is the vite dev server in a normal browser tab:
8
9
 
9
10
  ```bash
10
11
  pnpm dev
11
12
  ```
12
13
 
13
- To run as an actual extension, build (in watch mode) and load the `dist/` directory as an unpacked extension:
14
+ To run it as an extension, build in watch mode:
14
15
 
15
16
  ```bash
16
17
  pnpm build:watch
17
18
  ```
18
19
 
20
+ Then load the `dist/` directory as an unpacked extension:
21
+
19
22
  - **Chrome / Edge / Brave**: `chrome://extensions` → enable "Developer mode" → "Load unpacked" → select `dist/`
20
23
  - **Firefox**: `about:debugging#/runtime/this-firefox` → "Load Temporary Add-on…" → select `dist/manifest.json`
21
24
 
@@ -23,9 +26,14 @@ After a rebuild, re-open the popup (or reload the extension) to see changes.
23
26
 
24
27
  ## Anatomy
25
28
 
26
- - `public/manifest.json` — the extension manifest; copied verbatim into `dist/`. Add [`background`](https://developer.chrome.com/docs/extensions/reference/manifest/background), [`content_scripts`](https://developer.chrome.com/docs/extensions/reference/manifest/content-scripts), permissions, and icons here as your extension grows.
27
- - `index.html` — the popup page (`action.default_popup`). Extension pages are served with a `script-src 'self'` Content-Security-Policy, so the app boots from `app/boot.ts` rather than an inline script.
28
- - `app/` — a normal Ember app. Routing uses `locationType: "none"`, since extension pages have no URL bar to bind to.
29
+ - `public/manifest.json` is the extension manifest. It is copied verbatim into `dist/`.
30
+ Add [`background`](https://developer.chrome.com/docs/extensions/reference/manifest/background),
31
+ [`content_scripts`](https://developer.chrome.com/docs/extensions/reference/manifest/content-scripts),
32
+ permissions, and icons here as your extension grows.
33
+ - `index.html` is the popup page (`action.default_popup`).
34
+ Extension pages forbid inline scripts, so the app boots from `app/boot.ts`.
35
+ - `app/` is a normal Ember app.
36
+ Extension pages have no URL bar, so routing uses `locationType: "none"`.
29
37
 
30
38
  ## Building for release
31
39
 
@@ -1,11 +1,10 @@
1
1
  /**
2
2
  * Looking for services that come from addons?
3
3
  *
4
+ * App-tree merging from libraries is not supported.
4
5
  * See: https://github.com/embroider-build/embroider/issues/2659
5
6
  *
6
- * We currently don't support app-tree merging from libraries.
7
- *
8
- * For services, I highly recommend looking in to either of
7
+ * For services, look in to either of:
9
8
  * - https://github.com/chancancode/ember-polaris-service-
10
9
  * - https://ember-primitives.pages.dev/6-utils/createService.md
11
10
  * - https://ember-primitives.pages.dev/6-utils/createAsyncService.md
@@ -10,9 +10,11 @@ const ENV: Config = {
10
10
  environment: import.meta.env.DEV ? "development" : "production",
11
11
  rootURL: "/",
12
12
  /**
13
- * Extension pages live at chrome-extension://<id>/index.html (or
14
- * moz-extension://), where history-based routing has nothing to bind
15
- * to. "none" keeps routing fully programmatic.
13
+ * Extension pages live at chrome-extension://<id>/index.html
14
+ * (or moz-extension://).
15
+ *
16
+ * History-based routing has nothing to bind to there.
17
+ * "none" keeps routing fully programmatic.
16
18
  */
17
19
  locationType: "none",
18
20
  EmberENV: {},
@@ -12,8 +12,8 @@ import { removeConfiguredPlugin } from "#utils/babel.js";
12
12
  * whose popup is an Ember app:
13
13
  * - type: "module" in package.json
14
14
  * - public/manifest.json copied verbatim into dist
15
- * - index.html popup booting from an external script (extension pages
16
- * forbid inline scripts via CSP)
15
+ * - index.html popup booting from an external script
16
+ * (extension pages forbid inline scripts via CSP)
17
17
  * - No testing framework
18
18
  * - No linting or formatting
19
19
  * - No ember-welcome-page
@@ -25,8 +25,8 @@ export default {
25
25
  /**
26
26
  * 1. Apply files
27
27
  * a. Remove TS if needed
28
- * 2. Remove TS deps/files if needed
29
- * 3. Update name(s)
28
+ * 2. Update name(s)
29
+ * 3. Remove TS deps/files if needed
30
30
  * 4. Upgrade in-range dependencies
31
31
  * 5. Update an existing babel config, if any
32
32
  *
@@ -42,6 +42,8 @@ export default {
42
42
  };
43
43
 
44
44
  /**
45
+ * A JavaScript project's babel config must not reference the TS plugin.
46
+ *
45
47
  * @param {import('#utils/project.js').Project} project
46
48
  */
47
49
  async function updateBabelConfig(project) {
@@ -60,7 +62,9 @@ async function applyFiles(project) {
60
62
  }
61
63
 
62
64
  /**
63
- * Operates on known files where the name matters
65
+ * Operates on known files where the name matters.
66
+ *
67
+ * The extension's display name lives in public/manifest.json.
64
68
  *
65
69
  * @param {import('#utils/project.js').Project} project
66
70
  */
@@ -86,10 +90,10 @@ async function makeJavaScript(project) {
86
90
  if (await project.hasOrWantsLayer("typescript")) return;
87
91
 
88
92
  /**
89
- * We don't actually remove anything, because we want intellisense for JS
93
+ * Intellisense for JS needs some of these,
94
+ * but minimal means minimal.
90
95
  *
91
- * But perhaps for the sake of minimal, we do remoev it.
92
- * And we add a layer later for JSDoc ased TS or something
96
+ * A later layer for JSDoc-based TS can add them back.
93
97
  */
94
98
  await packageJson.removeDevDependencies(
95
99
  [
@@ -110,9 +114,10 @@ async function makeJavaScript(project) {
110
114
  }, project.directory);
111
115
 
112
116
  /**
113
- * The import-rewriting pass only handles module files; the popup's
114
- * <script src> points at the boot module by path, so it has to follow
115
- * the .ts -> .js rename by hand.
117
+ * The import-rewriting pass only handles module files.
118
+ *
119
+ * The popup's <script src> points at the boot module by path,
120
+ * so it has to follow the .ts -> .js rename by hand.
116
121
  */
117
122
  if (!project.hasFile("index.html")) return;
118
123
 
@@ -24,16 +24,17 @@ pnpm start
24
24
 
25
25
  ## Structure
26
26
 
27
- - `src/` — your library source. Author components in `.gts`/`.gjs`
28
- (template-tag) and plain modules in `.ts`/`.js`.
29
- - `src/index.ts` — the public entry point. Everything a consumer can import
30
- must be re-exported from here (or added as an entry in `tsdown.config.js`).
31
- - `dist/` — the built output that gets published (git-ignored).
27
+ - `src/` is your library source.
28
+ Author components in `.gts`/`.gjs` (template-tag) and plain modules in `.ts`/`.js`.
29
+ - `src/index.ts` is the public entry point.
30
+ Everything a consumer can import must be re-exported from here,
31
+ or added as an entry in `tsdown.config.js`.
32
+ - `dist/` is the built output that gets published (git-ignored).
32
33
 
33
34
  Declarations are emitted with
34
35
  [isolated declarations](https://www.typescriptlang.org/tsconfig/#isolatedDeclarations),
35
- so every exported value needs an explicit type annotation — in particular,
36
- annotate exported template-only components with `TOC<...>`.
36
+ so every exported value needs an explicit type annotation.
37
+ In particular, annotate exported template-only components with `TOC<...>`.
37
38
 
38
39
  ## Publishing
39
40
 
@@ -11,9 +11,9 @@ import { removeConfiguredPlugin } from "#utils/babel.js";
11
11
  * Provides the absolute bare minimum for an Ember v2 library (addon):
12
12
  * - type: "module" in package.json
13
13
  * - built with tsdown + @nullvoxpopuli/ember-rolldown
14
- * - a sample `<template>` component and a plain module
15
- * - No babel.config.js: ember() covers TS stripping, template compilation,
16
- * and decorators
14
+ * - an empty src/ with an index entry
15
+ * - No babel.config.js
16
+ * (ember() covers TS stripping, template compilation, and decorators)
17
17
  * - No testing framework
18
18
  * - No linting or formatting
19
19
  *
@@ -65,8 +65,10 @@ async function updateName(project) {
65
65
  }
66
66
 
67
67
  /**
68
- * The template's package.json is `private: true` so it can never be
69
- * published from this repo; the generated library exists to be published,
68
+ * The template's package.json is `private: true`,
69
+ * so it can never be published from this repo.
70
+ *
71
+ * The generated library exists to be published,
70
72
  * so the flag is removed entirely.
71
73
  *
72
74
  * @param {import('#utils/project.js').Project} project
@@ -78,9 +80,11 @@ async function makePublishable(project) {
78
80
  }
79
81
 
80
82
  /**
81
- * When the project is JavaScript (no typescript layer), remove the TS
82
- * toolchain, drop the tsconfig, and point the build at the emitted `.js`
83
- * entry (declarations can't be produced without types).
83
+ * When the project is JavaScript (no typescript layer):
84
+ * - remove the TS toolchain
85
+ * - drop the tsconfig
86
+ * - point the build at the emitted `.js` entry
87
+ * (declarations can't be produced without types)
84
88
  *
85
89
  * @param {import('#utils/project.js').Project} project
86
90
  */
@@ -99,8 +103,8 @@ async function makeJavaScript(project) {
99
103
  }
100
104
 
101
105
  /**
102
- * No declarations are emitted for a JavaScript library, so the `types`
103
- * export conditions would point at files that never exist.
106
+ * No declarations are emitted for a JavaScript library,
107
+ * so the `types` export conditions would point at files that never exist.
104
108
  *
105
109
  * @param {import('#utils/project.js').Project} project
106
110
  */
@@ -115,8 +119,9 @@ async function removeTypesExports(project) {
115
119
  }
116
120
 
117
121
  /**
118
- * Rewrites the tsdown config so it builds the JavaScript entry and stops
119
- * emitting declarations (defineConfig defaults to `dts: true`).
122
+ * Rewrites the tsdown config so it:
123
+ * - builds the JavaScript entry
124
+ * - stops emitting declarations (defineConfig defaults to `dts: true`)
120
125
  *
121
126
  * @param {import('#utils/project.js').Project} project
122
127
  */
@@ -152,9 +157,10 @@ async function upgradeDependencies(project) {
152
157
  }
153
158
 
154
159
  /**
155
- * The base doesn't emit a babel.config.js, but this can run over an
156
- * existing project that has one -- and a JavaScript project's config
157
- * must not reference the TS plugin.
160
+ * The base doesn't emit a babel.config.js,
161
+ * but this can run over an existing project that has one.
162
+ *
163
+ * A JavaScript project's babel config must not reference the TS plugin.
158
164
  *
159
165
  * @param {import('#utils/project.js').Project} project
160
166
  */