FormidableLabs / builder

An npm-based task runner
https://github.com/FormidableLabs/builder
MIT License
319 stars 26 forks source link

builder is unable to resolve archetypes when builder is symlinked in from external node_modules. #181

Open trusktr opened 4 years ago

trusktr commented 4 years ago

EDIT, the current solution is to prefix all builder commands with LOCAL_DEV=true, for example LOCAL_DEV=true builder run whatever


Original Post:

As an example, I'm using a project manager called rush, for managing "monorepos" or "umbrella repos" with multiple packages in subfolders. The rush install command installs common dependencies into an external location in the monorepo (f.e. common/temp/node_modules) then symlinks them into each package in the monorepo.

This causes builder not to find archetypes if the archetype is not also installed in the same common/temp/node_modules location.

A package in the monorepo might have a unique dependency on an archetype, in which case the archetyp is installed in the package, inside the monorepo, in a path like packages/some-package/node_modules/some-archetype

Inside of packages/some-package/node_modules/ is a symlink for builder that points to the common one, for example the symlink is

packages/some-package/node_modules/builder --> ../../../common/temp/node_modules/builder

In effect, rush manages common dependencies and links them into all packages (as long as they all depend on a compatible version of the package).

But while builder is in the external location, if we run a builder run command inside a package, it will not look in that package's node_modules for the archetype.

The following example output should help paint the picture more clearly. In the example, builder-js-package is the achetype in question, and element-behaviors is a package in the umbrella repo.

$ ls -ld common/temp/node_modules/builder
drwxr-xr-x 5 trusktr users 4096 Jan 28 12:31 common/temp/node_modules/builder/

$ ls -ld common/temp/node_modules/builder-js-package
ls: cannot access 'common/temp/node_modules/builder-js-package': No such file or directory

$ cd packages/element-behaviors

$ ls -ld node_modules/builder
lrwxrwxrwx 1 trusktr users 41 Jan 28 12:32 node_modules/builder -> ../../../common/temp/node_modules/builder/

$ ls -ld node_modules/builder-js-package
lrwxrwxrwx 1 trusktr users 24 Jan 28 12:32 node_modules/builder-js-package -> ../../builder-js-package/

$ npx builder run build:prod
Cannot find module 'builder-js-package/package.json'
Require stack:
- /home/trusktr/src/lume+lume/common/temp/node_modules/builder/lib/config.js
- /home/trusktr/src/lume+lume/common/temp/node_modules/builder/bin/builder-core.js
- /home/trusktr/src/lume+lume/common/temp/node_modules/builder/bin/builder.js

Solution

It'd be great if builder could somehow look in the CWD for node_modules (the node_modules of the package where we are running the builder command) when searching for archetypes as well as the node_modules where builder is located.

trusktr commented 4 years ago

After reading the builder source code, I realized that I could run it with LOCAL_DEV='true' and it works. LOCAL_DEV forces it it to look in process.cwd() + '/node_modules'.

But why does this option exist. Why not always look in process.cwd() by default?

trusktr commented 4 years ago

Alright, I'm back in action. All my scripts are belong to LOCAL_DEV now, like this:

{
    "scripts": {
        "clean": "LOCAL_DEV=true builder run clean",
        "build": "LOCAL_DEV=true builder run build:prod",
        "dev": "LOCAL_DEV=true builder run build:dev",
        "test": "LOCAL_DEV=true builder run npm:test",
        "test-debug": "LOCAL_DEV=true builder run npm:test-debug",
        "release:patch": "LOCAL_DEV=true builder run release:patch",
        "release:minor": "LOCAL_DEV=true builder run release:minor",
        "release:major": "LOCAL_DEV=true builder run release:major",
        "version": "LOCAL_DEV=true builder run npm:version",
        "postversion": "LOCAL_DEV=true builder run npm:postversion",
        // ... etc ...
    }
}