It seems that NPM pack, and by extension, nodejitsu, do not like my node_modules folders. :*(
I currently am building a web app.
My web app's project folder structure is as follows:
Root
Engine(folder) Server(folder) readme.md package.json
(Multiple Folders) (folder)(folder) node_modules(folder)
easyimage,mongodb,mysql(folders) socket.io (folder)
node_modules(folder, NPM Pack ignores this) node_modules(folder, NPM Pack ignores this)
Socket.io-client (folder, NPM Pack ignores this)
I hope everyone can see this structure alright!
The problem I am having is that when I run NPM Pack at the root directory, the entire directory structure is packed correctly, except for all of the node_modules folders below the first node_modules folder.
It is as if NPM pack completely ignores those node_modules folders. (The one below socket.io for instance).
Due to the fact NPM pack ignores these npm folders, jitsu is also ignoring them and I can't get my web app started.
How can I get NPM pack/nodejitsu to correctly package all of the node_modules folders correctly?
My current package.json file, at the root directory, looks like follows:
http://pastebin.com/SAU6rwb5
As you can see, I have attempted to use bundleDependencies to tell NPM Pack that I am trying to include some node_modules folders (modules?), but pack still ignores all of them... Also, if i include anything under "dependencies", NPM start creates a new (??) node_modules folder at the root directory... but at the root directory nothing needs node_modules... as you can see node_modules are used inside of the server folder.
How can I get NPM Pack to recognize the files and folders inside of all of the node_modules folders and pack them correctly?
(jump to last paragraph if you want a really easy solution)
I'm having a hard time understanding your app structure. I think I get what your trying to do though.
From https://npmjs.org/doc/folders.html , it actually goes into detail about when and why sub modules will or wont show up.
When installing locally, npm first tries to find an appropriate prefix folder. This is so that npm install foo#1.2.3 will install to the sensible root of your package, even if you happen to have cded into some other folder.
Starting at the $PWD, npm will walk up the folder tree checking for a folder that contains either a package.json file, or a node_modules folder. If such a thing is found, then that is treated as the effective "current directory" for the purpose of running npm commands. (This behavior is inspired by and similar to git's .git-folder seeking logic when running git commands in a working dir.)
If no package root is found, then the current folder is used.
When you run npm install foo#1.2.3, then the package is loaded into the cache, and then unpacked into ./node_modules/foo. Then, any of foo's dependencies are similarly unpacked into ./node_modules/foo/node_modules/....
Bear With me for another quote...
Cycles are handled using the property of node's module system that it walks up the directories looking for node_modules folders. So, at every stage, if a package is already installed in an ancestor node_modules folder, then it is not installed at the current location.
Consider the case above, where foo -> bar -> baz. Imagine if, in addition to that, baz depended on bar, so you'd have: foo -> bar -> baz -> bar -> baz .... However, since the folder structure is: foo/node_modules/bar/node_modules/baz, there's no need to put another copy of bar into .../baz/node_modules, since when it calls require("bar"), it will get the copy that is installed in foo/node_modules/bar.
This shortcut is only used if the exact same version would be installed in multiple nested node_modules folders. It is still possible to have a/node_modules/b/node_modules/a if the two "a" packages are different versions. However, without repeating the exact same package multiple times, an infinite regress will always be prevented.
As far as the bundledDependencies:
Upon publishing [this also applies to packing], npm will look in the node_modules folder. If any of the items there are not in the bundledDependencies array, then they will not be included in the package tarball.
I take this to mean that it will only bundle the listed modules in ./node_modules/ and specific sub-modules for a ./package.json . Then of course as written above, it recursively walks down the directory tree again... so if it sees another package.json file in this directory npm will look and see if that has any bundled deps to include in the pack.
So as I understand it right now, since you have no packages in your base directory, your bundled dependencies in package.json doesn't do anything, and actually having items in your bundledDependencies field does more harm than good.
To fix you need to edit the package.json files to include these bundles at each level.
I have had this issue before when trying to get a packed then unpacked meteor app working on nodejitsu. I solved it in a different way. In the root folder of my app I included all of the top level node modules and explicitly set their version in my package.json file.
From what I understand your file structure is such:
app
+-- Engine
+-- Server
| +-- socket.io
| | `-- package.json
| | +-- node_modules
`-- readme.md
`-- package.json
If this is so then you need to be editing the package.json under socket.io to include the bundled deps you want. Generally though you can trust the package maintainers to keep valid versions.(but in this case you can't?)
As for Socket.io-client not being packed that's a result of it being a dependency of socket.io.
If I was to suggest a way for you to make this easier for yourself, i'd suggest you to, in your MAIN top level package.json file, to include the dependencies you need for your app # the specific version you need. If you need them bundled for some reason, add them into the bundled section, if you need sub modules at a different version than what the author intended. Consider making a folder called package or vendor and then placing the modules in there, in those you can edit the package.json and bundles their dependencies to your hearts content. Be sure though that you do not ignore any files or folders under you vendor or packages directory with .npmignore or .gitignore files.
Alternatively, if this is too difficult (editing all theses files and specifying certain versions can be a pain) I'd suggest hosting your vendor packages some where where you could download them with a script, and then execute this script in the postinstall part of your package.json (take a read at https://npmjs.org/doc/scripts.html ... you would add this in the same section you have your "start" script.
I hope that clarifies things.
Related
I have a mono repo and want to link a component library inside a package which contains this library as a dependency. But as we control this library and make changes, I want to be able to test it locally.
cd <library_path>
npm link
cd <monorepo_path>
npm link --workspace <target_package> <library>
When I execute find: find -name '<library>' I can find the library in the <target_package> node_modules directory as well as in the roots node_modules directory, which means the one in the <target_package> will take precedence, but this is the published one, not the linked one. The linked one lives in the root.
When I install my node_modules without linking the package, the library lives only inside the root node_modules.
I tried several things without success.
How can I override the workspace dependency temporarily to use the local library from npm link?
EDIT:
I found a temporary workaround in our webpack configuration with hardcoding which path to use for this dependency.
However, this is not a satisfying solution in my opinion.
I want to do something like this, where, I want to keep all my packages globally just like node package itself. So for example in my package.json I have a package name called "Highcharts" I want to install it globally I don't want to create a local node_modules folder and use it but I want to access it from outside so next time whenever I want to create a copy of my project folder I should be able to use highcharts directly without using npm install. Is it possible?
globally installed node_modules - > Users/user/AppData/Roaming/node_modules/highcharts
app
src
node_modules (I don't want to keep it)
package.json
tsconfig.json
angular.json
How to link these globally installed node_modules with the current app or any app which we want to create?
Any help will be appreciated. Thank you so much :)
local packages are installed in the project directory
global packages are installed in a single place in your system
Usually it is a good idea to have all npm packages required for your project installed locally (project folder). This makes sure, that you can have dozens of applications which are running a different versions of each package if needed.
export NODE_PATH='yourdir'/node_modules
Hello, if am getting right, you want to keep all dependencies global.
You can just run install with -g command. Those libraries will be available in node installation folder.
From the Node docs
If the NODE_PATH environment variable is set to a colon-delimited list of absolute paths, then node will search those paths for modules if they are not found elsewhere. (Note: On Windows, NODE_PATH is delimited by semicolons instead of colons.)
Additionally, node will search in the following locations:
1: $HOME/.node_modules
2: $HOME/.node_libraries
3: $PREFIX/lib/node
Where $HOME is the user's home directory, and $PREFIX is node's configured node_prefix.
These are mostly for historic reasons. You are highly encouraged to place your dependencies locally in node_modules folders. They will be loaded faster, and more reliably.
I hope I answered, you just need to manage the paths to node_modules wherever you have kept it.
I had some issues with a current iOS React Native project that i spent a long time working on. I've decided to start afresh. However i did spend a lot of time ensuring i got the correct versions of various react native modules and configuring these to work. These sit in my old 'node_modules' folder.
Can i copy these modules/folders (from the old 'node_modules') over to my new project? Do i need to update 'package.json' or link using 'react-native link xxxxx'? It it as simple as that in theory?
You don't need to copy over your node_modules directory. You can if you'd like, but it is not considered best practice. In any case, you shouldn't make any modifications to the files inside node_modules.
Preferably you need to only copy over your package.json file and optionally, your package-lock.json (or yarn.lock if you're using Yarn) file so that your project will be easily installable and upgradeable on other computers.
When you have a package.json or package-lock.json file, you can run npm install (or yarn install) to install the packages to your node_modules directory.
Copying your package-lock.json file over as well would ensure that the exact same versions of all of the packages that you have installed in your previous project will be installed in the new project as well. See this for more information on the package-lock.json file.
Unfortunately, I don't know much about react-native and linking react-native dependencies, but from this answer it seems that you would have to link any dependencies that contain native code again after you've run npm install.
No, I wouldn't recommend you to copy specific module from node_modules folder as once installed it has entries in .bin folder and files which you will miss while copying and it will be of no help in new project as they will be downloaded and installed again due to missing indexes.
Solutions :
You can use same package.json and package-lock in another project if you are sure that the dependencies version in it are exactly compatible or one you want, and install those dependencies in new project. The package-lock.json will ensure the version you choose.
Yes you can copy whole node_modules (have done it multiple times) from one project to another and use same package.json and package-lock (Will only save time in dependencies installation/download)
As you are starting fresh what i will recommend is create a new package.json and copy only those dependencies which are important for the project initialization, and as you progress add specific dependencies you need while developing. This will save you from huge garbage of unused dependencies which are hard to keep track of once the project inflates.
Maybe you can move it but you can't copy it, at least not with a naive cp -r! The node_modules/.bin directory ought to be full of symlinks to scripts in their respective directories in node_moudles, but after a cp -r these will be copies, which will now resolve relative module paths incorrectly.
For example, npm install typescript installs a executable script with the contents
#!/usr/bin/env node
require('../lib/tsc.js')
in two locations. Before a copy, that looks like this:
$ ls -l node_modules/.bin/tsc node_modules/typescript/bin/tsc
-rwxr-xr-x 45 node_modules/.bin/tsc
-rwxr-xr-x 45 node_modules/typescript/bin/tsc
and after a cp -r copy, like this:
$ ls -l node_modules/.bin/tsc node_modules/typescript/bin/tsc
lrwxr-xr-x 21 node_modules/.bin/tsc -> ../typescript/bin/tsc
-rwxr-xr-x 45 node_modules/typescript/bin/tsc
which makes the ../typescript/bin/tsc no longer exist, resulting in
$ tsc -b
...
Error: Cannot find module '../lib/tsc.js'
...
Right now I got a NodeJS backend for a system I built. The problem is that I need to also maintain another instance of the backend for some client specific requirements, both of the instances share like 70-80% of the code. At the moment I'm using git branches to keep them apart, I know git is not meant to do this, so I would like to know if there is something that allows me to have two separate projects sharing some codebase, similar to flavors in Android.
There are few options to do this:
1. Install your own module as separate dependency with npm via package.json dependency.
create own reusable code as separate project on your git space
specify it as dependency in package.json
use it by installing it with npm install, in same fashion you do with regular npm modules
2. Use docker.
Docker is container virtualisation engine, that allows you to create images of vritual environments with pre-installed infrastructure/file system
You just crete image with some linux os inside, node and your module preinstalled, and all you need is to mount your unique code as "volume" to the container and thats it.
use nodejs offcial image - it have everything basic node.js env would need - to create own image. In the folder where you have /reusable_code folder and package.json create Dockerile file
Dockerfile:
FROM node:6.9.2
RUN mkdir app
COPY ./reusable_code /app/reusable_code
COPY ./package.json /app/package.json
WORKDIR /app
RUN npm install -g <your global modules> && npm install
now run docker build -t base-image-with-reusable-code .
It will create and tag the image as base-image-with-reusable-code
Now once you want to use it with any unique code you should do from the folder where the code is (this assuming all unique code use same package.json dependencies used in previous step - if not this will need extra step)
docker run -ti -v ./app.js:/app/app.js -v ./unique_code:/app/unique_code base-image-with-reusable-code node app.js
Of course names should be corrected, and if you have different project structure then the changes should reflect that.
3. Link the reusable code module folder via OS
Simply put, just ln -s /path/to/reusable/code ./resuable_code from your unique code project root folder, and then use it assuming it residing at root of every unique project you have linked it to.
4. Link the reusable code module folder via npm link
as suggested by #Paul :
node native way to do #3 is via npm link, which both sets up the symlink and makes reference to it in your package.json so that your code can treat it as an external module
Assuming you have reusable code folder in same folder where unique code folders are located:
Modified example of the npm link docs:
cd ~/projects/unique_project1 # go into the dir of your main project
npm link ../reusable_code # link the dir of your dependency
Note : all solutions assume you have separate git project for your reusable code. Generally speaking , it's a good practice.
I've got a project in Harp with this standard directory structure:
(highlighted parts are in my git, bower_components and www should be created upon install/compile).
When I install a new bower component, I can easy include its css in my Less, e.g.
#import "../../bower_components/some-component/stuff";
but what would be the "right" way to use javascripts (or other static assets, for that matter)? Of course, I could simply copy them over, e.g.
cp bower_components/some-jquery-plugin/plugin.js public/js/plugin.js
and this is what people actually do, but I'm looking for something better. Ideally, I'd like to avoid makefiles/gruntfiles completely and be able to initialize my project with just bower install:
git clone myproject // this will create public/ and bower/harp.json
cd myproject
bower install // this populates bower_components
harp server/compile // just works...
In other words, I'd like to somehow reference static assets that reside in bower_components from inside the public dir. Symlinking is not an option because harp compile doesn't resolve symlinks.
The quick and dirty solution is to tweak the .bowerrc settings to change the default directory that bower components are installed to.
.bowerrc
{
"directory": "public/js/bower"
...
}
Now a bower install command will drop those dependencies directly into your public/js/bower directory.
Upside: It's a quick "one-liner" in your .bowerrc
Downside: All of the source files for those dependencies get deployed publicly unless you have a deployment script that cleans up the unnecessary files. Then again, if they are all open source projects that you are using then it really doesn't matter if those extra files are sitting on your web server.