@darkobits/clean-link

Improved 'npm link'.

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
@darkobits/clean-link
0142.0.16 years ago6 years agoMinified + gzip package size for @darkobits/clean-link in KB

Readme

Install
npm install --save-dev @darkobits/clean-link

Then, use the clean-link-dir script anywhere in your package scripts. See below for an example.
Use
npm link is a handy utility for developing libraries / frameworks / tooling and ensuring they work with their dependents.
Given a hypothetical library, foo-lib, and a hypothetical dependent, bar-app, a common workflow involves something like the following:
  1. Run npm link from the foo-lib project folder.
  2. Start foo-lib's build script in watch mode.
  3. Run npm link foo-lib from the bar-app project folder.
  4. Make changes to foo-lib's source.
  5. Verify these changes didn't break anything in bar-app.
  6. ????
  7. Profit!! 💰

This nice workflow can get a little wonky under certain circumstances, however. Consider the following case:
  • bar-app is compiled with Babel 6.x.
  • foo-lib is compiled with Babel 7.x.
  • foo-lib is npm link-ed into bar-app.

If you try to run bar-app, you will get the following error:
Error: Requires Babel "^7.x.x", but was loaded with "6.x.x". If you are sure you
have a compatible version of @babel/core, it is likely that something in your
build process is loading the wrong version. Inspect the stack trace of this
error to look for the first entry that doesn't mention "@babel/core" or
"babel-core" to see what is calling Babel.

That's definitely a bad-timebad-time-url, mate. What's going on here? We don't need the files for foo-lib transpiled, they already have been!
This is happening because the copy of Babel in bar-app can see the .babelrc file in foo-lib because NPM symlinks the entire project folder into bar-app's node_modules. If we published foo-lib in its current state and npm install-ed it in bar-app normally, we would not encounter this and similar kinds of errors.
And, because Babel has a bug with ignore, we can't simply --ignore=node_modules from bar-app. What we really want is to hide foo-lib's .babelrc (and everything else that would not be included in a distribution) from bar-app, because developing in an environment that is as close as possible to production === 👍.
That's what clean-link does. Instead of symlink-ing your entire project, it only symlinks package.json, node_modules , and any bin files your project may specify. Then, it returns the path to this nice, clean workspace which you can then write your build artifacts to. In practice, that might look something like this:
{
  "name": "foo-lib",
  "version": "1.0.0",
  "files": [
    "dist"
  ],
  "main": "dist/index.js",
  "scripts": {
    // Our normal build script writes files to 'dist'.
    "build": "babel src --out-dir=dist",
    // 'npm run link' will write files to something like '/usr/local/lib/node_modules/foo-lib/dist'
    // and update it when we make changes.
    "link": "npm run build -- --out-dir=$(npx clean-link-dir)/dist --watch"
  }
  // etc...
}

Now, when we run npm link foo-lib from bar-app, we only get the files we need, and everything is copacetic. 🕶

Debugging

This package respects the LOG_LEVEL environment variable, and uses the standard NPM log levels. For more verbose output, try LOG_LEVEL=verbose npm run <script that uses clean-link-dir>.