Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: use a recursive helper to find named parent package #507

Merged
merged 4 commits into from
Nov 23, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/dry-seahorses-sin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/vite-plugin-svelte': patch
---

improve robustness of compile stats taking
2 changes: 1 addition & 1 deletion packages/vite-plugin-svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"kleur": "^4.1.5",
"magic-string": "^0.26.7",
"svelte-hmr": "^0.15.1",
"vitefu": "^0.2.1"
"vitefu": "^0.2.2"
},
"peerDependencies": {
"diff-match-patch": "^1.0.5",
Expand Down
91 changes: 52 additions & 39 deletions packages/vite-plugin-svelte/src/utils/vite-plugin-svelte-stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { log } from './log';
//eslint-disable-next-line node/no-missing-import
import { findClosestPkgJsonPath } from 'vitefu';
import { readFileSync } from 'fs';
import { dirname } from 'path';
import { performance } from 'perf_hooks';

interface Stat {
Expand Down Expand Up @@ -85,6 +86,31 @@ function formatPackageStats(pkgStats: PackageStats[]) {
return table;
}

async function parseClosestNamedPackage(
file: string,
dir?: string
): Promise<{ name: string; path: string }> {
const pkgPath = await findClosestPkgJsonPath(dir ?? file);
if (pkgPath) {
const name = JSON.parse(readFileSync(pkgPath, 'utf-8')).name;
if (!name) {
return parseClosestNamedPackage(file, dirname(pkgPath));
}
const path = pkgPath.replace(/package.json$/, '');
return { name, path };
} else {
// no package.json found with a name in it, give up.
const path = dirname(file) + '/';
bluwy marked this conversation as resolved.
Show resolved Hide resolved
log.debug.once(
`Encountered files outside a named package in ${path}, marking them as $unknown.`
);
return {
name: '$unknown',
path
};
}
}

export class VitePluginSvelteStats {
// package directory -> package name
private _packages: { path: string; name: string }[] = [];
Expand Down Expand Up @@ -133,54 +159,41 @@ export class VitePluginSvelteStats {
}

private async _finish(collection: StatCollection) {
collection.finished = true;
const now = performance.now();
collection.duration = now - collection.collectionStart;
const logResult = collection.options.logResult(collection);
if (logResult) {
await this._aggregateStatsResult(collection);
log.info(`${collection.name} done.`, formatPackageStats(collection.packageStats!));
}
// cut some ties to free it for garbage collection
const index = this._collections.indexOf(collection);
this._collections.splice(index, 1);
collection.stats.length = 0;
collection.stats = [];
if (collection.packageStats) {
collection.packageStats.length = 0;
collection.packageStats = [];
try {
collection.finished = true;
const now = performance.now();
collection.duration = now - collection.collectionStart;
const logResult = collection.options.logResult(collection);
if (logResult) {
await this._aggregateStatsResult(collection);
log.info(`${collection.name} done.`, formatPackageStats(collection.packageStats!));
}
// cut some ties to free it for garbage collection
const index = this._collections.indexOf(collection);
this._collections.splice(index, 1);
collection.stats.length = 0;
collection.stats = [];
if (collection.packageStats) {
collection.packageStats.length = 0;
collection.packageStats = [];
}
collection.start = () => () => {};
collection.finish = () => {};
} catch (e) {
// this should not happen, but stats taking also should not break the process
log.debug.once(`failed to finish stats for ${collection.name}`, e);
}
collection.start = () => () => {};
collection.finish = () => {};
}

private async _aggregateStatsResult(collection: StatCollection) {
const stats = collection.stats;
for (const stat of stats) {
let pkg = this._packages.find((p) => stat.file.startsWith(p.path));
if (!pkg) {
// check for package.json first
let pkgPath = await findClosestPkgJsonPath(stat.file);
if (pkgPath) {
let path = pkgPath?.replace(/package.json$/, '');
let name = JSON.parse(readFileSync(pkgPath, 'utf-8')).name;
if (!name) {
// some packages have nameless nested package.json
pkgPath = await findClosestPkgJsonPath(path);
if (pkgPath) {
path = pkgPath?.replace(/package.json$/, '');
name = JSON.parse(readFileSync(pkgPath, 'utf-8')).name;
}
}
if (path && name) {
pkg = { path, name };
this._packages.push(pkg);
}
}
pkg = await parseClosestNamedPackage(stat.file);
this._packages.push(pkg);
}
// TODO is it possible that we want to track files where there is no named packge.json as parent?
// what do we want to do for that, try to find common root paths for different stats?
stat.pkg = pkg?.name ?? '$unknown';
stat.pkg = pkg.name;
}

// group stats
Expand Down
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.