@williamthorsen/nmr 0.17.0 → 0.17.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.
- package/README.md +5 -5
- package/dist/esm/commands/build.d.ts +1 -1
- package/dist/esm/commands/build.js +24 -8
- package/package.json +1 -1
- package/dist/esm/.cache +0 -1
package/README.md
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
Context-aware script runner for PNPM monorepos. Ships an `nmr` (node-monorepo run) binary that provides centralized, consistent script execution across workspace packages and the monorepo root.
|
|
4
4
|
|
|
5
5
|
<!-- section:release-notes -->
|
|
6
|
-
## Release notes — v0.17.
|
|
6
|
+
## Release notes — v0.17.1 (2026-07-01)
|
|
7
7
|
|
|
8
|
-
###
|
|
8
|
+
### 🐛 Bug fixes
|
|
9
9
|
|
|
10
|
-
-
|
|
10
|
+
- Relocate nmr-compile's build cache out of the published dist (#457)
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Fixes an issue where packages built with nmr-compile shipped an internal build-cache file inside their published npm tarball.
|
|
13
13
|
<!-- /section:release-notes -->
|
|
14
14
|
|
|
15
15
|
## Installation
|
|
@@ -345,7 +345,7 @@ nmr sync-pnpm-version
|
|
|
345
345
|
|
|
346
346
|
### `nmr-compile`
|
|
347
347
|
|
|
348
|
-
Compile a single package's `src` tree to `dist/esm` with the TypeScript compiler API, emitting `.js` and `.d.ts` in one pass. Because the compiler parses each source file, every relative import form — static, re-export, dynamic `import()`, and bare side-effect — is rewritten from `.ts` to `.js` in both outputs, and `.ts` occurrences inside strings and comments are left intact. tsconfig `paths` aliases are resolved to runnable relative `.js` specifiers in both outputs, sourced from the package's tsconfig. The build is skipped when no input has changed (a content-and-path hash is cached
|
|
348
|
+
Compile a single package's `src` tree to `dist/esm` with the TypeScript compiler API, emitting `.js` and `.d.ts` in one pass. Because the compiler parses each source file, every relative import form — static, re-export, dynamic `import()`, and bare side-effect — is rewritten from `.ts` to `.js` in both outputs, and `.ts` occurrences inside strings and comments are left intact. tsconfig `paths` aliases are resolved to runnable relative `.js` specifiers in both outputs, sourced from the package's tsconfig. The build is skipped when no input has changed (a content-and-path hash is cached under `node_modules/.cache/nmr-compile/`, outside the published output). This is the default `compile` script — run it from a package directory.
|
|
349
349
|
|
|
350
350
|
`typescript` is a peer dependency (`>=5.7.0`, required for `rewriteRelativeImportExtensions`); the consuming repo provides it. Relative imports in source must carry explicit `.ts` extensions for them to be rewritten.
|
|
351
351
|
|
|
@@ -2,8 +2,8 @@ export interface BuildOptions {
|
|
|
2
2
|
entryGlobs?: string[];
|
|
3
3
|
ignore?: string[];
|
|
4
4
|
outdir?: string;
|
|
5
|
-
cacheFile?: string;
|
|
6
5
|
}
|
|
7
6
|
export declare function buildPackage(packageDir: string, options?: BuildOptions): Promise<void>;
|
|
8
7
|
export declare function computeBuildHash(packageDir: string, files: string[], emitConfig: object): Promise<string>;
|
|
9
8
|
export declare function resolveTsconfigChain(packageDir: string, configFileName?: string): string[];
|
|
9
|
+
export declare function resolveBuildCachePath(packageDir: string): string;
|
|
@@ -9,7 +9,6 @@ const SKIPPED_ICON = '⏭️';
|
|
|
9
9
|
const DEFAULT_ENTRY_GLOBS = ['src/**/*.ts'];
|
|
10
10
|
const DEFAULT_IGNORE = ['**/__tests__/**'];
|
|
11
11
|
const DEFAULT_OUTDIR = 'dist/esm/';
|
|
12
|
-
const DEFAULT_CACHE_FILE = 'dist/esm/.cache';
|
|
13
12
|
const SOURCE_ROOT = 'src';
|
|
14
13
|
const MINIMUM_TYPESCRIPT_MAJOR = 5;
|
|
15
14
|
const MINIMUM_TYPESCRIPT_MINOR = 7;
|
|
@@ -17,7 +16,7 @@ const TS_EXTENSION = '.ts';
|
|
|
17
16
|
const JS_EXTENSION = '.js';
|
|
18
17
|
export async function buildPackage(packageDir, options = {}) {
|
|
19
18
|
assertSupportedTypeScript();
|
|
20
|
-
const
|
|
19
|
+
const cachePath = resolveBuildCachePath(packageDir);
|
|
21
20
|
const outdir = options.outdir ?? DEFAULT_OUTDIR;
|
|
22
21
|
const emitConfig = { outdir, declaration: true, rewriteRelativeImportExtensions: true };
|
|
23
22
|
const entryPoints = await glob(options.entryGlobs ?? DEFAULT_ENTRY_GLOBS, {
|
|
@@ -25,12 +24,12 @@ export async function buildPackage(packageDir, options = {}) {
|
|
|
25
24
|
ignore: options.ignore ?? DEFAULT_IGNORE,
|
|
26
25
|
});
|
|
27
26
|
const dependencies = ['package.json', ...resolveTsconfigChain(packageDir)];
|
|
28
|
-
const { changed, currentHash } = await detectBuildChanges(packageDir, [...entryPoints, ...dependencies], emitConfig,
|
|
27
|
+
const { changed, currentHash } = await detectBuildChanges(packageDir, [...entryPoints, ...dependencies], emitConfig, cachePath);
|
|
29
28
|
if (!changed) {
|
|
30
29
|
return;
|
|
31
30
|
}
|
|
32
31
|
emitPackage(packageDir, entryPoints, outdir);
|
|
33
|
-
await writeBuildCache(
|
|
32
|
+
await writeBuildCache(cachePath, currentHash);
|
|
34
33
|
}
|
|
35
34
|
export async function computeBuildHash(packageDir, files, emitConfig) {
|
|
36
35
|
const hash = createHash('sha256');
|
|
@@ -181,9 +180,27 @@ function getModuleSpecifier(node) {
|
|
|
181
180
|
}
|
|
182
181
|
return undefined;
|
|
183
182
|
}
|
|
184
|
-
|
|
183
|
+
export function resolveBuildCachePath(packageDir) {
|
|
184
|
+
const absolutePackageDir = path.resolve(packageDir);
|
|
185
|
+
const home = findNearestNodeModulesHost(absolutePackageDir) ?? absolutePackageDir;
|
|
186
|
+
const digest = createHash('sha256').update(absolutePackageDir).digest('hex').slice(0, 8);
|
|
187
|
+
const key = `${path.basename(absolutePackageDir)}-${digest}.hash`;
|
|
188
|
+
return path.join(home, 'node_modules', '.cache', 'nmr-compile', key);
|
|
189
|
+
}
|
|
190
|
+
function findNearestNodeModulesHost(startDir) {
|
|
191
|
+
let current = startDir;
|
|
192
|
+
let parent = path.dirname(current);
|
|
193
|
+
while (!existsSync(path.join(current, 'node_modules'))) {
|
|
194
|
+
if (parent === current) {
|
|
195
|
+
return undefined;
|
|
196
|
+
}
|
|
197
|
+
current = parent;
|
|
198
|
+
parent = path.dirname(current);
|
|
199
|
+
}
|
|
200
|
+
return current;
|
|
201
|
+
}
|
|
202
|
+
async function detectBuildChanges(packageDir, files, emitConfig, cachePath) {
|
|
185
203
|
const packageName = path.basename(packageDir);
|
|
186
|
-
const cachePath = path.join(packageDir, cacheFile);
|
|
187
204
|
const previousHash = existsSync(cachePath) ? readFileSync(cachePath, 'utf8') : undefined;
|
|
188
205
|
const currentHash = await computeBuildHash(packageDir, files, emitConfig);
|
|
189
206
|
if (previousHash === currentHash) {
|
|
@@ -193,8 +210,7 @@ async function detectBuildChanges(packageDir, files, emitConfig, cacheFile) {
|
|
|
193
210
|
console.info(`${PACKAGE_ICON} ${packageName}: Changes detected.`);
|
|
194
211
|
return { changed: true, currentHash };
|
|
195
212
|
}
|
|
196
|
-
async function writeBuildCache(
|
|
197
|
-
const cachePath = path.join(packageDir, cacheFile);
|
|
213
|
+
async function writeBuildCache(cachePath, hash) {
|
|
198
214
|
await mkdir(path.dirname(cachePath), { recursive: true });
|
|
199
215
|
await writeFile(cachePath, hash);
|
|
200
216
|
}
|
package/package.json
CHANGED
package/dist/esm/.cache
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
49f79592247d14646b1445473aa445a8bcbeafb478c6dc9949eb31cee8e2a627
|