Skip to content

Commit 2c905c5

Browse files
Stop calling npm install on each prepare of ng projects
During project preparation CLI's trying to detect if all dependencies from package.json are installed by listing contents of node_modules directory. In case any of them are missing, CLI calls `npm install` inside the project. This executes all postinstall scripts of the dependencies and leads to slower prepare (and also slower builds in lots of cases). The problem is that the code is reading the contents of node_modules directory, but scoped dependencies (used in all angular projects) are not in the root of node_modules. So in all Angular projects each prepare calls `npm install`. Fix the listing of the directories to include scoped packages, so in case everything is installed, CLI will not call npm install on the next preparation of the project.
1 parent 86ed0d3 commit 2c905c5

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

lib/services/plugins-service.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,21 @@ export class PluginsService implements IPluginsService {
145145
public ensureAllDependenciesAreInstalled(): IFuture<void> {
146146
return (() => {
147147
let installedDependencies = this.$fs.exists(this.nodeModulesPath).wait() ? this.$fs.readDirectory(this.nodeModulesPath).wait() : [];
148+
// Scoped dependencies are not on the root of node_modules,
149+
// so we have to list the contents of all directories, starting with @
150+
// and add them to installed dependencies, so we can apply correct comparison against package.json's dependencies.
151+
_(installedDependencies)
152+
.filter(dependencyName => _.startsWith(dependencyName, "@"))
153+
.each(scopedDependencyDir => {
154+
let contents = this.$fs.readDirectory(path.join(this.nodeModulesPath, scopedDependencyDir)).wait();
155+
installedDependencies = installedDependencies.concat(...contents.map(dependencyName => `${scopedDependencyDir}/${dependencyName}`));
156+
});
157+
148158
let packageJsonContent = this.$fs.readJson(this.getPackageJsonFilePath()).wait();
149159
let allDependencies = _.keys(packageJsonContent.dependencies).concat(_.keys(packageJsonContent.devDependencies));
150-
if (this.$options.force || _.difference(allDependencies, installedDependencies).length) {
160+
let notInstalledDependencies = _.difference(allDependencies, installedDependencies);
161+
if (this.$options.force || notInstalledDependencies.length) {
162+
this.$logger.trace("Npm install will be called from CLI. Force option is: ", this.$options.force, " Not installed dependencies are: ", notInstalledDependencies);
151163
this.$npm.install(this.$projectData.projectDir, this.$projectData.projectDir, { "ignore-scripts": this.$options.ignoreScripts }).wait();
152164
}
153165
}).future<void>()();

0 commit comments

Comments
 (0)