Using a package.json variable in npm script - npm

I'm using npm run to build a javascript file through browserify. Before building, I would like it to create a directory in my build folder, named after the version listed in the package.json. Here is a trimmed example of my package.json:
{
"name": "My App",
"version": "0.0.0-pre-alpha",
"description": "App desc",
"main": "index.js",
"dependencies": {
"browserify" : "*",
}
"scripts": {
"prebuild": "mkdir -p build/$npm_package_version",
"browserify" : "browserify ./src/index.js ./build/$npm_package_version/js/myapp-$npm_package_version.js",
"build" : "npm run prebuild && npm run browserify"
}
}
The code executed in prebuild is:
mkdir -p build/$npm_package_version
But I want it to execute
mkdir -p build/0.0.0-pre-alpha
What am I doing wrong?

Update:
Turns out you can't use arguments with mkdir in a script. So i ended up using the mkdirp npm module.
Old post:
For others looking for an answer: Turns out when you are working in windows the correct way to use the variables is
%npm_package_version%
So the final code should look like:
"prebuild": "mkdir -p build/%npm_package_version%"

Related

How to login to AWS CodeArtifact before npm installs

How can I trigger the login before the install script in node v18.12.1/npm 8.19.2?
I expect the npm preinstall script will run before the install script based on the documentation. When running node v14.21.1/npm 6.14.17 I was able to follow the instructions in this tutorial to trigger a CodeArtifact login with the preinstall script. All packages were installed from my CodeArtifact repository on running npm install as expected.
After updating to node v18.12.1/npm 8.19.2, npm install fails with error:
Unable to authenticate, your authentication token seems to be invalid
What I have tested (each in a fresh environment with no npm cache):
npm run preinstall successfully logs on
∴ AWS credentials are configured and the preinstall script works when executed
npm install fails authentication
npm run preinstall; npm install successfully logs on and installs from CodeArtifact
∴ the preinstall script is not running. I get no results from filtering the debug logs suggesting the co:login step is not run:
$ cat /root/.npm/_logs/2022-12-06T07_12_47_353Z-debug-0.log | grep co:login
$ echo $?
1
After reverting to node v14.21.1/npm 6.14.17, npm install behaves as expected, logging in and installing packages from CodeArtifact.
I have recreated the problem with a minimal package.json which can be tested in a docker container:
docker run --rm -it -v ~/.aws:/root/.aws:ro --name app node:18.12.1 /bin/bash
wget --quiet -O "awscliv2.zip" "https://awscli.amazonaws.com/awscli-exe-linux-$(uname -m).zip" && unzip -q awscliv2.zip
./aws/install
rm awscliv2.zip && rm -r ./aws
Copy files in from a separate terminal
docker cp package.json app:/package.json
docker cp package-lock.json app:/package-lock.json
And then install with npm install in the docker container.
package.json template would require you to substitute your own CodeArtifact repository, domain and owner
{
"name": "app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"preinstall": "npm run co:login",
"co:login": "aws codeartifact login --tool npm --repository my-repository --domain my-domain --domain-owner 123456789 --region ap-southeast-2"
},
"author": "",
"license": "ISC",
"dependencies": {
"dayjs": "^1.11.6"
}
}
package-lock.json template would require you to substitute your own CodeArtifact url
{
"name": "app",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "app",
"version": "1.0.0",
"hasInstallScript": true,
"license": "ISC",
"dependencies": {
"dayjs": "^1.11.6"
}
},
"node_modules/dayjs": {
"version": "1.11.6",
"resolved": "https://mydomain-123456789.d.codeartifact.ap-southeast-2.amazonaws.com:443/npm/my-repository/dayjs/-/dayjs-1.11.6.tgz",
"integrity": "sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ=="
}
},
"dependencies": {
"dayjs": {
"version": "1.11.6",
"resolved": "https://mydomain-123456789.d.codeartifact.ap-southeast-2.amazonaws.com:443/npm/my-repository/dayjs/-/dayjs-1.11.6.tgz",
"integrity": "sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ=="
}
}
}

How to run npm scripts with forever.json?

I want to run an npm script (like npm start) using forever. I know this command:
forever start -c "npm start" /path/to/app/dir/
But how can I ad that into a json file like this
[
{
// App1
"uid": "app1",
"append": true,
"watch": false,
"script": "-c npm start", // doesn't work
"sourceDir": "/path/to/app/dir"
}
]
You cannot add directly npm start to the script, as you already know that script attribute is only to specify the main entry point of your application, probably you need to use some args.
"scripts" : { "start" : "node server.js" } }
where server.js is :-
http.createServer(...).listen(process.env.npm_package_config_port)

Watches not working in vscode? (Vuejs)

It took me a while to get the debugger to work within Visual Studio Code. Now the program breaks on set breakpoints inside of .vue files/components. But none of the watches seem to work. They are either undefined or unavailable, even when the variables have been created.
The settings I use in launch.json :
{
"name": "chrome debug",
"type": "chrome",
"request": "launch",
"port": 3000,
"url": "http://localhost:3000/admin",
"webRoot": "${workspaceFolder}",
"breakOnLoad": true
// "sourceMapPathOverrides": {
// "webpack:///src/*": "${webRoot}/*"
// }
}
I build my app through npm run build or npm run devbuild which, by my knowlegde, 'compiles' the .vue components into Javascript files. And then start the app with either npm start or nodemon index.js.
Package.json
"scripts": {
<...>
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules",
"devbuild": "cross-env NODE_ENV=development webpack --progress --hide-modules",
<...>
},
Have you ever tried add a new script with nodemon? Something like this:
"newScript": "nodemon -L -e ts,json --watch . --exec \"npm run build
|| npm run devbuild\""
-L = Though this should be a last resort as it will poll every file it can find.
-e = By default, nodemon looks for files with the .js, .mjs, .coffee, .litcoffee, and .json extensions. If you use the --exec option and monitor app.py nodemon will monitor files with the extension of .py. However, you can specify your own list with the -e (or --ext) switch like so: nodemon -e js,jade
--watch . = To watch all the changes on the path, in this case all the code on the current path.
(I got all of this information from the documentation.
then, run the command:
npm run newScript

npm pre commit not working

I am using npm precommit hook, but it is not stopping a file with issues to be committed, nor am I getting the message "Pre commit checks" when I try to commit a file.
Package Json:
{
"name": "myfolder",
"version": "1.0.0",
"description": "",
"main": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 0",
"precommit-msg": "echo 'Pre-commit checks...' && exit 0",
"lint": "csslint global/css"
},
"author": "SR",
"license": "ISC",
"dependencies": {
"csslint": "^1.0.4",
"jshint": "^2.9.4",
"pre-commit": "^1.2.2"
},
"pre-commit": [
"precommit-msg",
"lint"
],
"devDependencies": {
"pre-commit": "^1.2.2"
}
}
Please, make sure that your 'package.json' file is in the same folder, where '.git' folder is (where git repository was initialized). When you install 'pre-commit' package, 'pre-commit' file should appear under '.git/hooks/'.
Just FYI I had this issue because the pre-commit file was missing in the hooks folder.
Running npm i pre-commit --save-dev again created the file and solved it for me.
Have't managed to implement it with few "pre-commit" NPM modules (#fastify/pre-commit, monorepo-staged-precommit) so implemented it "manually" with adding tools/pre-commit.sh file into repo with content like:
#!/bin/sh
DIR='web'
echo "Pre-commit actions (NPM tests for $DIR)..."
cd $DIR && npm run test
and updating package.json with:
"scripts": {
"test",
"install-precommit": "cp ../tools/pre-commit.sh ../.git/hooks/pre-commit"
This solution has some limitations (like instead of automatic installation need to ask somewhere in "README" about npm run install-precommit and I'm not sure how it would work on Windows especially without Git Bash) but it worked for me.
Notes:
Other pre-commit NPM packages either didn't work as well or asked for NVM and other extra tools which I don't want devs to install for such small task.
pre-commit.sh may has any name and don't be executable - "install-precommit" task and git care about.

GULP: gulp is not defined

As shown in the screen shot below I am not able to run gulp to concat the JavaScript files. Its saying that gulp is not defined.
I have tried the following commands:
npm install -g gulp
npm install gulp
npm install gulp --save-dev
I have also set the environment variables as following:
C:\Users\<user>\AppData\Roaming\npm;C:\Python27;C:\Users\<user>\AppData\Roaming\npm\node_modules;C:\Users\<user>\AppData\Roaming\npm\node_modules\gulp;
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
//script paths
var jsFiles = 'scripts/*.js',
jsDest = 'dist/scripts';
gulp.task('scripts', function() {
return gulp.src(jsFiles)
.pipe(concat('scripts.js'))
.pipe(gulp.dest(jsDest));
});
you just need to install and require gulp locally, you probably only installed it globally
At the command line
cd <project-root> && npm install --save-dev gulp
In your gulpfile.js
var gulp = require('gulp');
this is a different dependency than the command line dependency (that you installed globally). More specifically, it is the same NPM package, but the command line program will execute code usually from a different entry point in the NPM package then what require('X') will return.
If we go to the package.json file in the Gulp project on Github, it will tell the whole story:
{
"name": "gulp",
"description": "The streaming build system",
"version": "3.9.1",
"homepage": "http://gulpjs.com",
"repository": "gulpjs/gulp",
"author": "Fractal <contact#wearefractal.com> (http://wearefractal.com/)",
"tags": [ ],
"files": [
// ...
],
"bin": {
"gulp": "./bin/gulp.js"
},
"man": "gulp.1",
"dependencies": {
// ...
},
"devDependencies": {
// ...
},
"scripts": {
"prepublish": "marked-man --name gulp docs/CLI.md > gulp.1",
"lint": "eslint . && jscs *.js bin/ lib/ test/",
"pretest": "npm run lint",
},
"engines": {
"node": ">= 0.9"
},
"license": "MIT"
}
so at the command line:
$ gulp default
will execute this:
"bin": {
"gulp": "./bin/gulp.js"
},
on the other hand, require('gulp') in your code will return the value of this:
https://github.com/gulpjs/gulp/blob/master/index.js
normally we see this in a package.json file as:
"main": "index.js"
but since this is the default, they just omitted it (which is dumb IMO, better to be explicit, but they aren't the first project I have seen take the lame shorthand route.).
Its occurs on Windows and usually one of the following fixes it:
If you didn't, run npm install gulp on the project folder, even if
you have gulp installed globally.
Normally, It isn't a problem on Windows, but it could be a issue with
the PATH. The package will try to get the PATH from the environment,
but you can override it by adding exec_args to your gulp settings.
For example, on Ubuntu:
"exec_args": {
"path": "/bin:/usr/bin:/usr/local/bin"
}
Hope It will be OK.
Source: https://github.com/NicoSantangelo/sublime-gulp/issues/12