6

I am a java developer learning EC6. I use npm to download JavaScript packages and webpack to create the final bundle.js file.

I have a nice project folder which contains java modules with java files and I would like to add EC6 JavaScript files to my web-modules. I use maven to manage the java jar dependency libraries.

This is my folder structure:

my-project
  |-common-module
  |-ejb-module
  |-web-module-1
  |   |-src
  |       |-main
  |           |-java
  |               |-com.a.b
  |                   |-Hello.java
  |           |-webapp
  |               |-index.jsp
  |               |-bundle.js
  |               |-package.json
  |               |-webpack.config.js
  |               |-WEB-INF
  |               |-node_modules <-- I WANT THIS FOLDER TO BE MOVED AWAY FROM HERE 
  |               |-app          <-- react + ec6 javascript files
  |                   |-action
  |                   |-components
  |                   |-...
  |-web-module-2
      |-<same structure then under web-module-1>

When I execute npm install... command in my-project/web-module-1/src/main/webapp folder then a new directory with name of node_modules is created by npm under webapp directory. This folder contains tons of files.

My problem is that when I work on my 2nd web project and execute the same npm install... command then a second node_modules directory is created with the same content under my-project/web-module-2/src/main/webapp directory.

Can I use a common, separated node_modules directory to avoid the duplicated files and save disk space? Can I store js dependencies under ex. /home/user/javascript/modules folder?

Comment 1: I do not want to execute npm as a root and use npm -g install!

Comment 2: I do not want to create symlinks as well.

Could you please help me?


EDIT What i did:

  • I have created a new folder for the JS packages: /home/user/javascript-modules.
  • Copied package.json file to /home/user/javascript-modules.
  • npm install --prefix /home/user/javascript-modules

After that the necessary JS modules are copied to my javascript-modules/node-modules directory. Nice!

But when I try to execute webpack then i get a missing module error:

  • cd my-project/web-module-1/src/main/webapp
  • ./home/user/javascript-modules/node_modules/.bin/webpack

Result:

Hash: a6bf1a0d210729a54be9
Version: webpack 1.14.0
Time: 39ms

ERROR in Entry module not found: Error: Cannot resolve module 'babel-loader' in /home/user/java/intellijmy-project/web-module-1/src/main/webapp

Comment: My webpack.config.js files contains a line with this content: loader: 'babel-loader'

Is there any way to specify the "classpath" for webpack? I mean to tell to webpack where are a modules.


UPDATE As you can see in the comments I have tried to solve my issue on many different ways without any success. For me it seems that what I wanted to do is not supported by webpack. That so sad :(

That is it. If some has any working, nice and complete solution please share it with us. Thanks.

zappee
  • 20,148
  • 14
  • 73
  • 129
  • updated answer..hope it solves your problem – Suraj Rao Dec 31 '16 at 14:40
  • 1
    I wanted to achieve the exact same thing. I ended up switching to [pnpm](https://github.com/pnpm/pnpm). Though it uses symlinks and hard links to avoid duplicates on disk but seems to work pretty well. – sceid Nov 02 '17 at 22:21
  • 1
    Possible duplicate of [How can I make multiple projects share node\_modules directory?](https://stackoverflow.com/questions/29786887/how-can-i-make-multiple-projects-share-node-modules-directory). Also, did you mean ES6? – Dan Dascalescu Jul 04 '18 at 20:44

2 Answers2

17

Use pnpm instead of npm.

From the pnpm project's website:

pnpm uses hard links and symlinks to save one version of a module only ever once on a disk. When using npm or Yarn for example, if you have 100 projects using the same version of lodash, you will have 100 copies of lodash on disk. With pnpm, lodash will be saved in a single place on the disk and a hard link will put it into the node_modules where it should be installed.

  1. To install using npm in a command window use:

     npm install -g pnpm
    
  2. To update your existing package installations (and all subdirectories) use:

     pnpm install --recursive
    

or, use the shortcut command for recursive install:

    pnpm i -r

Use pnpm anywhere you would typically use npm. (This commands safely falls back to npm functions when not supported by pnpm.

Benson
  • 4,181
  • 2
  • 26
  • 44
  • Great to see more awareness around `pnpm`. You could also point out that this question is probably a dupe of [the other one](https://stackoverflow.com/questions/29786887/how-can-i-make-multiple-projects-share-node-modules-directory) you left the same answer on. I'll do that now. – Dan Dascalescu Jul 04 '18 at 20:43
  • 1
    Cool thanks! Me thinks it’s time for me to learn how to mark a question as a duplicate. – Benson Jul 10 '18 at 11:19
3

Inorder to get npm to install in a directory of custom location,you need to run:

npm install --prefix path_to_node_modules_location

Edit : it is not possible to have the local folder without the package.json with it.

The only 'common location' for all projects is the global one. The global location contains all common packages and local contains specific ones for the project.

However, I am not sure it is such a good idea to have a common local node_modules folder for different projects as you end up with having to make sure their dependencies dont clash because of difference in package versions. It would mean trying to maintain package.json for multilple projects.

In order to configure webpack to look at new location check github link here

The loaders here are resolved relative to the resource which they are applied to. This means they are not resolved relative to the configuration file. If you have loaders installed from npm and your node_modules folder is not in a parent folder of all source files, webpack cannot find the loader. You need to add the node_modules folder as an absolute path to the resolveLoader.root option. (resolveLoader: { root: path.join(__dirname, "node_modules") })

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
  • 1
    i am trying to execute my-project/web-module-1/src/main/webapp/webapp/npm install --prefix /home/user/javascript/packages. Result: npm WARN enoent ENOENT: no such file or directory, open /home/user/javascript/packages/package.json'. – zappee Dec 31 '16 at 13:33
  • 1
    That means I need to copy package.json file to the separatated node_modules folder? Strange. Maven's concept looks better... – zappee Dec 31 '16 at 13:35
  • that ia odd..http://stackoverflow.com/questions/14469515/how-to-npm-install-to-a-specified-directory – Suraj Rao Dec 31 '16 at 13:43
  • I updated the answer accordingly.. The command referred to installing a single package. Sorry for the confusion. – Suraj Rao Dec 31 '16 at 14:13
  • ok..can you put up webpack.config.js? That ia where you set the its config..You will need to get the build process to check your new location – Suraj Rao Dec 31 '16 at 14:19
  • Honestly i tried to use many different configuration without an result :( This is my webpack.config.js: https://gist.github.com/zappee/13a29528dce954a0fcb3d10161551e4b. Could you please help me to configure webpack that it uses an external node_modules folder like this: /home/user/javascript-modules/node_modules? – zappee Jan 04 '17 at 21:42
  • As stated in my answer you have to set variable SRC as absolute path..not relative – Suraj Rao Jan 05 '17 at 04:12
  • I was able to solved almost every issue, thanks for your help. The only one error what remained is related to module.loaders. My webpack.config.js is here: https://gist.github.com/zappee/2a59fd0772d036ba93b42d279613aa77. The error related to row 34 in my config file. Error what I got is: Module build failed: ReferenceError: Unknown plugin "/home/soma/java-script/node_modules/transform-runtime". The babel-plugin-transform-runtime plugin is in the node_modules folder. What magic do I need to do please? – zappee Jan 05 '17 at 20:57
  • set excludes to correct path of node_modules..not sure if that is the actual solution here.. – Suraj Rao Jan 06 '17 at 13:56
  • 1
    It is completely makes me crazy. Why it is so complicated? Compare it with maven, webpack is so complicated. I made lost of changes on my original webpack.config.js file but it still does not work. I set excludes what you suggested and that seems fine. I changed es2015 to babel-preset-es2015 and stage-0 to babel-preset-stage-0 and react to babel-preset-react but now I get a different error: Cannot resolve module 'react'. I guess this comes from my *.js files, ex: App.js > import React from 'react'. My current config file: https://gist.github.com/zappee/387f9f50ad6cd430bbb0ee386eef110e. – zappee Jan 08 '17 at 22:38
  • That is my original webpack config: https://gist.github.com/zappee/ba2de1742b55c2ce5d2eabc5ed368f67. I do not want to do any complicated extra thing just use an external node_modules directory :( Maybe that totally against to webpack? – zappee Jan 08 '17 at 22:46
  • Thanks for your help. I think I will close this topic. The issue is not solved but you helped me a lot so i accept your post and add some comment to my original post. – zappee Jan 09 '17 at 11:30
  • @zappee What did you end up doing? I am struggling with the same issue more or less - I want to share the same node_modules folder between the same pages. It is a very painful process. – boggy Apr 18 '23 at 22:43