Config file in Node.js distributable package - node.js

I've been told to implement Continuous Integration for an existing application (FrontEnd: Node.js - BackEnd: .Net API).
The API endpoints are currently hardcoded in the .js files, that get "uglyfied" after the build (webpack). I want to move them to a config file, that gets copied to the dist folder, so they can be changed at deployment time (just like a Web.config file in the API).
I have zero experience with Node. Is this possible? How?

Look into a dotenv file and use process.env.MY_ENV_VARIABLE in your code to access environment variables. Here's one library https://github.com/motdotla/dotenv but I'm sure there others (can't remember which one I used in the past).
Edit: If you're using Webpack to bundle your front end app you might need to configure it to pull in environment variables, you can use the define plugin: https://webpack.js.org/plugins/define-plugin/

Related

Cons of directly pushing .env file in Google Cloud Standard App Engine

I am trying to add environment variables in my App Engine Standard NodeJs app, and I have found multiple ways, out of which one is to add them in app.yaml using separate file(which we will not commit to repo), and second is to directly push .env file while deploying to App engine (Not ignoring it).
I was just thinking what are the cons of the second step which is to directly push my .env file(which I was also doing in App Engine Nodejs Flexible app)? Are there any major issues if I will do that.
Thanks.
No, there is no issue with it. You can consider it as your own server. No one will have access to your environments variables. So, it's safe.

Environment Variables in App Engine for local dev

What's the best way to set environment variables when developing nodejs on a local machine for App Engine Flex environment? If they're set in app.yaml then they don't get set during local development. Is there a way to force this, or should I use something like dotenv and keep track of the same environment variables in 2 places?
Sensitive data (e.g. API Keys) should not be committed to source code.
The way I went around that is storing a .env file in Google Storage. Then you can use #google-cloud/storage to download it in production (using a prestart hook) and dotenv to load variables into memory.
You may find a full guide here: http://gunargessner.com/gcloud-env-vars/
PS: I would go for Aidan's answer for storing any data that is not sensitive. I have myself used dotenv satisfactorily in the past.
Similar to that, there's nconf, the package that gcloud itself uses for examples. Pretty neat!
Option 1:
require('dotenv').config({path: '/custom/project/root/app.yaml'})
Option 2:
Maintain both a .env file and a .yaml file with the same keys but different values (local and GAE, respectively). In app.yaml, I make sure not to deploy my .env file by adding the following line:
skip_files : .env
You will then need to add a check on ('dotenv').config() to make sure that it doesn't error or overwrite your process variables if no .env file is detected.
Aidan's suggestion is good.
As configurations should be different on GAE and local, I would suggest option 2 is best - a separate .ENV for local and .YAML for GAE environments.
One minor point though. I'd suggest to add a .gcloudignore files, something like the below:
.gcloudignore
.git
.gitignore
.env
staging.yaml
node_modules/

NodeJS config.json vs process.env for configuartion management

I've come across people using both methods to do config management.
What are the pros and cons of each approach?
If I have a lot of variables that I store in my config object, will I have to set them all one by one in an upstart script before executing the node app?
You generally use envvar to keep an application stateless. The same codebase should work in dev, staging, test and production environment.
You will put var like MySQL config, API keys, if log is enabled or not, if debug is on or not ...
Config file are used for variables which are not dependent of the environment. For instance, name of the application, number of items per page ...
I guess you can use config.json file for storing big configs. ENV I've usually use for passing application port or something very important for normal application start. For example if you use some external lib, it's better to be able to pass custom path to lib executor in ENV.
P.S. You should never save config.json in SVN.

Angular2 deploying to production environment questions

Some questions to put angular2 web project to production environment
We do development on lite server but what is best for production? Is is some other server module of nodejs? Technically we can have any server (apache, tomcat, etc).
How should we do source code management for below context.
browser must include js files so project should have js files when deployed
In standard java project we just commit .java files and uses jenkins (may be other tools) to compile and make the deploy-able structure
Should we follow same strategy here? i.e. don't commit compiled js files and deploy using some node compiler which takes ts files and compiles it to js
What is the best way to minify/obfuscate the js files
I know a way using outDir and outFile with grump but I don't want every files tobe included in one minified file because it kills the concept of lazy loading
Is there a way to minify and obfuscate js files on compile time only?
What enableProdMode() do? How it is different than not using it?
Here are some answers to your questions:
Angular2 applications only consist of static files so they can be serve by any static Web servers or server applications that can define static folders (Express, ...)
Regarding source code management, you must have a packaging phase to optimize the application loading (gater files, uglify, ...). Your source code must contain your TypeScript files (or JS files if using ES5 or ES6). Such packaging can be done using Gulp for example. Your Jenkins server will be able to checkout the source code, build it and execute tests.
In fact, when not using the outFile property of the TypeScript compiler, you won't be able to gather all the JS compiled files into a single one since anonymous modules will be created within each JS files.
See this question for more details of this:
How do I actually deploy an Angular 2 + Typescript + systemjs app?
Regarding prod mode, here is an extract of the documentation:
Disable Angular's development mode, which turns off assertions and other checks within the framework.
One important assertion this disables verifies that a change detection pass does not result in additional changes to any bindings (also known as unidirectional data flow).

Building (preparing) node.js application for production (deploy)

I have a project that consists of several nod.js backend applications. The apps are using the same modules (which a placed outside of each ap folder in shared location). The aps they are to be deployed on differnt environments (servers), some code is for test, some for debug as usual.
If I choosed a platform (for example PaaS nodejitsu) for one of my apps, how I'm supposed to send there only production code for one of my apps? I deployed on nodejitsu and it just sends the app folder and uses package.json to configure the app. But there are a bunch of code that is not need (tests) for example and some code is external. And what If I want to obstruct server code too? How this issues are supposed to be soleved?
For front-end applications has a tons of methods to be build for production. I understand that the requirements are different, but didn't find any infromation on best practices fo how correctly to prepare node.js back end application for deploy.
Read section "Keeping files out of your package" in the NPM Developer page. It states following
Use a .npmignorefile to keep stuff out of your package. If there's no .npmignore file, but there is a .gitignore file, then npm will ignore the stuff matched by the .gitignore file. If you want to include something that is excluded by your .gitignore file, you can create an empty .npmignore file to override it.
Add those test files in .gitignore
or make another branch for production in git and push the production branch.

Resources