Files
Colum Ferry 732a08c77d chore(core): build nx to local dist and use nodenext (#34111)
## Current Behavior

The `nx` package compiles its TypeScript output to
`../../dist/packages/nx/` (relative to the package root), which places
build artifacts outside the package directory at the repo root level
(`dist/packages/nx/`). This makes the package structure harder to reason
about, complicates the build pipeline, and doesn't align with how most
packages organize their output.

The package uses `"module": "commonjs"` with basic module resolution,
which limits future migration paths toward ESM.

## Expected Behavior

The `nx` package now builds to a local `dist/` directory within the
package itself (`packages/nx/dist/`). This is a cleaner, more standard
layout — like having your tools in your own toolbox instead of scattered
across the workshop.

### Key changes:

**Build configuration (`packages/nx/tsconfig.lib.json`):**
- `outDir` changed from `../../dist/packages/nx` to `dist` (local to
package)
- `module` changed to `nodenext` with `moduleResolution: nodenext`
- Updated `include` patterns to explicitly list source directories

**Package entry points (`packages/nx/package.json`):**
- `bin` paths updated: `./bin/nx.js` → `./dist/bin/nx.js`
- Added `"type": "commonjs"` explicitly
- Added comprehensive `exports` map with `@nx/nx-source` condition for
dev/test resolution back to TS source
- Added `postinstall` path update to `./dist/bin/post-install`

**Module resolution fixes:**
- Created `src/utils/handle-import.ts` — a CJS-first import utility that
falls back to ESM `import()` for ESM-only packages, providing a single
migration point for future ESM work
- Converted dynamic `await import()` calls to
`require(require.resolve())` pattern where needed to satisfy `nodenext`
extension requirements
- Plugin worker spawn path now uses correct `.ts`/`.js` extension based
on runtime context (source vs compiled)

**Test infrastructure:**
- Added custom `jest-resolver.js` for the `nx` package that resolves
`nx/...` imports using the `@nx/nx-source` exports condition, so tests
run against TS source
- Updated `jest.preset.js` with SWC transformer configuration
- Added chalk mock for test compatibility

**CI and tooling:**
- Conformance check updated to build `workspace-plugin` first (the Nx
Cloud runner lacks `@swc-node/register` for TS resolution)
- Conformance rule paths in `nx.json` now point to compiled
`dist/workspace-plugin/src/...` output
- Added `dist` to eslint ignore patterns to prevent linting compiled
output
- Added workspace-plugin build target and updated its dependencies

**Other fixes:**
- Various import path fixes across `create-nx-workspace`, gradle, and
other packages to work with `nodenext` resolution
- Updated e2e test paths to reference the new dist location
- Fixed `.gitignore` and `.npmignore` for the new output structure

## Related Issue(s)

Internal infrastructure improvement — no external issue.

---------

Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Coly010 <Coly010@users.noreply.github.com>
Co-authored-by: FrozenPandaz <jasonjean1993@gmail.com>
2026-03-20 19:30:03 -04:00

42 lines
1.0 KiB
JavaScript

const fs = require('fs');
const { execSync } = require('child_process');
const p = process.argv[2];
const possibleInputPath = process.argv[3];
const possibleOutputPath = process.argv[4];
let sourceReadmePath = `packages/${p}/README.md`;
if (possibleInputPath && fs.existsSync(possibleInputPath)) {
sourceReadmePath = possibleInputPath;
}
// we need exception for linter
if (p === 'linter') {
sourceReadmePath = 'packages/eslint/README.md';
}
let r = fs.readFileSync(sourceReadmePath).toString();
r = r.replace(
`{{links}}`,
fs.readFileSync('scripts/readme-fragments/links.md')
);
r = r.replace(
`{{content}}`,
fs.readFileSync('scripts/readme-fragments/content.md')
);
r = r.replace(
`{{resources}}`,
fs.readFileSync('scripts/readme-fragments/resources.md')
);
const outputPath = possibleOutputPath ?? `dist/packages/${p}/README.md`;
console.log('WRITING', outputPath);
fs.writeFileSync(outputPath, r);
try {
execSync(`npx prettier --write "${outputPath}"`, { stdio: 'ignore' });
} catch {
// Ignore prettier errors — formatting is best-effort
}