Webpacker: [Question] How are you handling npm tasks and dependencies?

Created on 25 Jan 2017  Â·  7Comments  Â·  Source: rails/webpacker

I've just begun using Webpacker in a Rails project to replace my use of Gulp. As someone coming from a primarily node/js background, I've noticed a few immediate issues that I've developed workarounds to, but am wondering if there are any better ways to accomplish what I'm trying to do within Rails.

1) Packages that use node, but contain code in the /javascript folder don't know where to find their module dependencies. This issue came up for me primarily with my use of Jest and resulted in errors such as Couldn't find preset "es2015" relative to directory .../javascript/packs when running my tests from within the /packs folder.

2) In a typical node app, you would call your scripts such as npm test from the root directory. With the way Webpacker is currently setup, you must cd into the /vendor folder before you can run any npm tasks.

3) It seems like it will be confusing to onboard new developers onto a project by telling them that you can't type yarn to install your npm files, but rather, you have to type bin/yarn

My solution to the first two issues above has been to symlink the node_modules folder and the package.json file to the root directory. Symlinking the node_modules folder has successfully resolved my issue with Jest not being able to find files that it requires, and symlinking package.json allows me to run npm scripts from the root folder. For anyone interested in following that approach, in terminal, from the root of your app you can do:

ls -s vendor/node_modules node_modules
ls -s vendor/package.json package.json

To somewhat resolve the third issue, I made an invalid yarn.lock file containing a warning in my root directory that causes running yarn to break. Someone debugging the yarn file will see that they should be using the binstub instead:

### yarn.lock
# Do not run `YARN` in the root directory!
# Use `./bin/yarn` to install dependencies!
This line is just to break the yarn install :)

Now I'm wondering, are these approaches correct? Has anyone developed a better way to resolve these issues? It just seems odd to me now that the two main files/folders in my /vendor folder are being symlinked in the root folder of my Rails app.

Most helpful comment

@joerodrig3 @merqlove I was able to use jest without symlinks by setting NODE_PATH in vendor/package.json:

  "scripts": {
    "test": "NODE_PATH='./node_modules:../app/javascript' jest"
  },
  "jest": {
    "testPathDirs": [
      "../app/javascript"
    ]
  }

After that I just had to create a .babelrc in the root of my project, replicating my webpack plugin setup.

All 7 comments

Hi, what is a problem to run bin/yarn?)
But yes, here easy to mistake, just first time.
Also you can try to run cd vendor; yarn

About tasks:
You can write any scripts you want in the package.json, then run it with YARN or with NPM.

The concern I have with bin/yarn is that in some cases, such as deploying to Heroku, it seems like we have to create a yarn.lock file and package.json file in the root directory of the app anyway to trick Heroku into installing yarn as a dependency. What benefits are there to organizing those files in vendor if we need to create/symlink them in root to get our app deployed and/or get client specs running? It seems like creating these duplicate files adds unnecessary complexity, but I'd also like to know more about why the choice was made to move these files into vendor!

As 3rd party packages, I can understand why node_modules would be put in vendor, but it seems odd to me that package.json and yarn.lock would be put in there as well. I think of them as config files that you typically expect access to on the root level, similar to Gemfile and Gemfile.lock

package.json must be at the same level, as modules folder. So if we have it at vendor level, then it's modules folder will be in vendor too.
But yes, for example in Phoenix framework node_modules, package.json sitting at the root level. And it just works.

About symlinks, yep it works like workaround, but better is avoid symlinks.

Heroku can update their Yarn detection in time. We've rehashed this typic
multiple times over already. Intent is to move Gemfile/.lock into vendor as
well in time.

On Thu, Jan 26, 2017 at 4:45 PM, Alexander Merkulov <
[email protected]> wrote:

package.json must be at the same level, as modules folder. So if we have
it at vendor level, then it's modules folder will be in vendor too.
But yes, for example in Phoenix framework node_modules, package.json
sitting at the root level. And it just works.

About symlinks, yep it works like workaround, but better is avoid symlinks.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/rails/webpacker/issues/72#issuecomment-275422354, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAAKtUrd9pJblqc60i5hMpe6wmjVfHgEks5rWL-agaJpZM4LuFds
.

@joerodrig3 @merqlove I was able to use jest without symlinks by setting NODE_PATH in vendor/package.json:

  "scripts": {
    "test": "NODE_PATH='./node_modules:../app/javascript' jest"
  },
  "jest": {
    "testPathDirs": [
      "../app/javascript"
    ]
  }

After that I just had to create a .babelrc in the root of my project, replicating my webpack plugin setup.

@schpet same here, also we can use Makefile :)

@schpet Thanks for that! That actually seems a lot better than the symlink solution

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ilrock picture ilrock  Â·  3Comments

johan-smits picture johan-smits  Â·  3Comments

naps62 picture naps62  Â·  3Comments

FrankFang picture FrankFang  Â·  3Comments

eriknygren picture eriknygren  Â·  3Comments