Skip to content

Commit 830c343

Browse files
authored
test: speed up npm bootstrap (#954)
1 parent 2754047 commit 830c343

File tree

1 file changed

+50
-3
lines changed

1 file changed

+50
-3
lines changed

@packages/test/src/npm.ts

+50-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,62 @@
1-
import execa from 'execa';
21
import path from 'path';
32
import fs from 'fs-extra';
3+
import resolvePkg from 'resolve-pkg';
44

55
import * as git from './git';
66

77
export async function bootstrap(fixture: string, directory?: string) {
88
const cwd = await git.bootstrap(fixture, directory);
9+
const manifestPath = path.join(cwd, 'package.json');
10+
const targetModulesPath = path.join(cwd, 'node_modules');
911

10-
if (await fs.pathExists(path.join(cwd, 'package.json'))) {
11-
await execa('npm', ['install'], {cwd});
12+
if (await fs.pathExists(manifestPath)) {
13+
const {dependencies = {}, devDependencies = {}} = await fs.readJson(
14+
manifestPath
15+
);
16+
const deps = Object.keys({...dependencies, ...devDependencies});
17+
await Promise.all(
18+
deps.map(async (dependency: any) => {
19+
const sourcePath = resolvePkg(dependency);
20+
21+
if (!sourcePath) {
22+
throw new Error(`Could not resolve dependency ${dependency}`);
23+
}
24+
25+
const sourceModulesPath = findParentPath(sourcePath, 'node_modules');
26+
27+
if (!sourceModulesPath) {
28+
throw new Error(`Could not determine node_modules for ${sourcePath}`);
29+
}
30+
31+
const relativePath = path.relative(sourceModulesPath, sourcePath);
32+
const targetPath = path.join(targetModulesPath, relativePath);
33+
34+
await fs.mkdirp(path.join(targetPath, '..'));
35+
await fs.symlink(sourcePath, targetPath);
36+
})
37+
);
1238
}
1339

1440
return cwd;
1541
}
42+
43+
function findParentPath(path: string, dirname: string): string | undefined {
44+
const rawFragments = path.split('/');
45+
46+
const {matched, fragments} = rawFragments.reduceRight(
47+
({fragments, matched}, item) => {
48+
if (item === dirname && !matched) {
49+
return {fragments, matched: true};
50+
}
51+
52+
if (!matched && fragments.length > 0) {
53+
fragments.pop();
54+
}
55+
56+
return {fragments, matched};
57+
},
58+
{fragments: rawFragments, matched: false}
59+
);
60+
61+
return matched ? fragments.join('/') : undefined;
62+
}

0 commit comments

Comments
 (0)