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.
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.
Within the root directory of my project, I run the following command using npm and html-minifier-terser:
npx html-minifier-terser --input-dir src/ --output-dir dist/ src/index.html -o index.min.html --file-ext html
The output file to dist/ is index.html and not index.min.html.
I tried to install html-minifier-terser globally, which does not help. I then tried to remove the specification of input and output directories within the command, which resulted in the expected behavior.
Any suggestions why I can't get dist/index.min.html to work?
Doing a little more research, I found a solution on this thread ng build production should minify index.html in dist.
The workaround is to omit using the input and output directory arguments and instead specify the output path as in --output dist/index.min.html.
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.
For my project, I have created a git on github containing some project related tools. The git contains a package.json and some binaries mapped to bin directives.
While being a private repo and not published to any actual NPM repo server, it can be installed using
$ npm install -g git+ssh://git#github.com:<path to my tool git>
Most of the tools don't have any dependencies to other files in the module, and they work just fine. But one of the tools is a wrapper to start a local DynamoDB server, and my package.json contains a section like this:
"bin": {
"ddb-local": "db/ddb_local.sh"
}
My db/db_local.sh file contains the java command to start DynamoDB:
#/bin/bash
java -Djava.library.path=DynamoDB/DynamoDBLocal_lib -jar DynamoDB/DynamoDBLocal.jar -inMemory
The DynamoDB folder is in the db folder which is in the root of my module:
<module root>
|
|- db
|- DynamoDB
|- DynamoDBLocal.jar
|- DynamoDBLocal_lib
| ddb_local.sh
|- package.json
After installation, ddb-local is linked from my node bin folder and can be invoked from anywhere, however the ddb_local.sh script will fail (unless the <path to my module>/db folder happens to be my current directory), since it tries to find files relative to the script, and the script will, in my case using NVM, be run from something like ~/.nvm/versions/node/v4.6.1/bin/
Now, if this was a node script, I would be able to require files in my own module easily, but since it is a bash script I am not sure what the best way is to produce a valid path to files in my module directory.
I know that my package is installed under ~/.nvm/versions/node/v4.6.1/lib/node_modules/<my module> and while I can create a relative path to my module's files using something like
`dirname "$0"`/../lib/node_modules/<module name>
this doesn't really seem to make sense. Surely there's an easy way to reference other scripts or files in your module from a script being globally installed as a binary? I have printed all environment variables etc, looking for something containing the path of my module, but with no luck.
I've come up with a slightly better solution using a combination of dirname and readlink:
SCRIPT_PATH=$(dirname $(dirname $0)/$(readlink $0))
This uses the fact that globally installed npm modules are installed as a symlink from $NODE_PATH/bin/<script> to ../lib/node_modules/<npm-module>/<script>.
It may not be 100% robust in all environments and it still feels like there should be an easier way, but it works.
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)