-
Notifications
You must be signed in to change notification settings - Fork 280
Fix dependencies bundling for yarn workspaces #1564
Fix dependencies bundling for yarn workspaces #1564
Conversation
This improves the hack which gets rid of protagonist (i.e. C++ compilation of drafter, the API Blueprint parser). When we moved dredd-transactions to the monorepo, where dependencies are managed by yarn workspaces, the hack to get rid of protagonist stopped to work. The hack relies on 'bundledDependencies', but those stopped to work. 'npm pack' cannot find the dependencies to bundle if they're in the root 'node_modules' directory. 'yarn pack' doesn't work either, it has bugs and it doesn't support 'bundledDependencies' or the workspaces very well - see yarnpkg/yarn#6794 This change overcomes the limitation by improving the prepack.js script. It now iterates over the 'bundledDependencies' and symlinks them to the local 'node_modules' directory where 'npm pack' can pick them up. After packing is done, there's a new postpack.js script, which makes sure the symlinks get cleaned up. The resulting .tgz then contains the dependencies bundled - without protagonist.
…cy for some reason
d4f1532
to
23c43e6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The script itself is fine, but I feel terribly sorry we have to invent such a process to exclude a single dependency.
I will try to research this on Yarn side (it's pretty smart, and allows a few additional things when working with dependencies than npm does), but otherwise I would expect this to be fixed in drafter
. Such dependencies distribution is strange.
|
||
|
||
// make sure all bundled deps are accessible in the local 'node_modules' dir | ||
const packageData = readPackageJson(PACKAGE_DIR, 'package.json'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
readPackageJson
function requires 1 argument, given 2. I think you can remove 'package.json'
.
Theoretically, it's possible to use Yarn custom resolutions to hijack which version of
The question is whether Yarn supports such nested path (it's a 5th party dependency in the end). If it does, replacing the tarball that should get installed by a non-existing package should hack the packing and omit Edit: tried this, doesn't seem to be working. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overlooked a few unused things. Please adjust and let's merge :) Thanks.
Edit: Committed changes in 096a322.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, just a few comments.
function symlinkDependencyTreeToLocalNodeModules(dependencyName) { | ||
const localDependencyPath = path.join(PACKAGE_DIR, 'node_modules', dependencyName); | ||
if (!fs.existsSync(localDependencyPath)) { | ||
fs.symlinkSync(`../../../node_modules/${dependencyName}`, localDependencyPath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's better to get the root of the project here, instead of doing ../../..
in case we change the directories later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since dredd-transactions
package is always the direct child of the dredd/packages
, the only thing that is variable is the location of the prepack.js
script, which casts module requires.
I don't think it's worthy to invest time into this, as scripts
are purely technical, and touching them should raise expectations that things may break.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, the first argument of fs.symlinkSync()
must be a relative path from the resulting symlink's location:
https://nodejs.org/api/fs.html#fs_fs_symlink_target_path_type_callback
I wouldn't be too concerned about this as if things change, the smoke test is our insurance.
// get rid of protagonist everywhere | ||
[ | ||
path.join(PACKAGE_DIR, 'node_modules', 'protagonist'), | ||
path.join(PACKAGE_DIR, '..', '..', 'node_modules', 'protagonist'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here about root project dir.
3acd07e
to
2e203e0
Compare
Thanks for the additional fixes. I'm merging this. |
🚀 Why this change?
This improves the hack which gets rid of protagonist (i.e. C++ compilation of drafter, the API Blueprint parser). When we moved dredd-transactions to the monorepo, where dependencies are managed by yarn workspaces, the hack to get rid of protagonist stopped to work. The hack relies on 'bundledDependencies', but those stopped to work. 'npm pack' cannot find the dependencies to bundle if they're in the root 'node_modules' directory. 'yarn pack' doesn't work either, it has bugs and it doesn't support 'bundledDependencies' or the workspaces very well - see yarnpkg/yarn#6794
This change overcomes the limitation by improving the prepack.js script. It now iterates over the 'bundledDependencies' and symlinks them to the local 'node_modules' directory where 'npm pack' can pick them up. After packing is done, there's a new postpack.js script, which makes sure the symlinks get cleaned up. The resulting .tgz then contains the dependencies bundled - without protagonist.
📝 Related issues and Pull Requests
#1551
✅ What didn't I forget?
npm run lint