@icebreakers/monorepo-templates 1.2.0 → 1.3.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.
Files changed (65) hide show
  1. package/assets/.github/workflows/ci.yml +4 -4
  2. package/assets/.github/workflows/release.yml +10 -7
  3. package/assets/package.json +2 -1
  4. package/assets/pnpm-workspace.yaml +2 -9
  5. package/assets/renovate.json +0 -1
  6. package/assets-data.mjs +0 -1
  7. package/dist/cli.mjs +1 -1
  8. package/dist/index.mjs +1 -1
  9. package/dist/{prepare-CNCmvco-.mjs → prepare-D7eJqEqy.mjs} +21 -2
  10. package/package.json +5 -3
  11. package/templates/cli/package.json +1 -1
  12. package/templates/client/package.json +1 -1
  13. package/templates/server/package.json +1 -1
  14. package/templates/tsdown/package.json +1 -1
  15. package/templates/vitepress/.vitepress/config.ts +9 -119
  16. package/templates/vitepress/.vitepress/env.d.ts +1 -0
  17. package/templates/vitepress/.vitepress/home/content.ts +186 -0
  18. package/templates/vitepress/.vitepress/home/types.ts +65 -0
  19. package/templates/vitepress/.vitepress/navigation/routes.ts +138 -0
  20. package/templates/vitepress/.vitepress/seo.ts +40 -0
  21. package/templates/vitepress/.vitepress/theme/components/HomePage.vue +134 -0
  22. package/templates/vitepress/.vitepress/theme/home/foundation.css +180 -0
  23. package/templates/vitepress/.vitepress/theme/home/index.css +3 -0
  24. package/templates/vitepress/.vitepress/theme/home/responsive.css +49 -0
  25. package/templates/vitepress/.vitepress/theme/home/sections.css +153 -0
  26. package/templates/vitepress/.vitepress/theme/index.ts +9 -1
  27. package/templates/vitepress/ai/llms-txt.md +2 -2
  28. package/templates/vitepress/index.md +6 -60
  29. package/templates/vitepress/package.json +11 -4
  30. package/templates/vitepress/public/repoctl-doctor.png +0 -0
  31. package/templates/vitepress/repoctl/workflows.md +35 -0
  32. package/templates/vitepress/scripts/check-locales.ts +162 -0
  33. package/templates/vitepress/thinking.md +15 -0
  34. package/templates/vitepress/tools/changeset.md +17 -12
  35. package/templates/vitepress/tools/husky.md +41 -3
  36. package/templates/vitepress/tools/lint-staged.md +32 -5
  37. package/templates/vitepress/tools/pnpm.md +39 -7
  38. package/templates/vitepress/tools/renovate.md +27 -3
  39. package/templates/vitepress/tools/turborepo.md +33 -7
  40. package/templates/vitepress/tsconfig.json +7 -0
  41. package/templates/vitepress/why/examples/2.npm-basic-package/README.md +1 -1
  42. package/templates/vitepress/why/examples/3.npm-basic-package/README.md +1 -1
  43. package/templates/vitepress/why/how-to-reuse-js-code.md +36 -6
  44. package/templates/vitepress/why/js-cjs-mjs.md +31 -9
  45. package/templates/vitepress/why/js-keywords.md +33 -4
  46. package/templates/vitepress/why/modern/bundlers.md +37 -2
  47. package/templates/vitepress/why/modern/dts.md +44 -3
  48. package/templates/vitepress/why/modern/esm-vs-cjs.md +38 -3
  49. package/templates/vitepress/why/modern/index.md +33 -9
  50. package/templates/vitepress/why/modern/package-entry-points.md +33 -4
  51. package/templates/vitepress/why/modern/typescript.md +40 -4
  52. package/templates/vitepress/why/publish-basic-npm-package.md +37 -13
  53. package/templates/vitepress/why/what-is-npm-package.md +32 -3
  54. package/templates/vitepress/wrangler.jsonc +20 -3
  55. package/templates/vitepress/zh/ai/index.md +1 -1
  56. package/templates/vitepress/zh/ai/llms-txt.md +1 -1
  57. package/templates/vitepress/zh/index.md +6 -63
  58. package/templates/vitepress/zh/repoctl/workflows.md +35 -0
  59. package/templates/vitepress/zh/thinking.md +9 -6
  60. package/templates/vitepress/zh/why/examples/2.npm-basic-package/README.md +1 -1
  61. package/templates/vitepress/zh/why/examples/3.npm-basic-package/README.md +1 -1
  62. package/templates/vitepress/zh/why/index.md +38 -1
  63. package/templates/vue-lib/package.json +1 -1
  64. package/assets/.changeset/ledger.yaml +0 -51
  65. package/assets/netlify.toml +0 -14
@@ -1,15 +1,47 @@
1
1
  # pnpm
2
2
 
3
- pnpm owns workspace discovery, dependency installation, script execution, and versioning configuration.
3
+ pnpm is the package manager used by repoctl workspaces. Its workspace protocol, content-addressable store, and filter syntax make it a practical fit for repositories with several packages and applications.
4
+
5
+ ## Install dependencies
4
6
 
5
7
  ```bash
6
8
  pnpm install
7
- pnpm --filter <package> build
8
- pnpm -r test
9
- pnpm change
10
- pnpm change status
9
+ pnpm install --frozen-lockfile
11
10
  ```
12
11
 
13
- `pnpm-workspace.yaml` is the source of truth for package patterns and release groups. repoctl can diagnose missing patterns and synchronize recommended defaults, but pnpm remains the package manager.
12
+ Use the frozen form in CI. It proves that `package.json` files and the lockfile describe the same dependency graph.
13
+
14
+ ## Work with one workspace
15
+
16
+ ```bash
17
+ pnpm --filter repoctl build
18
+ pnpm --filter @icebreakers/monorepo test
19
+ pnpm --filter './packages/*' lint
20
+ ```
21
+
22
+ Filters are a routing tool, not a replacement for repository scripts. Prefer an existing package script over an ad hoc command when a task should be repeatable.
23
+
24
+ ## Link local packages
25
+
26
+ ```json
27
+ {
28
+ "dependencies": {
29
+ "@icebreakers/monorepo": "workspace:*"
30
+ }
31
+ }
32
+ ```
33
+
34
+ The `workspace:` protocol prevents accidentally resolving a local package from the public registry during development.
35
+
36
+ ## Operational guidance
37
+
38
+ - Pin the package manager in the root `package.json`.
39
+ - Commit `pnpm-lock.yaml` for applications and monorepos.
40
+ - Use `pnpm exec` for binaries supplied by the current workspace.
41
+ - Use `pnpm --filter` for a scoped package command and Turbo for graph-wide task orchestration.
42
+
43
+ ## Keep Reading
14
44
 
15
- Prefer exact workspace filters in automation and keep `packageManager` plus `engines.node` declared at the repository root.
45
+ - [Turborepo](./turborepo.md)
46
+ - [Managing A Monorepo](../monorepo/manage.md)
47
+ - [repoctl Commands](../repoctl/commands.md)
@@ -1,7 +1,31 @@
1
1
  # Renovate
2
2
 
3
- Renovate opens dependency update pull requests according to repository policy.
3
+ Renovate keeps dependencies current through reviewable pull requests. It is most useful when the configuration groups compatible updates, lets CI prove the upgrade, and avoids mixing unrelated ecosystem changes.
4
4
 
5
- Group related tooling updates, respect pnpm workspace constraints, and let the normal build, lint, typecheck, tsd, and test matrix validate each update. Avoid combining unrelated runtime and tooling upgrades when separate review makes regressions easier to isolate.
5
+ ## Repository policy
6
6
 
7
- repoctl does not replace Renovate. It provides the diagnostic and verification commands that Renovate pull requests can run consistently.
7
+ ```json
8
+ {
9
+ "extends": ["config:recommended", "group:allNonMajor"],
10
+ "rangeStrategy": "bump",
11
+ "automerge": true,
12
+ "automergeType": "pr"
13
+ }
14
+ ```
15
+
16
+ The repository groups compatible minor and patch updates. Cloudflare Workers tooling is grouped separately because Wrangler and its Vite plugin have a deliberate compatibility relationship.
17
+
18
+ ## Review an update
19
+
20
+ 1. Read the package release notes when the update changes build, test, or deployment tooling.
21
+ 2. Run the normal build and validation sequence against the updated lockfile.
22
+ 3. Check generated assets and package metadata for unexpected churn.
23
+ 4. Merge only after the configured checks prove the update is compatible.
24
+
25
+ Do not rely on commit-message directives for a retired deployment provider. Deployment behavior belongs in the active platform configuration and CI settings.
26
+
27
+ ## Keep Reading
28
+
29
+ - [pnpm](./pnpm.md)
30
+ - [Workflows and CI](../repoctl/workflows.md)
31
+ - [Troubleshooting](../repoctl/troubleshooting.md)
@@ -1,14 +1,40 @@
1
1
  # Turborepo
2
2
 
3
- Turborepo runs the monorepo task graph and caches repeatable work.
3
+ Turborepo turns package scripts into a dependency-aware task graph. repoctl workspaces use it for the repository-wide work that should be cached and run in dependency order.
4
+
5
+ ## Define task boundaries
6
+
7
+ ```json
8
+ {
9
+ "tasks": {
10
+ "build": { "dependsOn": ["^build"], "outputs": ["dist/**"] },
11
+ "test": { "dependsOn": ["build"], "outputs": ["coverage/**"] },
12
+ "typecheck": { "dependsOn": ["^typecheck"], "outputs": [] }
13
+ }
14
+ }
15
+ ```
16
+
17
+ `^build` means that a package must build its workspace dependencies before its own build starts. Declare outputs accurately so the cache can restore useful artifacts and ignore transient files.
18
+
19
+ ## Run graph-aware tasks
4
20
 
5
21
  ```bash
6
- pnpm build
7
- pnpm lint
8
- pnpm typecheck
9
- pnpm test
22
+ pnpm turbo run build
23
+ pnpm turbo run test --filter=repoctl
24
+ pnpm turbo run lint typecheck
10
25
  ```
11
26
 
12
- Root scripts delegate to `turbo run`. Package scripts define the actual build, lint, typecheck, and test commands; `turbo.json` defines dependencies, inputs, outputs, and cache behavior.
27
+ Use root scripts for the common entrypoints. The root script is the stable command people and CI should remember; Turbo remains the graph executor beneath it.
28
+
29
+ ## Cache with care
30
+
31
+ - Include configuration files that materially affect output in task inputs.
32
+ - Keep secrets out of cached output.
33
+ - Set `outputs: []` for validation-only tasks.
34
+ - Use `--force` only when diagnosing cache behavior.
35
+
36
+ ## Keep Reading
13
37
 
14
- Mark generated artifacts as task outputs and declare upstream dependencies such as `build` before tests that consume built packages.
38
+ - [pnpm](./pnpm.md)
39
+ - [Verification](../repoctl/checks.md)
40
+ - [Managing A Monorepo](../monorepo/manage.md)
@@ -9,6 +9,13 @@
9
9
  "skipLibCheck": true
10
10
  },
11
11
  "include": [
12
+ ".vitepress/home/**/*.ts",
13
+ ".vitepress/navigation/**/*.ts",
14
+ ".vitepress/seo.ts",
15
+ ".vitepress/theme/**/*.ts",
16
+ ".vitepress/theme/**/*.vue",
17
+ ".vitepress/env.d.ts",
18
+ "scripts/**/*.ts",
12
19
  "why/examples/2.npm-basic-package/src/**/*.ts",
13
20
  "why/examples/3.npm-basic-package/src/**/*.ts"
14
21
  ]
@@ -1 +1 @@
1
- https://repo.icebreaker.top/
1
+ https://repoctl.icebreaker.top/
@@ -1 +1 @@
1
- https://repo.icebreaker.top/
1
+ https://repoctl.icebreaker.top/
@@ -1,9 +1,39 @@
1
- # Reusing JavaScript Code
1
+ # Reusing JavaScript
2
2
 
3
- JavaScript code can be shared through source modules, workspace packages, or published npm packages. The right boundary depends on ownership and consumers.
3
+ Reuse source code through an explicit package boundary. Copying files between applications is fast once and expensive every time the shared behavior changes; a local workspace package makes ownership, versioning, and tests visible.
4
4
 
5
- - Use a local module for code owned by one package.
6
- - Use a workspace package when multiple projects in the same repository share versioned behavior.
7
- - Publish an npm package when external repositories need a stable public API.
5
+ ## Start with a workspace package
8
6
 
9
- In a pnpm workspace, declare internal dependencies with the `workspace:` protocol and let the package build produce explicit runtime and type entrypoints.
7
+ ```json
8
+ {
9
+ "dependencies": {
10
+ "@example/shared": "workspace:*"
11
+ }
12
+ }
13
+ ```
14
+
15
+ The workspace protocol uses the local package during development and protects the repository from accidentally resolving an unrelated registry version.
16
+
17
+ ## Export a narrow API
18
+
19
+ ```ts
20
+ export function normalizeName(value: string) {
21
+ return value.trim().toLowerCase()
22
+ }
23
+ ```
24
+
25
+ Keep the public entry point small. A shared package should expose behavior that has a real consumer, not a collection of unrelated helpers that happen to be nearby.
26
+
27
+ ## Choose the right reuse level
28
+
29
+ | Need | Better boundary |
30
+ | ---------------------------- | -------------------------------------- |
31
+ | Shared runtime behavior | A versioned package |
32
+ | Shared build and lint policy | A preset package or managed asset |
33
+ | Shared application feature | A feature package with clear ownership |
34
+ | One-off project setup | A template, not a dependency |
35
+
36
+ ## Keep Reading
37
+
38
+ - [What Is An npm Package?](./what-is-npm-package.md)
39
+ - [Template Systems](../monorepo/templates.md)
@@ -1,12 +1,34 @@
1
- # JavaScript Module Extensions
1
+ # JavaScript, CommonJS, and ESM Files
2
2
 
3
- Node.js uses file extensions and the nearest `package.json` `type` field to determine module format.
3
+ File extensions tell Node which module loader should read a file. Use them deliberately when a package publishes both module formats or when a script must work independently of the nearest `package.json`.
4
4
 
5
- | Extension | Meaning |
6
- | --------------- | --------------------------------------------- |
7
- | `.mjs` | Always ES module |
8
- | `.cjs` | Always CommonJS |
9
- | `.js` | Depends on `package.json` `type` |
10
- | `.mts` / `.cts` | TypeScript source with explicit module intent |
5
+ ## Extension rules
11
6
 
12
- For published libraries, make the package `exports` map explicit and test both import and require paths when both formats are supported.
7
+ | Extension | Module format |
8
+ | --------- | ----------------------------------------------------- |
9
+ | `.mjs` | ESM in every package |
10
+ | `.cjs` | CommonJS in every package |
11
+ | `.js` | Determined by the nearest `package.json` `type` field |
12
+
13
+ ```json
14
+ {
15
+ "type": "module"
16
+ }
17
+ ```
18
+
19
+ With this declaration, `.js` files are ESM. Use `.cjs` for CommonJS output such as a compatibility build or an older tooling configuration file.
20
+
21
+ ## Avoid ambiguous output
22
+
23
+ ```text
24
+ dist/index.js ESM output
25
+ dist/index.cjs CommonJS output
26
+ dist/index.d.ts Type declarations
27
+ ```
28
+
29
+ Connect these files through `exports`; do not ask consumers to infer a `dist` layout. A clear output layout also makes package tarball checks easier.
30
+
31
+ ## Keep Reading
32
+
33
+ - [ESM vs CommonJS](./modern/esm-vs-cjs.md)
34
+ - [Package Entry Points](./modern/package-entry-points.md)
@@ -1,7 +1,36 @@
1
- # ESM and CommonJS Runtime Globals
1
+ # JavaScript Runtime Keywords
2
2
 
3
- CommonJS provides `require`, `module`, `exports`, `__filename`, and `__dirname`. ES modules use `import`, `export`, `import.meta.url`, and `createRequire` when interoperability is required.
3
+ Modern JavaScript modules have different runtime globals depending on whether Node loads them as CommonJS or ESM. Know the boundary before copying code between build tools, scripts, and package entry points.
4
4
 
5
- Avoid assuming CommonJS globals exist inside ESM. Resolve file paths with `fileURLToPath(import.meta.url)` and prefer static imports so bundlers and type checkers can understand dependencies.
5
+ ## CommonJS values
6
6
 
7
- See [ESM vs CommonJS](./modern/esm-vs-cjs.md) for package-level guidance.
7
+ ```js
8
+ console.log(__filename)
9
+ console.log(__dirname)
10
+ console.log(require.main)
11
+ ```
12
+
13
+ These values are available in CommonJS modules. They are not automatically present in ESM files.
14
+
15
+ ## ESM equivalents
16
+
17
+ ```js
18
+ import path from 'node:path'
19
+ import { fileURLToPath } from 'node:url'
20
+
21
+ const filename = fileURLToPath(import.meta.url)
22
+ const dirname = path.dirname(filename)
23
+ ```
24
+
25
+ Use `import.meta.url` as the starting point for resolving files relative to an ESM module. Prefer explicit Node built-in imports such as `node:path` so bundlers and readers can identify runtime-only dependencies.
26
+
27
+ ## Keep code portable
28
+
29
+ - Keep filesystem access behind a small module when browser builds share source code.
30
+ - Do not use CommonJS globals in a package that declares `type: module`.
31
+ - Test generated ESM and CommonJS outputs independently when both are published.
32
+
33
+ ## Keep Reading
34
+
35
+ - [JavaScript, CommonJS, and ESM Files](./js-cjs-mjs.md)
36
+ - [Reusing JavaScript](./how-to-reuse-js-code.md)
@@ -1,5 +1,40 @@
1
1
  # Bundlers
2
2
 
3
- Library bundlers turn source modules into publishable runtime and declaration artifacts. The repository's TypeScript library asset uses [tsdown](https://github.com/sonofmagic/repoctl/tree/main/templates/tsdown), while the Vue library asset adds Vue-specific build and type checking.
3
+ Choose a bundler by the package boundary you need to ship. A library build needs reliable entry points and declarations; a component library also needs framework and CSS handling; an application build needs an optimized browser bundle.
4
4
 
5
- Configure entrypoints, external dependencies, output formats, source maps, and declarations according to the package contract. Applications and libraries have different goals: application builds optimize deployment; library builds preserve reusable public boundaries.
5
+ ## Current choices
6
+
7
+ | Tool | Good fit | Notes |
8
+ | ---------- | ----------------------------------------------- | ------------------------------------------------- |
9
+ | `tsdown` | TypeScript libraries and tooling | Produces modern library output with declarations |
10
+ | `vite` | Applications and component libraries | Strong development server and library mode |
11
+ | `rolldown` | Toolchains that need Rollup-compatible behavior | Evaluate ecosystem compatibility before migration |
12
+
13
+ The repoctl generic library template uses `tsdown`. Vue component libraries continue to use Vite library mode.
14
+
15
+ ## tsdown library configuration
16
+
17
+ :::code-group
18
+
19
+ ```ts [tsdown.config.ts]
20
+ import { defineConfig } from 'tsdown'
21
+
22
+ export default defineConfig({
23
+ entry: ['./src/index.ts'],
24
+ format: ['cjs', 'esm'],
25
+ dts: true,
26
+ clean: true,
27
+ target: 'node18',
28
+ })
29
+ ```
30
+
31
+ :::
32
+
33
+ ## Retired defaults
34
+
35
+ `tsup` and `unbuild` are not recommended for new repoctl templates. Existing projects can migrate when their build behavior and published artifacts are covered by tests. Do not rewrite a working package merely to follow a tooling trend.
36
+
37
+ ## Keep Reading
38
+
39
+ - [TypeScript](./typescript.md)
40
+ - [Package Entry Points](./package-entry-points.md)
@@ -1,7 +1,48 @@
1
1
  # Type Declarations
2
2
 
3
- Type declarations are part of a TypeScript package's public API.
3
+ Type declarations describe the public TypeScript contract of a JavaScript package. They must be generated from the same source and exported through the same public entry points as the runtime code.
4
4
 
5
- Generate `.d.ts` files from the same source revision as runtime output, point `types` and export conditions at files included in the tarball, and use `tsd` tests for important inference and error behavior.
5
+ ## Emit declarations
6
6
 
7
- Declaration bundling can simplify public output, but it must preserve module augmentation, generics, and referenced types. Always inspect the packed artifact rather than testing source imports alone.
7
+ ```json
8
+ {
9
+ "compilerOptions": {
10
+ "declaration": true,
11
+ "declarationMap": true,
12
+ "emitDeclarationOnly": false,
13
+ "outDir": "./dist"
14
+ }
15
+ }
16
+ ```
17
+
18
+ Bundlers such as tsdown can emit declaration files alongside runtime output. The important rule is that declaration paths are stable and match the package exports map.
19
+
20
+ ## Link types to exports
21
+
22
+ ```json
23
+ {
24
+ "exports": {
25
+ ".": {
26
+ "types": "./dist/index.d.ts",
27
+ "import": "./dist/index.js",
28
+ "require": "./dist/index.cjs"
29
+ }
30
+ }
31
+ }
32
+ ```
33
+
34
+ The top-level `types` field is useful for simple packages. Per-entry `types` declarations are necessary when a package exposes subpaths or format-specific output.
35
+
36
+ ## Test the public contract
37
+
38
+ ```bash
39
+ pnpm tsd
40
+ pnpm pack --dry-run
41
+ ```
42
+
43
+ Type tests should import from the package name, not a source file. That proves the declarations consumers receive are compatible with the documented API.
44
+
45
+ ## Keep Reading
46
+
47
+ - [Package Entry Points](./package-entry-points.md)
48
+ - [TypeScript](./typescript.md)
@@ -1,7 +1,42 @@
1
1
  # ESM vs CommonJS
2
2
 
3
- ES modules are the preferred format for new packages. CommonJS remains relevant when consumers or toolchains still require `require()`.
3
+ Node supports two JavaScript module systems. ESM uses `import` and `export`; CommonJS uses `require` and `module.exports`. A package can support both, but it must state how each consumer reaches the correct file.
4
4
 
5
- Choose ESM-only when your supported runtime matrix allows it. Publish dual formats only when the compatibility benefit justifies duplicate builds and interop testing.
5
+ ## Identify the format
6
6
 
7
- For dual packages, map `import`, `require`, and `types` conditions explicitly and test each consumer path. Avoid exporting different logical module instances from the two formats.
7
+ | Signal | Meaning |
8
+ | ------------------------------- | ------------------- |
9
+ | `.mjs` | Always ESM |
10
+ | `.cjs` | Always CommonJS |
11
+ | `.js` with `"type": "module"` | ESM |
12
+ | `.js` without that package type | CommonJS by default |
13
+
14
+ Avoid guessing from syntax alone. Node resolves a `.js` file from its extension and the nearest package boundary.
15
+
16
+ ## Publish both formats
17
+
18
+ ```json
19
+ {
20
+ "type": "module",
21
+ "exports": {
22
+ ".": {
23
+ "import": "./dist/index.js",
24
+ "require": "./dist/index.cjs"
25
+ }
26
+ }
27
+ }
28
+ ```
29
+
30
+ Use an exports map rather than asking consumers to reach into `dist`. It gives each module system an intentional entry point and prevents accidental private imports becoming a public API.
31
+
32
+ ## Interoperability rules
33
+
34
+ - Keep the package API identical across formats where possible.
35
+ - Test both `import` and `require` from a consumer fixture.
36
+ - Do not publish TypeScript source as the runtime entry point.
37
+ - Use `.cjs` for CommonJS output when the package itself declares `type: module`.
38
+
39
+ ## Keep Reading
40
+
41
+ - [Package Entry Points](./package-entry-points.md)
42
+ - [Type Declarations](./dts.md)
@@ -1,14 +1,38 @@
1
1
  # Modern Package Guide
2
2
 
3
- Modern packages should expose a small, explicit API and generate artifacts that match their declared contract.
3
+ A publishable package is more than a source folder. Consumers depend on its runtime format, type declarations, entry points, files list, and compatibility policy. This guide explains the decisions that keep those contracts explicit.
4
4
 
5
- ## Checklist
5
+ ## Start with the consumer
6
6
 
7
- - Choose ESM-only or intentional dual-package support.
8
- - Declare every public subpath in `exports`.
9
- - Emit and test type declarations.
10
- - Keep development-only files out of the package tarball.
11
- - Validate the supported Node and bundler matrix.
12
- - Record public changes through repository versioning.
7
+ Before choosing a bundler or module format, answer these questions:
13
8
 
14
- Start with [ESM vs CommonJS](./esm-vs-cjs.md), then review [entry points](./package-entry-points.md) and [declarations](./dts.md).
9
+ - Will consumers load the package through ESM, CommonJS, or both?
10
+ - Does the package ship runtime code, types, a CLI, or generated assets?
11
+ - Which Node versions must work?
12
+ - Should consumers import one public entry point or several intentional subpaths?
13
+
14
+ The answers define the package boundary. Tooling should implement that boundary, not invent it.
15
+
16
+ ## Recommended shape
17
+
18
+ ```text
19
+ src/ source code
20
+ dist/ generated ESM, CommonJS, and declaration files
21
+ package.json public metadata and exports map
22
+ README.md installation and usage contract
23
+ ```
24
+
25
+ Use `files` to publish only the built output and deliberately included documentation. Run `npm pack --dry-run` before publishing to inspect the actual package tarball.
26
+
27
+ ## Topics
28
+
29
+ - [ESM vs CommonJS](./esm-vs-cjs.md)
30
+ - [Type Declarations](./dts.md)
31
+ - [Package Entry Points](./package-entry-points.md)
32
+ - [Bundlers](./bundlers.md)
33
+ - [TypeScript](./typescript.md)
34
+
35
+ ## Keep Reading
36
+
37
+ - [What Is An npm Package?](../what-is-npm-package.md)
38
+ - [Publishing A Package](../publish-basic-npm-package.md)
@@ -1,17 +1,46 @@
1
1
  # Package Entry Points
2
2
 
3
- Use the `exports` field to define the package's supported public paths.
3
+ The `exports` field is the public map of a package. It selects files for ESM, CommonJS, types, and intentional subpath imports while preventing consumers from coupling to internal folders.
4
+
5
+ ## Define one primary entry
4
6
 
5
7
  ```json
6
8
  {
9
+ "name": "example-package",
7
10
  "exports": {
8
11
  ".": {
9
12
  "types": "./dist/index.d.ts",
10
- "import": "./dist/index.js"
11
- },
13
+ "import": "./dist/index.js",
14
+ "require": "./dist/index.cjs"
15
+ }
16
+ }
17
+ }
18
+ ```
19
+
20
+ Consumers can now use `import { feature } from 'example-package'` or `require('example-package')` without knowing your output layout.
21
+
22
+ ## Add a deliberate subpath
23
+
24
+ ```json
25
+ {
26
+ "exports": {
27
+ ".": "./dist/index.js",
28
+ "./cli": "./dist/cli.js",
12
29
  "./package.json": "./package.json"
13
30
  }
14
31
  }
15
32
  ```
16
33
 
17
- Do not rely on consumers reaching into undeclared internal files. Every exported path should have runtime output, types where applicable, and a compatibility test.
34
+ Each subpath is a public promise. Add one only when it has a stable purpose, documentation, and tests. Do not expose `./dist/*` as a shortcut around API design.
35
+
36
+ ## Verify consumers
37
+
38
+ - Test the root import and every documented subpath.
39
+ - Verify both ESM and CommonJS branches when both are published.
40
+ - Check `npm pack --dry-run` includes every exported file.
41
+ - Treat removing or changing a public subpath as a breaking change.
42
+
43
+ ## Keep Reading
44
+
45
+ - [ESM vs CommonJS](./esm-vs-cjs.md)
46
+ - [Type Declarations](./dts.md)
@@ -1,7 +1,43 @@
1
- # TypeScript Packages
1
+ # TypeScript
2
2
 
3
- Use TypeScript to validate source and to publish a precise consumer contract.
3
+ TypeScript gives a package one source language for implementation and public types. Build output should remain JavaScript plus declarations so consumers do not need your development compiler configuration.
4
4
 
5
- Keep the source typecheck separate from artifact generation, enable strict settings appropriate for libraries, and avoid path aliases that cannot be resolved by consumers. Vue packages should run `vue-tsc`; non-Vue TypeScript packages should run `tsc`.
5
+ ## Start with a strict package config
6
6
 
7
- Public type behavior belongs in `tsd` tests. Runtime tests should import built output so module resolution matches delivery.
7
+ ```jsonc
8
+ {
9
+ "compilerOptions": {
10
+ "target": "ES2020",
11
+ "module": "ESNext",
12
+ "moduleResolution": "bundler",
13
+ "strict": true,
14
+ "declaration": true,
15
+ "declarationMap": true,
16
+ "outDir": "./dist",
17
+ "skipLibCheck": true
18
+ },
19
+ "include": ["src"]
20
+ }
21
+ ```
22
+
23
+ Use a separate configuration only when an output format genuinely needs different compiler behavior. Prefer a bundler configuration for output strategy and keep the TypeScript configuration focused on source checking and declaration generation.
24
+
25
+ ## Build and test from artifacts
26
+
27
+ ```bash
28
+ pnpm build
29
+ pnpm typecheck
30
+ pnpm tsd
31
+ ```
32
+
33
+ Run type tests against the generated package contract. A source-only test can pass while the published declaration path or exports map is broken.
34
+
35
+ ## Runtime execution
36
+
37
+ For local scripts, `tsx` can run TypeScript without creating a development `dist` directory. That is convenient for tooling, but it is not a replacement for building libraries before testing the package that consumers install.
38
+
39
+ ## Keep Reading
40
+
41
+ - [Type Declarations](./dts.md)
42
+ - [Bundlers](./bundlers.md)
43
+ - [Publishing A Package](../publish-basic-npm-package.md)
@@ -1,19 +1,43 @@
1
- # Publishing An npm Package
1
+ # Publishing A Package
2
2
 
3
- 1. Define explicit runtime and type entrypoints.
4
- 2. Build the package and run tests against built artifacts.
5
- 3. Inspect `pnpm pack` output.
6
- 4. Record a change intent and verify the version plan.
7
- 5. Publish with provenance and the intended access level.
3
+ Publishing is the point where the repository's package contract becomes public. Build first, test the built artifacts, inspect the tarball, and publish only after the version intent and changelog describe the consumer-visible change.
4
+
5
+ ## Prepare the package
6
+
7
+ ```bash
8
+ pnpm --filter example-package build
9
+ pnpm --filter example-package typecheck
10
+ pnpm --filter example-package test
11
+ pnpm --filter example-package tsd
12
+ pnpm --filter example-package pack --pack-destination ../../artifacts
13
+ ```
14
+
15
+ Run the package commands against generated output where possible. A source-only test does not prove that `exports`, files, or declarations will resolve after installation.
16
+
17
+ ## Verify package metadata
18
+
19
+ ```json
20
+ {
21
+ "name": "example-package",
22
+ "version": "1.0.0",
23
+ "files": ["dist", "README.md", "LICENSE"],
24
+ "publishConfig": { "access": "public" }
25
+ }
26
+ ```
27
+
28
+ Use `npm pack --dry-run` to see what users receive. Confirm the runtime entry point, declaration files, README, and license are present.
29
+
30
+ ## Release through the repository workflow
8
31
 
9
32
  ```bash
10
- pnpm build
11
- pnpm lint
12
- pnpm typecheck
13
- pnpm tsd
14
- pnpm test
15
- pnpm pack
16
33
  pnpm change
34
+ pnpm version -r
35
+ pnpm publish -r
17
36
  ```
18
37
 
19
- Never publish template source workspaces that are intentionally marked `private: true`.
38
+ The version ledger preserves why the release exists. Do not manually edit a package version to bypass fixed-group or changelog rules.
39
+
40
+ ## Keep Reading
41
+
42
+ - [pnpm Versioning](../tools/changeset.md)
43
+ - [Modern Package Guide](./modern/)