Skip to content

Commit c41508c

Browse files
committed
feat: significantly improve CLI startup times
Move a few heavier modules from static imports to lazy `require()`s. Also remove support for globally installed addons via yarn *and* npm. If Yarn is detected, Denali will search Yarn for global addons, otherwise it wills search npm, but not both. This lets Yarn users avoid the delays that npm forces (because we need to shell out for `npm root`, which eats 500ms). We could make this behavior configurable in the future, once we have a ~/.denali config file
1 parent 1341067 commit c41508c

File tree

3 files changed

+16
-14
lines changed

3 files changed

+16
-14
lines changed

lib/blueprint.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { execSync, ExecSyncOptions } from 'child_process';
1212
import { sync as commandExists } from 'command-exists';
1313
import * as chalk from 'chalk';
1414
import * as walk from 'walk-sync';
15-
import * as codeshift from 'jscodeshift';
1615
import * as mkdirp from 'mkdirp';
1716
import * as rimraf from 'rimraf';
1817
import * as yargs from 'yargs';
@@ -330,6 +329,7 @@ export default class Blueprint extends Command {
330329
ui.warn(`Attempted to add "${ method.toUpperCase() } ${ urlPattern } -> ${ actionPath }" route, but config/routes.js does not exist. Skipping ...`);
331330
return;
332331
}
332+
const codeshift = require('jscodeshift');
333333
let j = codeshift;
334334
let ast = codeshift(routesSource);
335335
let drawRoutesFunction = ast.find(j.ExportDefaultDeclaration).get().value.declaration;
@@ -377,6 +377,7 @@ export default class Blueprint extends Command {
377377
ui.warn(`Attempted to remove "${ method.toUpperCase() } ${ urlPattern } -> ${ actionPath }" route, but config/routes.js does not exist. Skipping ...`);
378378
return;
379379
}
380+
const codeshift = require('jscodeshift');
380381
let j = codeshift;
381382
let ast = codeshift(routesSource);
382383
let drawRoutesFunction = ast.find(j.ExportDefaultDeclaration).get().value.declaration;

lib/find-addons.ts

+12-11
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,7 @@ export default function findAddons(isLocal: boolean): AddonSummary[] {
3838
return finalizeAddons(addons);
3939
}
4040

41-
let npmRoot = execSync('npm root -g').toString().trim();
42-
debug(`searching for addons globally in npm root: ${ npmRoot }`);
43-
let addons = findPlugins(merge({
44-
dir: npmRoot,
45-
scanAllDirs: true
46-
}, findOptions));
41+
let addons;
4742

4843
// Because yarn stores it's global modules separately, and doesn't yet support the `root` command,
4944
// we have to double check yarn's global installs for any denali addons. The easiest way of
@@ -52,13 +47,12 @@ export default function findAddons(isLocal: boolean): AddonSummary[] {
5247
// development of global addons (like denali itself)
5348
// TODO shell out to `yarn root` once yarnpkg/yarn#2388 is fixed
5449
if (commandExists('yarn')) {
55-
let yarnGlobalInstalls = path.join(YarnConstants.GLOBAL_MODULE_DIRECTORY, 'node_modules');
50+
let yarnGlobalInstalls = YarnConstants.GLOBAL_MODULE_DIRECTORY;
5651
debug(`searching for addons globally in yarn global installs: ${ yarnGlobalInstalls }`);
5752
if (fs.existsSync(yarnGlobalInstalls)) {
58-
addons = addons.concat(findPlugins(merge({
59-
dir: yarnGlobalInstalls,
60-
scanAllDirs: true
61-
}, findOptions)));
53+
addons = findPlugins(merge({
54+
dir: yarnGlobalInstalls
55+
}, findOptions));
6256
} else {
6357
debug(`Tried to load globally installed addons from yarn, but ${ yarnGlobalInstalls } doesn't exist, skipping ...`);
6458
}
@@ -72,6 +66,13 @@ export default function findAddons(isLocal: boolean): AddonSummary[] {
7266
} else {
7367
debug(`Tried to load globally linked addons from yarn, but ${ yarnGlobalLinks } doesn't exist, skipping ...`);
7468
}
69+
} else {
70+
let npmRoot = execSync('npm root -g').toString().trim();
71+
debug(`searching for addons globally in npm root: ${ npmRoot }`);
72+
addons = findPlugins(merge({
73+
dir: npmRoot,
74+
scanAllDirs: true
75+
}, findOptions));
7576
}
7677

7778
return finalizeAddons(addons);

lib/project.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import {
66
import * as path from 'path';
77
import * as fs from 'fs';
88
import * as dedent from 'dedent-js';
9-
import * as nsp from 'nsp';
10-
import * as broccoli from 'broccoli';
119
import * as rimraf from 'rimraf';
1210
import printSlowNodes from 'broccoli-slow-trees';
1311
import { sync as copyDereferenceSync } from 'copy-dereference';
@@ -168,6 +166,7 @@ export default class Project {
168166
this.rootTree = this.rootBuilder.toTree();
169167
}
170168

169+
const broccoli = require('broccoli');
171170
let broccoliBuilder = this.broccoliBuilder = new broccoli.Builder(this.rootTree);
172171
// tslint:disable-next-line:completed-docs
173172
function onExit() {
@@ -314,6 +313,7 @@ export default class Project {
314313
*/
315314
protected auditPackage() {
316315
debug('sending package.json to nsp for audit');
316+
const nsp = require('nsp');
317317
let pkg = path.join(this.dir, 'package.json');
318318
nsp.check({ package: pkg }, (err: any, vulnerabilities: Vulnerability[]) => {
319319
if (err && [ 'ENOTFOUND', 'ECONNRESET' ].indexOf(err.code) > -1) {

0 commit comments

Comments
 (0)