14

My package.json includes webpack and some loaders:

"devDependencies": {
  "babel-core": "^5.2.17",
  "babel-loader": "^5.0.0",
  "jsx-loader": "^0.13.2",
  "node-libs-browser": "^0.5.0",
  "webpack": "^1.9.4"
}

When I run webpack it's not in my path so it doesn't show as found. I installed it globally npm install -g webpack so the binary would appear in my path, but then it can't find the loader modules that were installed in ./node_modules that it needs to process my dependency tree:

$ webpack --progress --colors --watch
10% 0/1 build modules/usr/local/lib/node_modules/webpack/node_modules/webpack-core/lib/NormalModuleMixin.js:206
                throw e;
                      ^
Error: Cannot find module 'jstransform/simple'```

What is the preferred solution here?

I can install my loaders globally, but I don't like that because of cross-project issues

I can try to run webpack out of node_modules (not sure how to be honest, add it to $PATH for every project?)

Or I can try to give my global webpack access to my node_modules folder, which also seems hacky.

Have I done something wrong, or is there a better community-approved way around this maybe common problem?

Matt Huggins
  • 81,398
  • 36
  • 149
  • 218
Alex Mcp
  • 19,037
  • 12
  • 60
  • 93

2 Answers2

24

I have a blog post called Managing Per-Project Interpreters and the PATH that details my methodology for this. I'll summarize here to address some of your key questions.

What is the preferred solution here?

Never (really, literally never) use npm -g. Just install normally within your project. Use your shell to set the PATH appropriately. I use zsh to do this automatically as detailed in the blog post above so if I cd into a project with ./node_modules/.bin, it gets put on my PATH automatically.

There are other ways that work including making aliases like alias webpack="./node_modules/.bin/webpack" and so on. But really just embrace changing your PATH and you'll have the most harmonious long-term experience. The needs of a multiproject developer are not met by old school unix everything lives in either /bin or /usr/bin.

  • If you use npm scripts (the "scripts" key in your package.json), npm automatically includes ./node_modules/.bin in your PATH during those scripts so you can just run commands and they will be found. So make use of npm scripts and if you make use of shell scripts that's an easy place to just do export PATH="$PWD/node_modules/.bin:$PATH".
Peter Lyons
  • 142,938
  • 30
  • 279
  • 274
6

Any binaries that come with packages defined in your dependencies should be placed under ./node_modules/.bin, so you should be able to access there, i.e.: ./node_modules/.bin/webpack.

Alternatively, you could define a script inside your package.json, which would allow you to run something like npm run webpack as an alias.

Matt Huggins
  • 81,398
  • 36
  • 149
  • 218
  • It has enough flags on it that it DOES feel ergonomic to use an npm script definition for it anyhow, so I like that second option. I'll wait a few minutes for a better answer if there is one ;-) – Alex Mcp May 11 '15 at 16:56