ember.nvp 1.7.0 → 1.8.0
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.
- package/.github/workflows/ci.yml +22 -0
- package/.release-plan.json +35 -7
- package/CHANGELOG.md +32 -0
- package/README.md +41 -28
- package/RELEASE.md +16 -14
- package/package.json +1 -1
- package/packages/build-tooling-utils/README.md +7 -12
- package/packages/build-tooling-utils/package.json +2 -2
- package/packages/build-tooling-utils/src/extensions.ts +4 -3
- package/packages/build-tooling-utils/src/maybe-babel.ts +18 -15
- package/packages/rolldown/README.md +105 -100
- package/packages/rolldown/index.ts +37 -24
- package/packages/rolldown/package.json +4 -4
- package/packages/rolldown/src/app-reexports.test.ts +4 -3
- package/packages/rolldown/src/app-reexports.ts +37 -27
- package/packages/rolldown/src/babel.test.ts +10 -5
- package/packages/rolldown/src/babel.ts +88 -69
- package/packages/rolldown/src/config.ts +21 -17
- package/packages/rolldown/src/dts.test.ts +42 -26
- package/packages/rolldown/src/externals.test.ts +16 -11
- package/packages/rolldown/src/externals.ts +18 -12
- package/packages/rolldown/src/isolated-declarations.ts +56 -43
- package/packages/rolldown/src/plugin-like.ts +18 -15
- package/packages/rolldown/src/published-types.test.ts +18 -13
- package/packages/rolldown/src/transform.test.ts +26 -17
- package/packages/rolldown/src/transform.ts +68 -48
- package/packages/vite/README.md +10 -11
- package/packages/vite/package.json +2 -2
- package/packages/vite/src/ember.ts +44 -36
- package/packages/vite/src/test-html.ts +13 -11
- package/src/bases/README.md +6 -3
- package/src/bases/minimal-app/app.test.ts +7 -4
- package/src/bases/minimal-app/files/app/app.ts +2 -3
- package/src/bases/minimal-app/files/app/router.ts +3 -3
- package/src/bases/minimal-app/index.js +10 -6
- package/src/bases/minimal-custom-element/files/README.md +16 -12
- package/src/bases/minimal-extension/files/README.md +13 -5
- package/src/bases/minimal-extension/files/app/app.ts +2 -3
- package/src/bases/minimal-extension/files/app/config.ts +5 -3
- package/src/bases/minimal-extension/index.js +16 -11
- package/src/bases/minimal-library/files/README.md +8 -7
- package/src/bases/minimal-library/index.js +21 -15
- package/src/cli/index.js +23 -18
- package/src/cli/questions/write.js +12 -10
- package/src/layers/are-the-types-wrong/index.js +4 -4
- package/src/layers/github-actions/index.js +7 -4
- package/src/layers/inspector-support/index.js +2 -2
- package/src/layers/qunit/index.js +18 -14
- package/src/layers/readme/index.js +2 -4
- package/src/layers/renovate/index.js +2 -1
- package/src/layers/typescript/index.js +12 -12
- package/src/layers/vitest/index.js +7 -3
- package/src/utils/babel.js +3 -2
- package/src/utils/buffer.js +2 -2
- package/src/utils/cli.js +4 -4
- package/src/utils/fs.js +23 -14
- package/src/utils/inspector-support.js +22 -19
- package/src/utils/npm.js +15 -12
- package/src/utils/project-type.js +19 -0
- package/src/utils/project.js +4 -13
- package/src/utils/remove-types.js +2 -4
- package/src/utils/rewrite-imports.js +43 -31
- package/src/utils/stage.js +44 -33
- package/src/utils/tsdown-config.js +6 -5
- package/src/utils/types.ts +9 -8
- package/test/ember.nvp/base-library.test.ts +6 -4
- package/test/ember.nvp/generator-replace-or-update.test.ts +6 -4
- package/test/ember.nvp/inspector-support.test.ts +4 -3
- package/test/ember.nvp/layer-inspector-support.test.ts +2 -3
- package/test/ember.nvp/layer-publish-checks.test.ts +2 -3
- package/test/ember.nvp/layer-qunit.test.ts +2 -2
- package/test/ember.nvp/layer-readme.test.ts +2 -2
- package/test/ember.nvp/layer-vitest.test.ts +16 -9
- package/test/ember.nvp/layers-load.test.ts +26 -0
- package/test/ember.nvp/library-src-fixtures.ts +7 -3
- package/test/ember.nvp/permutations/shared.ts +19 -12
- package/test/ember.nvp/publish-configs.test.ts +44 -31
- package/test/ember.nvp/rewrite-imports.test.ts +4 -3
- package/test/ember.nvp/scoped-css-library.test.ts +6 -4
- package/test/test-helpers/permutate.test.ts +3 -3
- package/test/test-helpers.ts +10 -6
|
@@ -8,20 +8,26 @@ import { join } from "node:path";
|
|
|
8
8
|
import type { Project } from "ember.nvp";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* A library whose package also holds dev-only code (a demo app, in-package
|
|
12
|
-
*
|
|
13
|
-
* `
|
|
14
|
-
*
|
|
15
|
-
*
|
|
11
|
+
* A library whose package also holds dev-only code (a demo app, in-package tests)
|
|
12
|
+
* keeps two of each build config:
|
|
13
|
+
* - a permissive `tsconfig.json` and `babel.config.js`,
|
|
14
|
+
* which editors and `tsc --noEmit` use over everything
|
|
15
|
+
* - publish-only counterparts, covering just what gets published
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* Either publish config can sit in the package root or in `config/`.
|
|
18
|
+
*
|
|
19
|
+
* These tests generate a real library,
|
|
20
|
+
* put the configs in each of those places,
|
|
21
|
+
* and run the real `pnpm build`.
|
|
19
22
|
*/
|
|
20
23
|
|
|
21
24
|
/**
|
|
22
|
-
* A development babel config
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
+
* A development babel config.
|
|
26
|
+
*
|
|
27
|
+
* Strips TypeScript, but leaves `<template>` as the
|
|
28
|
+
* `@ember/template-compiler` call content-tag produced.
|
|
29
|
+
*
|
|
30
|
+
* Publishing this output ties the artifact to one exact ember-source.
|
|
25
31
|
*/
|
|
26
32
|
const devBabelConfig = `export default {
|
|
27
33
|
plugins: [
|
|
@@ -31,8 +37,10 @@ const devBabelConfig = `export default {
|
|
|
31
37
|
`;
|
|
32
38
|
|
|
33
39
|
/**
|
|
34
|
-
* A publish babel config
|
|
35
|
-
*
|
|
40
|
+
* A publish babel config.
|
|
41
|
+
*
|
|
42
|
+
* Compiles templates to `precompileTemplate`, which is what a published library ships.
|
|
43
|
+
* The consuming app does the final compile.
|
|
36
44
|
*/
|
|
37
45
|
const publishBabelConfig = `export default {
|
|
38
46
|
plugins: [
|
|
@@ -44,11 +52,14 @@ const publishBabelConfig = `export default {
|
|
|
44
52
|
`;
|
|
45
53
|
|
|
46
54
|
/**
|
|
47
|
-
* The `tsconfig.json` such a library actually has
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
55
|
+
* The `tsconfig.json` such a library actually has.
|
|
56
|
+
*
|
|
57
|
+
* It covers the demo app as well as `src`,
|
|
58
|
+
* and deliberately has no `isolatedDeclarations`:
|
|
59
|
+
* dev-only code must not be held to a declaration-emit constraint.
|
|
60
|
+
*
|
|
61
|
+
* If the build reads this file rather than the publish tsconfig, the guard fails it.
|
|
62
|
+
* That is what makes every assertion below meaningful.
|
|
52
63
|
*/
|
|
53
64
|
const devTsconfig = `{
|
|
54
65
|
"extends": "@ember/library-tsconfig",
|
|
@@ -61,8 +72,8 @@ const devTsconfig = `{
|
|
|
61
72
|
`;
|
|
62
73
|
|
|
63
74
|
/**
|
|
64
|
-
* Relative paths in a tsconfig resolve against the file itself,
|
|
65
|
-
* kept in `config/` has to reach back out to `src`.
|
|
75
|
+
* Relative paths in a tsconfig resolve against the file itself,
|
|
76
|
+
* so the copy kept in `config/` has to reach back out to `src`.
|
|
66
77
|
*/
|
|
67
78
|
function publishTsconfig(directory: "." | "config"): string {
|
|
68
79
|
const src = directory === "config" ? "../src" : "./src";
|
|
@@ -211,9 +222,9 @@ describe("publish configs", () => {
|
|
|
211
222
|
// ...and the dev config, which has no template compilation, did not.
|
|
212
223
|
expect(output).not.toContain("@ember/template-compiler");
|
|
213
224
|
|
|
214
|
-
// Declarations emitted, so the guard read the publish tsconfig
|
|
215
|
-
// dev tsconfig.json covering demo-app/ has no isolatedDeclarations
|
|
216
|
-
// would have failed the build.
|
|
225
|
+
// Declarations emitted, so the guard read the publish tsconfig.
|
|
226
|
+
// The dev tsconfig.json covering demo-app/ has no isolatedDeclarations,
|
|
227
|
+
// and would have failed the build.
|
|
217
228
|
expect(await listFiles(join(project.directory, "dist"))).toContain("index.d.ts");
|
|
218
229
|
});
|
|
219
230
|
}
|
|
@@ -224,17 +235,18 @@ describe("publish configs", () => {
|
|
|
224
235
|
|
|
225
236
|
expect(build.exitCode, build.all).toBe(0);
|
|
226
237
|
|
|
227
|
-
// Nothing compiled the template, so content-tag's output survives
|
|
228
|
-
// artifact you don't want to publish
|
|
238
|
+
// Nothing compiled the template, so content-tag's output survives.
|
|
239
|
+
// That is the artifact you don't want to publish: the reason the preference exists.
|
|
229
240
|
expect(output).toContain("@ember/template-compiler");
|
|
230
241
|
expect(output).not.toContain("precompileTemplate");
|
|
231
242
|
});
|
|
232
243
|
|
|
233
244
|
/**
|
|
234
|
-
* Writes `files` into the project and builds with `tsconfigOption` as tsdown's
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
245
|
+
* Writes `files` into the project and builds with `tsconfigOption` as tsdown's `tsconfig`.
|
|
246
|
+
* For the cases about *which* tsconfig the guard ends up reading.
|
|
247
|
+
*
|
|
248
|
+
* The publish babel config is always present,
|
|
249
|
+
* so these fail for tsconfig reasons only.
|
|
238
250
|
*/
|
|
239
251
|
async function buildWithTsconfigOption(
|
|
240
252
|
tsconfigOption: string,
|
|
@@ -295,9 +307,10 @@ describe("publish configs", () => {
|
|
|
295
307
|
});
|
|
296
308
|
|
|
297
309
|
it("rejects tsconfig: false while declarations are on", async () => {
|
|
298
|
-
// No tsconfig means no isolatedDeclarations,
|
|
299
|
-
//
|
|
300
|
-
//
|
|
310
|
+
// No tsconfig means no isolatedDeclarations,
|
|
311
|
+
// so tsdown falls back to the tsc-based pipeline.
|
|
312
|
+
// That pipeline can't see compiled .gts and dies with "Source file not found".
|
|
313
|
+
// Fail with something actionable instead.
|
|
301
314
|
const { build } = await buildWithTsconfigOption("false");
|
|
302
315
|
|
|
303
316
|
expect(build.exitCode).not.toBe(0);
|
|
@@ -6,9 +6,10 @@ import { dirname, join } from "node:path";
|
|
|
6
6
|
import { rewriteImportsToMatchFiles } from "#utils/rewrite-imports.js";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* Generation renames files (e.g. type removal turns .ts into .js),
|
|
10
|
-
* import specifiers are checked against the emitted project tree
|
|
11
|
-
*
|
|
9
|
+
* Generation renames files (e.g. type removal turns .ts into .js),
|
|
10
|
+
* so import specifiers are checked against the emitted project tree.
|
|
11
|
+
*
|
|
12
|
+
* Whatever file actually exists on disk wins.
|
|
12
13
|
*/
|
|
13
14
|
describe("rewriteImportsToMatchFiles", () => {
|
|
14
15
|
const dirs: string[] = [];
|
|
@@ -7,8 +7,8 @@ import { dirname, join } from "node:path";
|
|
|
7
7
|
import type { Project } from "ember.nvp";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* Integration test for building a library that uses ember-scoped-css
|
|
11
|
-
* `@nullvoxpopuli/ember-rolldown` (tsdown):
|
|
10
|
+
* Integration test for building a library that uses ember-scoped-css
|
|
11
|
+
* through `@nullvoxpopuli/ember-rolldown` (tsdown):
|
|
12
12
|
*
|
|
13
13
|
* - the `scopedCSS()` unplugin (ember-scoped-css/rollup) resolves and rewrites
|
|
14
14
|
* the `?scoped=` CSS requests the template transform injects
|
|
@@ -18,8 +18,10 @@ import type { Project } from "ember.nvp";
|
|
|
18
18
|
* `dist/style.css` and keeps the import in `dist/index.js`, so consuming
|
|
19
19
|
* apps load the styles through the module graph
|
|
20
20
|
*
|
|
21
|
-
* Covers all three authoring modes:
|
|
22
|
-
*
|
|
21
|
+
* Covers all three authoring modes:
|
|
22
|
+
* - co-located `.css`
|
|
23
|
+
* - inline `<style scoped>`
|
|
24
|
+
* - the `scopedClass` pseudo-helper in module code
|
|
23
25
|
*/
|
|
24
26
|
|
|
25
27
|
const source = {
|
|
@@ -19,7 +19,7 @@ describe("permutate", () => {
|
|
|
19
19
|
it("skips duplicate entries", () => {
|
|
20
20
|
const result = permutate(["a", "b", "b"]);
|
|
21
21
|
|
|
22
|
-
//
|
|
22
|
+
// Must not include ["a", "b"] twice
|
|
23
23
|
const count = result.filter((perm) => perm.join(",") === "a,b").length;
|
|
24
24
|
expect(count).toBe(1);
|
|
25
25
|
});
|
|
@@ -77,8 +77,8 @@ describe("permutate", () => {
|
|
|
77
77
|
expect(eslintCount).toBeLessThanOrEqual(1);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
//
|
|
81
|
-
//
|
|
80
|
+
// Expected permutations: ["a"], ["a", "eslint-foo"], ["a", "b"], etc.
|
|
81
|
+
// Never ["a", "eslint-foo", "eslint-bar"]
|
|
82
82
|
const hasMultipleEslint = result.some(
|
|
83
83
|
(perm) => perm.filter((item) => item.startsWith("eslint-")).length > 1,
|
|
84
84
|
);
|
package/test/test-helpers.ts
CHANGED
|
@@ -19,9 +19,11 @@ export const bases = [minimalApp, minimalAddon, minimalExtension, minimalCustomE
|
|
|
19
19
|
export const layers = await discoverLayers();
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* Layers in the same group are alternatives to each other
|
|
23
|
-
* config, one test framework)
|
|
24
|
-
*
|
|
22
|
+
* Layers in the same group are alternatives to each other
|
|
23
|
+
* (one eslint config, one test framework).
|
|
24
|
+
*
|
|
25
|
+
* Selecting two of them produces a broken project,
|
|
26
|
+
* so permutations never combine them.
|
|
25
27
|
*/
|
|
26
28
|
function exclusivityGroup(name: string): string | undefined {
|
|
27
29
|
if (name.startsWith("eslint-")) return "eslint";
|
|
@@ -190,9 +192,11 @@ export async function expectIsSetup(project: Project, layer: DiscoveredLayer) {
|
|
|
190
192
|
}
|
|
191
193
|
|
|
192
194
|
/**
|
|
193
|
-
* List every file under `directory` (recursively)
|
|
194
|
-
* to `directory`.
|
|
195
|
-
*
|
|
195
|
+
* List every file under `directory` (recursively),
|
|
196
|
+
* as sorted paths relative to `directory`.
|
|
197
|
+
*
|
|
198
|
+
* `node_modules` is always excluded.
|
|
199
|
+
* Pass `{ includeDist: false }` to also exclude the `dist/` build output.
|
|
196
200
|
*/
|
|
197
201
|
export async function listFiles(
|
|
198
202
|
directory: string,
|