why package.json script works fine on local project but doesn't work on a dependency project - node.js

I have created a npm module(let call it ModuleA) and defined clean script in its package.json file like below:
"scripts": {
"test": "nyc mocha tests/ --opts mocha.opts",
"build": "babel -d dist/ src/",
"prepublish": "yarn run clean && yarn run build",
"postinstall": "yarn run clean && yarn run build",
"clean": "rimraf ./dist"
},
I use rimraf to remove the dist directory. This dependency is defined in devDependencies as "rimraf": "^2.6.1". It works fine on this project. But in one of my other project (let call it ModuleB) which has a dependency on this module, the yarn install doesn't work and I get below error:
$ rimraf ./dist
sh: 1: rimraf: not found
this error happens when npm/yarn is building the ModuleB. I have checked that rimraf exist in node_modules/.bin directory in ModuleB. It works fine if I install rimraf globally. I wonder how I can make the npm/yarn to use rimraf from node_modules/.bin/rimraf?
BTW, I also put the rimraf in devDependencies in ModuleB.
I tried to update the script in ModuleA to use rimraf from node_modules/.bin/rimraf as below:
"clean": "node_modules/.bin/rimraf ./dist"
it works fine on ModuleA. But I got below error when run yarn install on ModuleB:
$ node_modules/.bin/rimraf ./dist
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
sh: node_modules/.bin/rimraf: No such file or directory
error Command failed with exit code 127.

See those issues:
https://github.com/yarnpkg/yarn/issues/721 (postinstall hook doesn't appear to be run #721)
https://github.com/yarnpkg/yarn/issues/853 (preinstall and postinstall are not run #853)
https://github.com/yarnpkg/yarn/issues/614 (Bug: issue with postinstall scripts in git-hooks package)
Now make sure that yarn clean and npm clean works as expected.
For example this will not work if you didn't install rimraf globally:
$ rimraf ./dist
But this should work:
$ ./node_modules/.bin/rimraf ./dist
Test those commands first:
npm run clean
and:
yarn run clean
to use the "clean": "rimraf ./dist" script defined in package.json.
Note that ./node_modules/.bin is added to your PATH when you run package.json scripts.
Try running the commands from the simple ones where you run the script directly without npm or yarn, then test with both npmand yarn, and then finally try to narrow down the problem with postinstall hooks.

Related

NPM Run Build Always Builds Production and Never Development

On an inherited project I have, I am trying to get the build command to build a version other than Production.
I have attempted to change the alias in the script section in package.json to pass in extra variables such as --dev and --configuration=dev to no avail.
The project has these json data files:
env.dev
env.development
env.production
with the package.json has this build alias build:dev which I run npm run build:dev:
"scripts": {
"start": "NODE_ENV=dev && react-scripts start",
…
"build:dev": "npm run build --dev --configuration=dev && react-scripts build"
}
This works and builds, but for production only which I verify when I view the resultant files.
If I remove the file env.production from the directory and run the build command, it fails with:
Creating an optimized production build...
Failed to compile.
Module not found: Error: Can't resolve 'polyfills' in 'C:\Work\MyProj\WebSiteName\src'
which just informs me that it can alias polyfills found in the env.production file for the location NODE_PATH=src/.
Thoughts?
you need to set the env. variable like you do in "start" before calling the build command.
"build:dev": "NODE_ENV=dev npm run build --dev --configuration=dev && react-scripts build"

How to run npm test after npm start in bash script

In my docker file, I want to run test script inside it after app is up in Docker dev version. Problem is when I created a bash script and add like that, test script is not working.
Here is my package json file:
"scripts": {
"build": "./node_modules/babel-cli/bin/babel.js src --out-dir lib --copy-files lib --plugins transform-react-jsx --presets es2015",
"bundle": "./node_modules/browserify/bin/cmd.js lib/client.js -o public/js/bundle.js",
"start": "npm run build && npm run bundle && node lib/server.js",
"test": "mocha ./src/*.test.js"
},
and here is bash script file
#!/bin/bash
npm start
npm run start
npm test
npm run test
Please let me know how to fix it, thanks much.
#!/bin/bash
npm run build
npm run bundle
forever start ./lib/server.js
npm test
I've found solution that I need to install forever or pm2 first.

cross platform "rm" command

I currently have the following script in my package.json for deleting all ".js" files in my bundles folder for when I run "npm run build". It works fine when running it in dev servers but breaks when it is run in a Windows machine.
{
"scripts": {
"build": "rm bundles/*.js && webpack",
},
}
Since I am hashing all my build files, I am required to delete them all before adding new ones, such that I don't end up with a bunch of old builds.
Is there a "rm bundles/*.js" that would work in both Mac and Windows?
The npm package rimraf is available for command-line usage in scripts.
First install locally into your project:
$ npm install --save-dev rimraf
Then update the build script in your package.json file:
"scripts": {
"prebuild": "rimraf bundles/*.js",
"build": "webpack"
}
The rimraf command (named after rm -rf) deletes the files.
Documentation:
https://www.npmjs.com/package/rimraf#cli
rimraf is a well established project with over 3,000 4,000 5,000 ⭐s on GitHub.
Take a look at shelljs:
ShellJS is a portable (Windows/Linux/OS X) implementation of Unix
shell commands on top of the Node.js API. You can use it to eliminate
your shell script's dependency on Unix while still keeping its
familiar and powerful commands. You can also install it globally so
you can run it from outside Node projects - say goodbye to those
gnarly Bash scripts!
And further to shelljs/shx, which provides the following example:
{
"scripts": {
"clean": "shx rm -rf build dist && shx echo Done"
}
}
An alternative:
You may also want to take a look at Gulp or Grunt, both so called Task Runners. Gulp has gulp-clean and Grunt has grunt-contrib-clean. Both aim to delete folders and/or files.
Let's take Grunt for example:
Add the Grunt CLI with npm i -g grunt-cli to your system
Add the needed packages to your project with npm i --save-dev grunt grunt-contrib-clean
Create a file named gruntfile.js
Add the following lines:
module.exports = (grunt) => {
'use strict';
grunt.initConfig({
clean: ['bundles'],
});
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.registerTask('default', ['clean']);
};
Update your script "build": "grunt && webpack"
Cross-platform, no dependencies
If you're like me and don't want to add 11 dependencies just to delete a directory, you can use node exit codes to conditionally run scripts:
e.g. Remove the ./dist folder
{
"scripts": {
"clean": "npm run clean:win && npm run clean:lin",
"clean:win": "node -e \"if (process.platform === 'win32') process.exit(1)\" || , if exist dist rmdir /Q /S dist",
"clean:lin": "node -e \"if (process.platform !== 'win32') process.exit(1)\" || rm -rf dist",
}
}
npm run clean
If you do not concern about 'rm/del not found' console.log, here is the short and simple solution, no additional dependencies are required, rm works on Mac and Linux, del works on Windows:
{
"scripts": {
"build": "(rm bundles/*.js || del bundles/*.js) && webpack",
},
}
Update: recursive-fs added a CLI for deleting a folder so you can now do:
"scripts": {
"clean": "recursive-delete \"./bundles\""
}
Original:
If you decide you don't need 11 additional packages just to delete a single folder, you can use recursive-fs and a short script:
node -e \"require('recursive-fs').rmdirr(require('path').resolve('bundles'), ()=>{})\"
Alternatively, someone could write an NPM package that does this and has only a single dependency on recursive-fs, which would still put it at 9 packages fewer than rimraf. Another option would be to fork recursive-fs and publish an NPM package that includes a CLI in it that makes using it for recursive deletions easier.

gcloud deploy fails nodejs

I'm trying to deploy to google app engine. When I do so, the initial information all seems correct, the docker build is successful, but after docker it tries the following and fails:
Beginning teardown of remote build environment (this may take a few seconds).
Updating module [default].../Deleted [https://www.googleapis.com/compute/v1/projects/jamsesh-1219/zones/us-central1-f/instances/gae-builder-vm-20160213t114355].
Updating module [default]...failed.
ERROR: (gcloud.preview.app.deploy) Error Response: [13] Timed out when starting VMs. It's possible that the application code is unhealthy. (0/2 ready, 2 still deploying).
I know that I'm running es6 code transpiled to run on node 4.1.2 which is the version I'm told I can use here - I just have to run nvm install v4.1.2 which will switch me over, so I include that in my scripts. Here are my scripts in package.json:
"scripts": {
"test": "test",
"clean": "rm -rf lib",
"watch-js": "./node_modules/.bin/babel --plugins transform-es2015-classes src --presets react -d lib",
"dev-server": "./node_modules/.bin/webpack lib/client/entry.js",
"lint": "./node_modules/.bin/eslint ./src",
"server": "node lib/server/server",
"start-dev": "npm run lint && npm run build && npm run dev-server && npm run server",
"start": "nvm install v4.1.2 && node lib/server/server",
"styles": "./node_modules/.bin/lessc ./public/less/bundle.less ./public/css/bundle.css",
"build": "npm run clean && ./node_modules/.bin/babel --plugins transform-es2015-classes src --presets react -d lib && npm run styles"
},
and my docker file:
# Dockerfile extending the generic Node image with application files for a
# single application.
FROM gcr.io/google_appengine/nodejs
COPY . /app/
# You have to specify "--unsafe-perm" with npm install
# when running as root. Failing to do this can cause
# install to appear to succeed even if a preinstall
# script fails, and may have other adverse consequences
# as well.
# This command will also cat the npm-debug.log file after the
# build, if it exists.
RUN npm install --unsafe-perm || \
((if [ -f npm-debug.log ]; then \
cat npm-debug.log; \
fi) && false)
CMD npm start
So yeah, I've got no clue why the deployment failing. I could definitely benefit from some more thorough documentation on deploying node on GAE. It works on a test repo. Is there something else I need to be doing to run node on GAE with my babel6 transpiled code? Or should something be different in my scripts? In the Google Shell I can run locally fine once I switch to node v4.1.2

Run npm from subdirectories on Heroku

I have a project which contains 2 subprojects:
First is the API
Second is the client
And both of these projects have their own dependencies mapped in their own packages.json files, which is placed in each subdir.
So the question is how to run npm install from sub directories on heroku?
I tried putting something like this in the main npm file
"scripts": {
"postinstall": "cd my_subdir; npm install"
}
But it doesn't work, showing can't cd to my_subdir
Utilize npm's --prefix option:
"scripts": {
"postinstall": "npm install --prefix ./my_subdir"
}

Resources