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

[rush] Install optional dependencies, except when using npm<5.0.0 #878

Merged
merged 1 commit into from
Oct 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 21 additions & 20 deletions apps/rush-lib/src/logic/InstallManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -781,23 +781,6 @@ export class InstallManager {
}

// Run "npm install" in the common folder

// NOTE:
// we do NOT install optional dependencies for Rush, as it seems that optional dependencies do not
// work properly with shrinkwrap. Consider the "fsevents" package. This is a Mac specific package
// which is an optional second-order dependency. Optional dependencies work by attempting to install
// the package, but removes the package if the install failed.
// This means that someone running generate on a Mac WILL have fsevents included in their shrinkwrap.
// When someone using Windows attempts to install from the shrinkwrap, the install will fail.
//
// If someone generates the shrinkwrap using Windows, then fsevents will NOT be listed in the shrinkwrap.
// When someone using Mac attempts to install from the shrinkwrap, (as of NPM 4), they will NOT have the
// optional dependency installed.
//
// One possible solution would be to have the shrinkwrap include information about whether the dependency
// is optional or not, but it does not appear to do so. Also, this would result in strange behavior where
// people would have different node_modules based on their system.

const installArgs: string[] = [ 'install' ];
this._pushConfigurationArgs(installArgs, options);

Expand Down Expand Up @@ -975,15 +958,34 @@ export class InstallManager {
*/
private _pushConfigurationArgs(args: string[], options: IInstallManagerOptions): void {
if (this._rushConfiguration.packageManager === 'npm') {
args.push('--no-optional');
if (semver.lt(this._rushConfiguration.packageManagerToolVersion, '5.0.0')) {
// NOTE:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept this comment (which was originally added in #175), reworded it a bit, and added a couple useful links. lmk if I should change anything else here.

//
// When using an npm version older than v5.0.0, we do NOT install optional dependencies for
// Rush, because npm does not generate the shrinkwrap file consistently across platforms.
//
// Consider the "fsevents" package. This is a Mac specific package
// which is an optional second-order dependency. Optional dependencies work by attempting to install
// the package, but removes the package if the install failed.
// This means that someone running generate on a Mac WILL have fsevents included in their shrinkwrap.
// When someone using Windows attempts to install from the shrinkwrap, the install will fail.
//
// If someone generates the shrinkwrap using Windows, then fsevents will NOT be listed in the shrinkwrap.
// When someone using Mac attempts to install from the shrinkwrap, they will NOT have the
// optional dependency installed.
//
// This issue has been fixed as of npm v5.0.0: https://github.com/npm/npm/releases/tag/v5.0.0
//
// For more context, see https://github.com/Microsoft/web-build-tools/issues/761#issuecomment-428689600
args.push('--no-optional');
}
args.push('--cache', this._rushConfiguration.npmCacheFolder);
args.push('--tmp', this._rushConfiguration.npmTmpFolder);

if (options.collectLogFile) {
args.push('--verbose');
}
} else if (this._rushConfiguration.packageManager === 'pnpm') {
args.push('--no-optional');
args.push('--store', this._rushConfiguration.pnpmStoreFolder);

// we are using the --no-lock flag for now, which unfortunately prints a warning, but should be OK
Expand All @@ -1009,7 +1011,6 @@ export class InstallManager {
args.push('--strict-peer-dependencies');
}
} else if (this._rushConfiguration.packageManager === 'yarn') {
args.push('--ignore-optional');
args.push('--link-folder', 'yarn-link');
args.push('--cache-folder', this._rushConfiguration.yarnCacheFolder);

Expand Down
2 changes: 1 addition & 1 deletion apps/rush-lib/src/logic/npm/NpmLinkManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ export class NpmLinkManager extends BaseLinkManager {
throw Error(`The dependency "${dependency.name}" needed by "${localPackage.name}"`
+ ` was not found in the common folder -- do you need to run "rush install"?`);
} else {
console.log(colors.yellow('Skipping optional dependency: ' + dependency.name));
console.log('Skipping optional dependency: ' + dependency.name);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"comment": "Install optional dependencies, except w/ npm<5.0.0",
"packageName": "@microsoft/rush",
"type": "none"
}
],
"packageName": "@microsoft/rush",
"email": "elliottsj@users.noreply.github.com"
}