How to use lerna with dotenv package? - node.js

I have a monorepo managed using Lerna. I need to use multiple environment variables to start my web server. My npm script to start the server is:
"scripts": {
"dev:start": "lerna run --parallel dev:start"
}
I am also trying to use dotenv package to load environment variables for .env file. Since, dotenv is purely development helper to set env vars, I have installed it as a devDependency of top package.json. dotenv utilizes node.js preload script like: node -r dotenv/config server_script.js.
But with Lerna, I can no longer invoke preload script. Is there any way to use dotenv with lerna? Or alternately, how to run preload scripts with lerna?

But with Lerna, I can no longer invoke preload script
That's not true. Lerna allows you to pass arguments to the npm script. You just need to pass it with a pair of double dashes:
packages/ServerPkg/package.json:
"dev:start": "node foo.js"
package.json
"dev:start": "lerna run dev:start -- -- -r /path/to/dotenv"
Should execute:
node foo.js -r /path/to/dotenv

Related

Reactjs : set .env file with 3 variables(prod,dev,staging) in the build folder with react build

I have a react app with build folder ( generated by : npm run build ) , I want to have 3 variables in my .env file ( just one file ):
REACT_APP_API_URL=http://localhost:3000/api ( for production)
REACT_APP_PROD_URL=http://localhost:3001/api ( for staging)
REACT_APP_STAGIN_URL=http://localhost:3002/api ( for development)
and use them in the npm run build folder
Create differences env files
install yarn add env-cmd
and add script to package.json:
"start-qa": "env-cmd -f .env.qa react-scripts start"
or build:
"build-qa": "env-cmd -f .env.qa react-scripts build"
try with cross-env
something like this in your package.json
"start": cross-env REACT_APP_API_URL=http://localhost:3000/api node scripts/start.js
may be it will help you in achieving your stuff
You need to create a separate .env file for each environment.
As said in CRA Documentation: What other .env files can be used?:
.env.development, .env.test, .env.production: Environment-specific settings.
You can't place all your env variables in one file, the values will be overridden. For more information check dotenv documentation
Or if you want to edit env variables after building your project, please refer to this: https://stackoverflow.com/a/56120507/5078746

Transpiling ES6 and launching Express app upon file change

I'm developing an Express app. The code uses ES6 import statements, so it needs to be transpiled by Babel in ES5 code so it can be run with Node. The ES6 source code is stored in my src directory, and the compiled code is placed in my dest directory.
I would like an npm command that I can run that will watch for any changes in my src directory, transpile the project into dest, and then restart the Express app.
Below is my solution so far (I run npm run server:watch). It uses chokidar-cli to execute the server:build and server:run scripts whenever any js file changes within my src directory. This works perfectly except that the Express app does not die when the code is transpiled again, so I get a 'port in use' exception when I try to run server:watch again.
// package.json
"scripts": {
"server:clean": "rm -f dist/*",
"server:build": "npm run server:clean && ./node_modules/.bin/babel ./src --experimental --source-maps-inline -d ./dist",
"server:run": "nodemon dist/app.js --watch",
"server:watch": "chokidar 'src/*.js' -c 'npm run server:build && npm run server:run'"
}
Am I on the right track here? What is the best solution to this sort of problem?
(For clarification, I am talking about transpiling server-side code, so webpack or any other module bundler would be inappropriate here)
nodemon is watching your dist files, and is never terminating. With your watch script, you're launching a second instance of nodemon every time there's a file change, hence the "port in use" error.
You need to launch nodemon once, and keep in running in the background while your watch script is running. This is most easily done with https://github.com/mysticatea/npm-run-all.
Install it by running:
npm install npm-run-all --save-dev
on the command line.
Then you'd edit your scripts to:
// package.json
"scripts": {
"server:clean": "rm -f dist/*",
"server:build": "npm run server:clean && ./node_modules/.bin/babel ./src --experimental --source-maps-inline -d ./dist",
"server:run": "nodemon dist/app.js --watch",
"server:watch": "chokidar 'src/*.js' -c 'npm run server:build'",
"server:dev": "run-p server:run server:watch"
}
Then, you simply run npm run server:dev on the command line to start up your server via nodemon, and start the watch/rebuild process, all in one command.
Side note: If you're developing on Windows, you won't be able to use single quotes in your scripts, you have to use double-quotes, escaped with \" in the JSON.

Create single binary from express + react app with zeit pkg?

How do I package an express + react folderstructure into a single binary with zeit?
I can run each of them like this:
node server.js
npm run start client
I can start both like this:
scripts element in package.json:
"myapp": "concurrently --kill-others \"node server\" \"npm run --prefix client start\"",
then - npm run myapp in the same folder as package.json.
What I would like to achieve is to apply zeit/pkg somehow so that I have a single binary that I can run that starts both servers in the same way as npm run myapp.
Anyone who knows how?
I don't think zeit/pkg accepts multiple entry points based on their documentation
The entrypoint of your project is a mandatory CLI argument. It may be:
Path to entry file. Suppose it is /path/app.js, then packaged app will work the same way as node /path/app.js
Path to package.json. Pkg will follow bin property of the specified package.json and use it as entry file.
Path to directory. Pkg will look for package.json in the specified directory. See above.
Maybe the better route would be to do some server-side rendering via their Next.js framework? Then you would only have to package your app via the NodeJS entry point.

Run npm scripts using local deps

Currently I run npm scripts using local deps this way:
package.json:
"scripts": {
"test": "node ./node_modules/karma/bin/karma start",
"node-test": "node ./node_modules/jasmine/bin/jasmine",
"build": "node ./node_modules/gulp/bin/gulp build"
},
I don't want to use global deps, since I can forgot to add deps to the package.json. This way when a local dep is missing, then I got an error message and I don't have problems because some deps are not installed globally, e.g. karma plugins.
Is there a better (shorter) way to define npm scripts using the local libs? Is this travis compatible?
edit:
If it wasn't obvious I have the same libs installed globally, but I want to use the local installs by these projects. That means when I start karma with karma start then the globally installed version will start the karma server, which means that if I don't have all of the karma plugins globally installed, then I got error.
Another problem that I have windows, so the solutions described here: How to use package installed locally in node_modules? do not work. Windows does not recognize the #!/bin/sh and the #!/usr/bin/env node head sections and there is no sh command as far as I can tell. At least not in webstorm terminal. Git bash has the sh command, but I want to run these npm scripts from webstorm terminal.
One possible solution could be to fix somehow webstorm so it could use sh from terminal. After that I could use $(npm bin) I assume. But that's just a guess. I am not sure whether this can be done.
npm automatically puts prepends the path ./node_modules/.bin to your PATH env before it executes commands run by using npm run (including the two "magic" shortcuts npm start and npm test)
npm scripts docs
You can just set this up with:
"scripts": {
"test": "karma start",
"node-test": "jasmine",
"build": "gulp build"
}
Assuming that you have karma, jasmine and gulp-cli listed in either your devDependencies or dependencies (so that they're install when doing npm install)
And yes, it is travis-compatible. Here is an example of a package that is tested on travis using tap which is installed locally as a module:
https://github.com/scriptoLLC/couchdown/

NODE_PATH not recognized

Here is my package.json script:
"scripts": {
"start": "NODE_PATH=$NODE_PATH:./shared node",
"dev": "npm run start & webpack-dev-server --progress --color"
},
When I run npm start in Windows 8 it shows the below error:
node_path is not recognized as a internal or external command, operable program or batch file
I had the same problem when I wanted to set the environment variable in a browserify script:
"scripts": {
"build:symlinked": "NODE_PATH=./node_modules browserify src/index.js > dist/build.js"
}
To be able to use linked node modules that are requiring peer-dependencies.
As mentioned above, you can try to set the environment variable manually or by script where it seems you have to use different commands depending on what command line tool you use.
For not having to do this every time, I found that npm package: cross-env.
By installing it and applying the script like this
"scripts": {
"build:symlinked": "cross-env NODE_PATH=./node_modules browserify src/index.js > dist/build.js"
}
I was able to solve that problem. This is mainly useful, if you work in a team with mixed MAC/Linux and Windows users, so you don't have to to take care about applying the Environment variables in such scripts anymore.
You don't need to define environment variable in package.json just use this
{
"scripts" : "node server.js"
}
or define what you want, here is the reference link.

Resources