NPM Run Build Always Builds Production and Never Development - node.js

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"

Related

How to execute postbuild script after all package script events?

The package.json of an Angular library defines the following scripts:
"scripts": {
"build": "node ../../node_modules/#angular/cli/bin/ng build dining",
"watch": "node ../../node_modules/#angular/cli/bin/ng build dining --watch",
"postbuild": "node copy-assets.js"
}
The postbuild script is executed successfully when I build the library: npm run build
but NOT when I call the watch script npm run watch:
Built dining
Built Angular Package!
- from: C:\[...]\projects\dining
- to: C:\[...]\dist\dining
Compilation complete. Watching for file changes...
"dining" is a angular library created by running npm run ng generate library dining.
copy-assets.js copies the library's assets folder to the dist folder.
Node.js version is 12 and npm version is 6.9.0.
How can I have the project built and watched for file modifications and the postbuild script executed in one command?

npm run build production does not distribute the production

I have a problem with my Angular project. Especially on the build of the project.
When I build my Angular poject with
ng build
it creates the dist-folder with the correct build. When I use the following command:
ng build --prod
it creates the production build (correct)
When I use NPM (used by build server) I use this:
run build
But I want the production build. Whatever I do, it doesn't work locally or on the buildserver. I used these:
npm run build --prod
npm run build --target=production
npm run build --environment=prod
npm run build --environment=production
npm run build --env=production
npm run build --env=prod
npm run build *projectname* --environment=production
npm run build *projectname* --env=production
npm run build *projectname* production
And probably a lot more. It just does not build the production!
I have a environment.prod.ts (production = true). It is set in the Angular.json. I have no clue what I am doing wrong.
You could also use -- to separate the params passed to npm command itself and params passed to your script.
So the correct syntax for your case would be:
npm run build -- --prod
npm run build should have the script in the package.json
have a look there and maybe add the line in the scripts
{
...
scripts: {
"build": "ng build --prod"
},
...
}
this should do the trick
What you can do is update the build script in the package.json as
scripts:{
"build": "npm run ng build --",
"ng": "ng"
}
-- allows you to pass arguments to a script.
Then you can pass the arguments to ng build like ng build --prod
Try this if your environment is production:
npm run build -- --configuration=production
or this if it's prod:
npm run build -- --configuration=prod
If you don't specify the "configuration" parameter name you may see this error:
npm run build -- --prod
Error: Unknown argument: prod
npm run build -- --production
Error: Unknown argument: production

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

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.

How do I deploy my Typescript Node.js app to Heroku?

When testing locally I was previously running:
"build-live": "nodemon --exec ./node_modules/.bin/ts-node -r dotenv/config -- ./index.ts"
I then figured my Procfile should be something like:
web: ./node_modules/.bin/ts-node -- ./index.ts
But it says module 'typescript' not found, even when it is in package.json. I read in a few places that ts-node is not the way to go to deploy to Heroku, so I am not sure what to do.
UPDATE: I think I am supposed to compile it, so I tried:
web: ./node_modules/.bin/tsc --module commonjs --allowJs --outDir build/ --sourceMap --target es6 index.ts && node build/index.js
This succeeds, however when actually running it, a bunch of the libs I'm using get "Cannot find module '...'".
Alternatively you can have the TypeScript compile as a postinstall hook and run node build/index.js as the only Procfile command:
Your package.json should contain a postinstall hint that gets executed after npm install and before the node process launches:
"scripts": {
"start": "node build/index.js",
"build": "tsc",
"postinstall": "npm run build"
}
You can then leave your Procfile as is:
web: npm start
This 'build on deploy' approach is documented by Heroku here.
The command you've given Heroku is to launch the web "process" by compiling index.ts and dependencies and starting node at index.js. Depending on how things are timed, index.js might or might not exist at the time node starts.
You need to already have your sources compiled by the time you want to start your app. For example, web should just be web: node index.js or similar.
Each build process is different, so you need to figure that out for your own setup. But, suppose you have a classical setup where you push to git and then Heroku picks up that change and updates the app with the new slug. You could just compile things locally and include index.js and any other build output in the repository, for it to be available in the slug for Heroku to use.
A better approach is to use a build server which has an integration with Heroku. After you do the build there, configure it to send the build results to Heroku. Travis has a straighforward setup like this. This way you don't need to include build outputs in your repository, which is considered an anti-pattern.
On a sidenode, try using a tsconfig.json to keep the tsc configuration. It will save you from having to write such long command lines all over the place.
Fabian said that we could do something like:
"scripts": {
"start": "node build/index.js",
"build": "tsc",
"postinstall": "npm run build"
}
As of me writing this, I tested this and can state: postinstall is not required since build script is ran by Heroku. If you want to do it without build script, then you can use heroku-postbuild which will run after dependencies are installed there you run tsc to compile.
My problem was about missing Typescript npm modules. The Typescript compiler tsc was not found when deployed the app to Heroku.
The Heroku deploy process (rightly) does not install development dependencies, in my case the Typescript module was part of devDependencies and thus the tsc command was not running on the Heroku platform.
Solution 1
Add typescript to dependencies: npm i typescript -s
Solution 2
Open Heroku console:
Select console type:
Run the command npm i typescript && npm run tsc
Install typescript as a dev dependency (cf. https://www.typescriptlang.org/download). Once built, your app does not need typescript anymore!
npm install -D typescript
Then in your package.json:
{
"main": "index.js", // <- file will be generated at build time with `tsc`
"scripts": {
"build": "tsc",
"start": "node ."
"start:dev": "ts-node index.ts" // idem, install ts-node as a dev dependency
}
}
The key point here is "build": "tsc".
Why?
Heroku does install all dependencies during build and remove the dev dependencies before the app is deployed (source here).
Node.js deployments will automatically execute an app’s build script during build (since March 11. 2019 source here)
In package.json
"scripts": {
"tsc": "./node_modules/typescript/bin/tsc",
"postinstall": "npm run tsc"
},
Works for me for Heroku deployment.
Installing typescript npm install -D typescript and writing tsc in the build script "build": "tsc", does not work for me. Also, try to run npm i typescript && npm run tsc in the Heroku console which also does not work.
In my case, I remove some dependencies from "devDependencies" to "dependencies", so it goes like this:
"dependencies": {
// The other dependencies goes here, I don't touch them.
// But all TS dependencies I remove to here.
"ts-node": "^9.1.1",
"tsconfig-paths": "^3.9.0",
"typescript": "^4.2.3",
"ts-loader": "^8.0.18"
},

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

Resources