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

Allow bundleDependencies to be respected during pack #5966

Merged
merged 5 commits into from
Jul 25, 2018

Conversation

thoov
Copy link
Contributor

@thoov thoov commented Jun 10, 2018

Summary

Yarn pack does not include bundleDependencies during yarn pack. This was due to 3 issues:

  1. The normalized property is bundleDependencies and not bundledDependencies. This was causing the destructuring to always be undefined even if bundledDependencies or bundleDependencies were set in package.json.

  2. The way the filtering logic is constructed excludes node_modules from the 'search space'. This leads the filtering to attempt to find dependencies but cant because they were excluded.

  3. The logic was only set up to find the dependency but not that dependency's dependency tree. This would lead to an incomplete pack of the needed dependencies.

Fixing problem 1: was a simple property name change which you can see here: 8081ccd

For fixing problems 2 & 3: We take the specified bundleDependencies and construct the list of their dependency graphs. Once we have the list we figure out all of the needed files for each one of those (sub)dependencies. You can see that change here: 54830e4

Related Issue: #2636

Test plan

I ran this in comparison to npm pack on a few local projects of various sizes and compared the outputs and performance (right now there is also an issue with bundleDependecies and npm so we will need to use npm 5.3.0 as that is the last working version).

The outputs look correct but I do notice a perf hit compared to npm pack. This perf slowness does not seem to be related to these changes directly but on the library that created the tar. On larger projects that I tested it would take npm pack about 15 seconds and for yarn pack it was 45 seconds.

@buildsize
Copy link

buildsize bot commented Jun 10, 2018

File name Previous Size New Size Change
yarn-[version].noarch.rpm 925.41 KB 930.47 KB 5.06 KB (1%)
yarn-[version].js 4 MB 4.02 MB 23.5 KB (1%)
yarn-legacy-[version].js 4.16 MB 4.19 MB 23.61 KB (1%)
yarn-v[version].tar.gz 930.5 KB 935.81 KB 5.31 KB (1%)
yarn_[version]all.deb 685.19 KB 689.12 KB 3.93 KB (1%)

@arcanis
Copy link
Member

arcanis commented Jun 11, 2018

Pack-related tests seem to fail.

Btw, I'm a bit curious, what are you using bundleDependencies for?

@stefanpenner
Copy link
Contributor

Btw, I'm a bit curious, what are you using bundleDependencies for?

A deployable tarball.

@thoov
Copy link
Contributor Author

thoov commented Jun 12, 2018

@arcanis Tests should now be passing (except for appveyor but they seem to be failing before my change). As @stefanpenner said bundleDependencies are needed for us to create deployable tarball that is completely self contained.

@stefanpenner
Copy link
Contributor

@thoov mind comparing appveyer before/after and confirming its not worse then before? That should help the yarn maintainers a tad.

@thoov thoov force-pushed the yarn-pack-improvements branch from df2e6cb to 9479172 Compare June 13, 2018 02:35
@thoov
Copy link
Contributor Author

thoov commented Jun 13, 2018

@stefanpenner @arcanis Ok now tests are fully passing

@thoov
Copy link
Contributor Author

thoov commented Jun 27, 2018

@arcanis Could you provide a review or do you know who would be best to take a look at this PR?

@byF
Copy link

byF commented Jul 12, 2018

Can anyone review and approve this please?

let bundleDependenciesFiles = [];
if (bundleDependencies) {
for (const dependency of bundleDependencies) {
const dependencyList = depsFor(dependency, config.cwd);
Copy link
Member

Choose a reason for hiding this comment

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

What is this depsFor used for? Why can't we just walk the node_modules/${dependency} tree?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

depsFor simply returns a list of all of the dependencies for a given package so in a sense it is "walking the tree". I agree with your concerns about not adding unnecessary extra packages to the project. Do you know if yarn has a built in util for getting this info? If not I think it is safe to bring this package in.

Copy link
Member

@arcanis arcanis Jul 19, 2018

Choose a reason for hiding this comment

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

What I don't understand is: wouldn't something like this work without depsFor (pseudo code)?

const FOLDERS_IGNORE_NO_NODE_MODULES = new Set(FOLDERS_IGNORE);
FOLDERS_IGNORE_NO_NODE_MODULES.delete('node_modules');

for (const dependency of bundleDependencies) {
  const depPath = getPathForDependency(dependency);

  const filesForBundledDep = await fs.walk(depPath, null, new Set(FOLDERS_IGNORE_NO_NODE_MODULES));
  bundleDependenciesFiles = bundleDependenciesFiles.concat(filesForBundledDep);
}

Since walk would then traverse the whole node_modules tree and pack them all.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@arcanis The issue is that this pseudo code doesn't actually walk the dependency graph for a dependency and only walks the directory structure. If we have a dependency a which has b and c as dependencies we get this tree structure:

node_modules/a
node_modules/b
node_modules/c

And const depPath = getPathForDependency(dependency); would only walk node_modules/a and miss the other ones. Thats why I use depsFor as I need more than the "top" level bundled dependencies. Let me know if this make sense or if there is something I am missing.

Copy link
Member

Choose a reason for hiding this comment

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

I see, that makes sense. I'm not fond of adding a new dep, but I don't see an easy replacement at the moment, so we can start with that.

@arcanis
Copy link
Member

arcanis commented Jul 12, 2018

Hey, sorry for the delay, I'd like to know more about the depsFor function. It seems to come from a package without much usage, that itself uses dependencies without much usage. Unless there's a good reason to use it, I'd prefer to be careful about the dependencies we add to the project.

@thoov
Copy link
Contributor Author

thoov commented Jul 12, 2018

Thanks for the comments @arcanis. I left a response inline to your concern above.

let bundleDependenciesFiles = [];
if (bundleDependencies) {
for (const dependency of bundleDependencies) {
const dependencyList = depsFor(dependency, config.cwd);
Copy link
Member

@arcanis arcanis Jul 19, 2018

Choose a reason for hiding this comment

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

What I don't understand is: wouldn't something like this work without depsFor (pseudo code)?

const FOLDERS_IGNORE_NO_NODE_MODULES = new Set(FOLDERS_IGNORE);
FOLDERS_IGNORE_NO_NODE_MODULES.delete('node_modules');

for (const dependency of bundleDependencies) {
  const depPath = getPathForDependency(dependency);

  const filesForBundledDep = await fs.walk(depPath, null, new Set(FOLDERS_IGNORE_NO_NODE_MODULES));
  bundleDependenciesFiles = bundleDependenciesFiles.concat(filesForBundledDep);
}

Since walk would then traverse the whole node_modules tree and pack them all.

@arcanis arcanis merged commit dda0217 into yarnpkg:master Jul 25, 2018
@arcanis
Copy link
Member

arcanis commented Jul 25, 2018

Merged. Thanks!

thoov added a commit to thoov/yarn that referenced this pull request Jan 11, 2019
When running `yarn pack` with a bundledDependency yarn was throwing
an error: "error An unexpected error occurred: "Cannot find module \".\""."

This was due to yarn's cli.js being transpiled to on line 110321:

```
var thePackage = !(function webpackMissingModule() { var e = new Error("Cannot find module \".\""); e.code = 'MODULE_NOT_FOUND'; throw e; }());
```

This line comes from
[here](https://github.com/stefanpenner/hash-for-dep/blob/e849d3e2f0350810716a0e504c84603362229570/lib/pkg.js#L20)
and is a dynamic require. This commit impements a fix for this based on
the guidence from [this
issue](webpack/webpack#4175 (comment))

This code was originally added with yarnpkg#5966
thoov added a commit to thoov/yarn that referenced this pull request Jan 11, 2019
When running `yarn pack` with a bundledDependency yarn was throwing
an error: "error An unexpected error occurred: "Cannot find module \".\""."

This was due to yarn's cli.js being transpiled to on line 110321:

```
var thePackage = !(function webpackMissingModule() { var e = new Error("Cannot find module \".\""); e.code = 'MODULE_NOT_FOUND'; throw e; }());
```

This line comes from https://github.com/stefanpenner/hash-for-dep/blob/e849d3e2f0350810716a0e504c84603362229570/lib/pkg.js#L20
and is a dynamic require. This commit impements a fix for this based on the guidence from webpack/webpack#4175 (comment)

This code was originally added with yarnpkg#5966
thoov added a commit to thoov/yarn that referenced this pull request Jan 11, 2019
When running `yarn pack` with a bundledDependency yarn was throwing
an error: An unexpected error occurred: "Cannot find module \".\"".

This was due to yarn's cli.js being transpiled to on line 110321:

```
var thePackage = !(function webpackMissingModule() { var e = new Error("Cannot find module \".\""); e.code = 'MODULE_NOT_FOUND'; throw e; }());
```

This line comes from https://github.com/stefanpenner/hash-for-dep/blob/e849d3e2f0350810716a0e504c84603362229570/lib/pkg.js#L20
and is a dynamic require. This commit impements a fix for this based on the guidence from webpack/webpack#4175 (comment)

This code was originally added with yarnpkg#5966
thoov added a commit to thoov/yarn that referenced this pull request Jan 11, 2019
When running `yarn pack` with a bundledDependency yarn was throwing
an error: An unexpected error occurred: "Cannot find module \".\"".

This was due to yarn's cli.js being transpiled to on line 110321:

```
var thePackage = !(function webpackMissingModule() { var e = new Error("Cannot find module \".\""); e.code = 'MODULE_NOT_FOUND'; throw e; }());
```

This line comes from https://github.com/stefanpenner/hash-for-dep/blob/e849d3e2f0350810716a0e504c84603362229570/lib/pkg.js#L20
and is a dynamic require. This commit impements a fix for this based on the guidence from webpack/webpack#4175 (comment)

This code was originally added with yarnpkg#5966
arcanis pushed a commit that referenced this pull request Jan 14, 2019
* Fixing dynamic require missing from webpack

When running `yarn pack` with a bundledDependency yarn was throwing
an error: An unexpected error occurred: "Cannot find module \".\"".

This was due to yarn's cli.js being transpiled to on line 110321:

```
var thePackage = !(function webpackMissingModule() { var e = new Error("Cannot find module \".\""); e.code = 'MODULE_NOT_FOUND'; throw e; }());
```

This line comes from https://github.com/stefanpenner/hash-for-dep/blob/e849d3e2f0350810716a0e504c84603362229570/lib/pkg.js#L20
and is a dynamic require. This commit impements a fix for this based on the guidence from webpack/webpack#4175 (comment)

This code was originally added with #5966

* Update CHANGELOG.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants