Running grunt on dependencies - javascript

I have 3 projects all using grunt.
Project a depends on project c and b
Project b depends on project c
Project c depends on nothing
Project a and b both require a step that compiles project c (which is a style repo that contains global styles for our org).
I am attempting to run grunt post install for project b.
There are a couple problems here.
Project a and b both try to build project c in their build processes. This takes sometime and I'd rather avoid it.
Project b expects different paths when running alone. loadNpmTasks fails unless I grunt.file.setBase, but then I have other paths that are broken as well. This means I need to manually track all of those down and make sure they are correct in both situations. This is rather flimsy.
As a result, I am thinking I am not doing this correctly or in a "normal way". What is the appropriate way to manage dependencies that use grunt?
Update
The main problem is that I get the following errors no matter what solution I've been choosing:
Local Npm module "grunt-contrib-compass" not found. Is it installed?
Local Npm module "grunt-contrib-handlebars" not found. Is it installed?
Local Npm module "grunt-contrib-requirejs" not found. Is it installed?
Local Npm module "grunt-contrib-watch" not found. Is it installed?
Local Npm module "grunt-notify" not found. Is it installed?
Local Npm module "grunt-curl" not found. Is it installed?
Local Npm module "grunt-shell" not found. Is it installed?
I tried spawn a task and calling grunt via the command line. I tried using various plugins to help. I think the issue is that both the top level and the dependencies require those tasks. This means they get pulled up into the parent node_modules folder. As a result the dependencies are missing the above modules in their node_modules folder.

I've built grunt-grunt with exactly this kind of scenario in mind.
grunt.initConfig({
grunt: {
lintsome: {
gruntfile: 'node_modules/some/Gruntfile.js',
task: 'jshint'
}
}
});
The README contains enough documentation to get you going.

Related

Why the same package are installed in a different way?

I installed the same package for both my projects. That package(won't link, it's private one) has react-popper as dependency(which in order has create-react-context as dependency), so, when I run project one - everything is ok, but error appears for project two:
ERROR in ./node_modules/react-popper/lib/esm/Manager.js
Module not found: Error: Can't resolve 'create-react-context' in '/../node_modules/react-popper/lib/esm'
After some investigation, I got that node_modules structure is different:
for project one, all react-popper dependencies are saved in project one
node modules, and local folder contain only warning package:
for project two all react-popper dependencies saved in ../react-popper/node_modules local folder:
I've tried some common approaches like reinstalling node modules, clear cache and so on, but the structure is the same. Actually I had a thoughts about webpack and babel versions, but I don't think it can affect node_modules structure itself.
So the question is, which factors can affect it? What should I check?
NOTE: If I manually add create-react-context to project two, it works fine, but it's not a solution.
NOTE: I found out similar issue, but no suggestions there - Why does npm install packages in different directories?, im my case re-creating of yarn.lock also helps, but it's also doesn't look like a right way to solve it. Hope my description is more complete and will help to figure it out.
This is very likely because of the way yarn (as well as npm) tries to deduplicate dependencies. Let's say there are modules A and B which exist in 2 versions (1.0.0 and 2.0.0). B depends on Version 1.0.0 of Module A.
If you install only module B, you will get a node_modules folder like this:
node_modules
- A#1.0.0
- B#2.0.0
But what if you install module A in its latest version (2.0.0)? If npm just updated the version of module A, your existing module B would (potentially) no longer work as it depends on module A. So your node_modules folder will instead look like this (A#1.0.0 is moved inside B's node_modules folder)
node_modules
- A#2.0.0
- B#2.0.0
-- A#1.0.0
Your 2 projects likely have further dependencies, which somehow overlap with react-popper or its dependencies. Due to the nodeJs module resolution mechanism, this usually shouldn't be a problem.
TLDR: The exact structure of the node_modules folder depends on all your dependencies (and devDependencies). yarn/npm will look into every package.json/package-lock.json file of your projects dependencies (and their dependencies) and use this information to calculate a dependency tree with minimal duplication.

How to executing a script that is located inside a symlink dir?

I have two directory structure:
The first one, which is my utils project is like this
mock-utils:
app-mock (symlinked to app-mock)
common
utils.js
node_modules
package.json
package-lock.json
I have another one which is the app-mock which is somewhere locally,
app-mock:
tests
test.js
test.js contains the following import, and the entry point for the execution is inside the mock-utils since package.json is located there:
var mocha = require('mocha');
var shield = require(‘../../common/utils.js’)
However, executing test.js from mock-utils will give the error of
Error: Cannot find module
Originally, app-mock is inside the mock-utils but it have to be separated for git. How do I adjust it so that it would be possible to execute test.js while retaining this kind of structure?
You can find a solution here:
Installing a local module using npm?
Please note that due to recent NPM updates you might need to remove you package-lock.json file for this to work. Avoid running npm install during your development because this will recreate the package-lock.json file and npm will try to replace your symlinked package with the real one which, with your current setup, from what i understand, will throw a package not found exception.

How to find a locally installed npm module which depends on a certain module?

There's an error being thrown in of my node.js projects, and the stack trace doesn't seem to point back to any of the libraries I'm using, is there a simple method of finding out what packages depend on this package in my node_modules directory?
Ideally this method doesn't involve manually checking the package.json of every module in my node_modules directory.
Use npm ls <module-name>.
You can use a bit of bash scripting to automate this
who_depends_on() {
local dependency=$1;
for file in $(ls node_modules); do
local match=$(grep $dependency "node_modules/$file/package.json");
if [[ $match ]]; then
echo "'$file' is dependant in '$dependency'";
fi
done
}
Put the function wherever you store your shell functions, and then run like so
who_depends_on "your-package-here"
The main caveat with this package is it'll pick up the package.json package you're looking for as well.

Change Directory in Node REPL not working?

Just earlier, I posted my question:
https://stackoverflow.com/questions/28336443/how-to-not-put-my-js-files-in-user-myuser-for-node-js
I have a file, hello.js, located in /Users/MyUser/Desktop/Node/
I can see that my default directory is /Users/MyUser/
Okay, so I get that I need to change my working directory. What I have been able to find so far is to use >process.chrdir('/Users/MyUser/Desktop/Node/');
Cool, that works, but now when I get out of the REPL shell, the directory resets.
The person who responded to my question said that I needed to run >node init and later npm install <name of dependency> --save
My first question: I have ran >node init and see that I can create this package.json file, what does this do exactly?
Secondly: I was told that I need to add dependancies. Could someone please explain to me what this means in Node terms? Does a dependancy simply mean a folder that I want node to include? Do I want to add this Node folder on my Desktop to be able to run my scripts?
I am currently trying to go through the learnyounode courses, however I do not want to have to save all of these test files in my /User/MyUser directory, so any advice would be greatly appreciated.
Thanks
I have ran >node init and see that I can create
this package.json file, what does this do exactly?
npm init is used to create a package.json file interactively. This will ask you a bunch of questions, and then write a package.json for you.
package.json is just a file that handle the project's dependencies and holds various metadata relevant to the project[ project description, version, license information etc]
I was told that I need to add dependencies. Could someone please
explain to me what this means in Node terms?
Lets say you're building an application that is dependent on a number of NPM modules, you can specify them in your package.json file this way:
"dependencies": {
"express": "2.3.12",
"jade": ">= 0.0.1",
"redis": "0.6.0"
}
Now doing npm install would install a package, and any packages that it depends on.
A package is:
a folder containing a program described by a package.json file
a gzipped tarball containing (1)
a url that resolves to (2)
a # that is published on the registry with (3)
a # that points to (4)
a that has a "latest" tag satisfying (5)
a that resolves to (2)
If you need to install a dependency that haven't been included in package.json, simply do npm install <packageName>. Whether or not you want to include this newly installed package in package.json is completely your take. You can also decide how this newly installed package shall appear in your package.json
npm install <packageName> [--save|--save-dev|--save-optional]:
--save: Package will appear in your dependencies.
--save-dev: Package will appear in your devDependencies.
--save-optional: Package will appear in your optionalDependencies.
Does a dependency simply mean a folder that I want node to include?
Umm, partly yes. You may consider dependencies as folders, typically stored in node_modules directory.
Do I want to add this Node folder on my Desktop to be able to run my
scripts?
No, node manages it all. npm install will automatically create node_modules directory and you can refer to those dependencies with
require() in your .js files
var express = require('express');
Node REPL simply provides a way to interactively run JavaScript and see the results. It can be used for debugging, testing, or just trying things out.
process.cwd() points to the directory from which REPL itself has been initiated. You may change it using process.chdir('/path'), but once you close the REPL session and restart, it would always re-instantiate process.cwd() to the directory from which it has been started.
If you are installing some packages/dependencies in node project1 and think those dependencies can also be useful for node project2,
install them again for project2 (to get independentnode_modules directory)
install them globally [using -g flag]. see this
reference packages in project2 as
var referencedDependency = require('/home/User/project1/node_modules/<dependency>')
Simply doing process.chdir('/home/User/project1/node_modules/') in REPL and referencing as
var referencedDependency = require('<dependency>') in your js file wont work.
>process.chdir('/Users/MyUser/Desktop/Node/'); change the working directory only for that particular REPL session.
Hope it helps!
This has nothing to do with node.js but is rather inherent in the design of Unix (which in turn influences the design of shells on other operating systems).
Processes inherit values from their parent's environment but their environments are distinct.
That terse description of how process environments work has a sometimes unexpected behavior: you cannot change your parent's environment. It was designed this way explicitly for security reasons.
What this means is, when you change the working directory in a process and quits that process your shell's working directory will not be affected. Indeed, your shell's working directory isn't affected even when the process (in this case, node REPL) is running.
This exact question is often asked by people writing shell scripts wanting to write a script that CDs into someplace. But it's also common to find this question asked by people writing other languages such as Perl, Tcl, Ruby etc. (even C).
The answer to this question is always the same regardless of language: it's not possible to CD from another program/script/process.
I'm not sure how Windows handles it so it may be possible to do it there. But it's not possible on Unixen.

Using stellar-lib api with Meteor

this is probably a silly question but am new to Meteor and struggling a bit. I want to build a stellar app that tweets when you get stellar. There is a nice Javascript API stellar-lib that works on node, but im unsure how to access the modules in Meteor...
I'm also building an app with Meteor and stellar-lib and have found two options:
1) You can manually copy over the built stellar-lib.js or stellar-lib-min.js from the build/ directory from either the github repo or the node_modules folder you installed it to when you ran the npm install command.
If you do this, you will have to copy the .js file to client/compatibility, otherwise stellar-lib will not work (note: this means you can only use Stellar on the client).
2) If you need it on the server, you can also have browserify wrap stellar-lib for you, then copy the output to lib/ in your Meteor app's root directory. I did this in my repo here with gulp.
Here's a short explanation to how 2) works:
.gulp is where I'll install my NPM modules where they will be ignored by the Meteor build environment (because the folder is hidden).
In deps.js, I require the modules I would want to use in my Meteor app as I would if I was using them in a traditional node.js app. package.json defines the modules I'll install with NPM and the gulpfile.js describes a build task that will resolve my require statements and output a single deps.js file that includes my dependencies to my Meteor app's lib/ folder.

Categories

Resources