I'm using the scripts section inside the package.json file to store some commands I have to run regularly.
"scripts": {
"test": "./test/phantomjs ./test/js/run_jasmine_test.coffee ./test/index.html",
"rjs": "r.js -o ./js/app.build.js",
"less": "lessc -x ./css/app.less > ./css/app.css"
}
in every command I have got a ./ at the beginning of the path - this is why I can only call npm run-script rjs from the project's root directory.
is there a way to reference the project's root directory inside the package.json so that I can run e.g. npm test from anywhere in my project?
I think it depends on the way you organize your project.
I created a sample project just to demonstrate. This is my sample project directory tree:
.
├── dir1
│ └── dir2
├── package.json
├── src
│ └── index.js
└── test
└── test.js
NOTE: ./dir1/dir2 are just two empty directories for demonstration.
My package.json file looks like this:
{
"name": "sample",
"version": "1.0.0",
"description": "sample",
"main": "index.js",
"scripts": {
"test": "node test/test.js",
"start": "node src/index.js"
},
"author": "yaniv",
"license": "ISC"
}
Focus on the scripts section, those are two simple line, without considerations about my location.
If I change directory to /dir1/dir2 and execute npm test and the script I wrote on test property is executed properly without the use of ./ (which defines the current directory...)
Bottom line - I suppose if you re-organize your project and remove ./ will do the job in your case.
INIT_CWD
We can reference the root directory of the project throught the environment variable INIT_CWD that npm set for us!
From the doc :
Scripts are run from the root of the module, regardless of what your current working directory is when you call npm run. If you want your script to use different behavior based on what subdirectory you’re in, you can use the INIT_CWD environment variable, which holds the full path you were in when you ran npm run.
Example:
"tas:adminApp:build": "cd src/KidoService/AdminApp && npm run build && cd $INIT_CWD && gulp build_copyAdminApp",
And just because i love to think too much!
What if we didn't have such a variable set for us!
We can execute an env variable set command at all start! export ROOT_DIR=$PDW !
And then when we need it ! We can use it!
The above example will become
"tas:adminApp:build": "export ROOT_DIR=$PDW && cd src/KidoService/AdminApp && npm run build && cd $ROOT_DIR && gulp build_copyAdminApp",
You can see it's a nice technique ! We can use that to reference some directories that we want to go back to!
For windows we use set VAR=VALUE
considered creating a shell file that runs?
for example create a .sh file make it executable (chmod 777 file.sh)
and then cd to your nodejs project root, run the npm command, and then cd back into the directory you have just left?
adding the script to your environment will make it executable from anywhere...
alternatively will hard coding the full path be ok? (so rather than using ./ - put /home/user/username/yourproject/phantomjs)
Related
I am having a Monorepo and using NX build system.
I am trying to figure out a way to inject the project name in my package.json
package.json
"scripts": {
...
"sampleCmd": "env-cmd -f apps/${projectName}/.env.local"
},
I am looking for a way to inject the projectName/appName.
Example:
If I execute yarn sampleCmd user-service
The sampleCmd should be "env-cmd -f apps/user-service/.env.local"
Yarn run command just add arguments to end of script command defined in package.json. It's not possible to get a specific argument, neither to change the order.
But as a workaround, we can create a dedicated script in a scripts folder for example, and reference it from package.json.
Then inside this script, we can get arguments.
for example, in /scripts/sample-cmd.sh
#!/usr/bin/env bash
cd $(dirname ${0})/..
PROJECT_NAME="${1}"
env-cmd -f apps/$PROJECT_NAME/.env.local
Then in package.json :
"scripts": {
...
"sampleCmd": "./scripts/sample-cmd.sh"
},
Of course, this need to be adapted to target environment, system... (bash, linux/mac/windows...). But the main idea is here.
Note this in not related to NX monorepo, and will work for every NPM/YARN project.
so I have an npm script where I start up a server and need to build to a directory in my project. The directory has a sub-directory that matches the version of my app that is defined in the package.json.
{
name: “my-app”,
version: “0.3.2”
…
scripts: {
“server”: “npm-watch build:local & serve -C -l 5000 build/*”
}
}
So instead of the asterisk I need it to replace that with the value I have for the version.
I think it would be easier to write another starting file and read the version inside package.json
I have come out another solution by writing a start.sh.
folder structure
- my-project
|- build
|- 0.0.1
|- 0.1.0
|- 0.1.1
|- index.js
|-start.sh
|-package.json
my start.sh
#!/bin/bash
export p="./build/$(ls ./build | sort -r | head -n 1)"
node $p
My solution is quite simple, list all the directory under ./build and then sort in reverse. Now 0.1.1 is the biggest version and it would list at first. head -n 1 means get the first line which is the current biggest version number.
Then use the dir as the node execution path.
Inside the package.json
"scripts": {
"test": "bash start.sh"
}
I think it is similar way to change to your own command.
Note I have tried to put script content inside package.json, but the npm run would not interpret shell variables well. So I recommend write a standalone script.
I have a fairly standard web application structure which is using npm to execute some node.js test scripts. In addition, npm allows you to execute the parent package scripts from a subdirectory.
As an example:
|-- my-app
| |-- package.json
| |-- test-script.js
| |-- component-one
| | |-- test-one.spec.js
| |-- component-two
| | |-- test-two.spec.js
> /my-app/component-one: npm run test
# Runs test-script.js as specified in root package's scripts
I would like to be able to determine the original subfolder that I run the scripts from. However, I haven't been able to find a way to access that directory. Both process.cwd() and __dirname are returning the parent level directory location of the script (my-app in the example).
My primary use case is to filter the tests to only run ones in the current sub directory, so adding individual scripts to run for each subdirectory isn't practical.
From npm docs:
Scripts are run from the root of the module, regardless of what your
current working directory is when you call npm run. If you want your
script to use different behavior based on what subdirectory you’re in,
you can use the INIT_CWD environment variable, which holds the full
path you were in when you ran npm run.
Docs from the pull request:
npm run adds current working directory to INIT_CWD. You can run scripts in subdirectory of project. For example, you want to run babel in specific subdirectory. You should write:
"scripts": {
"build": "babel $INIT_CWD/src -d $INIT_CWD/lib"
}
or you can write:
"scripts": {
"build": "cd $INIT_CWD && babel src -d lib"
}
Now, you can run the script, npm run build in any subdirectory you want to compile JavaScript. In your case, you may need to pass the cwd as an argument to the script and override the INIT_CWD var.
I am trying to run some Mocha tests within my Node.js app.
Here is my folder structure:
compute/
folder1/
app/
tests/
mytest.js
folder2/
app/
tests/
mytest2.js
I got a package.json in both with mocha installed.
When I try to start a test with yarn test, I got an error
Warning: Could not find any test files matching pattern: test
No test files found
How can I manage to run it?
Because my folders' names are "tests" and not "test" as in the default and they are not at source.
When you don't use the default folders, you need to specify them as arguments. An example follows:
mocha "folder{1,2}/**/tests/*.js"
If you want to run with only npm test/yarn test, then you need to update your package.json file like following:
"scripts": {
"test": "mocha \"folder{1,2}/**/tests/*.js\"",
},
I want to try using npm to run my various build tasks for a web application. I know I can do this by adding a scripts field to my package.json like so:
"scripts": {
"build": "some build command"
},
This gets unwieldy when you have more complex commands with a bunch of options. Is it possible to move these commands to a bash script or something along those lines? Something like:
"scripts": {
"build": "build.sh"
},
where npm run build would execute the commands in the build.sh file?
Reading through this post it seems like it is, but I'm not clear on exactly where I'm supposed to drop my build.sh file or if I'm missing something.
Its totally possible...
"scripts": {
"build": "./build.sh"
},
also, make sure you put a hash bang at the top of your bash file #!/usr/bin/env bash
also make sure you have permissions to execute the file
chmod +x ./build.sh
Finally, the command to run build in npm would be
npm run build
If you don't want to bother with giving permissions and the env you execute the script has for example sh, you could just do
"scripts": {
"build": "sh ./build.sh"
}
Even Simpler:
I routinely do this for one-offs and PoC's not involving a VCS
package.json
{
"scripts": {
"ship": "rsync -avz deployable/* <some-server>:/var/www/some-site/sub-dir/"
},
}
...
Just add 'bash' keyword before the file_name.sh
"scripts": { "build": "bash ./file_name.sh" }
then run "npm run build" on terminal
In case someone sees this and is using Docker for creating an image of this application.
Regarding:
but I'm not clear on exactly where I'm supposed to drop my build.sh file
Wherever you do decide to drop your build.sh file, make sure it is included in the Dockerfile image output, i.e. the file's path is in one of the COPY commands in the Dockerfile.
For example, if you have something like
scripts {
"build": "./scripts/build.sh"
}
Then your Dockerfile should have a COPY command similar to:
COPY scripts/build.sh scripts/