Load Local Environmental Variables For Use In NPM Scripts - javascript

I have an NPM script that looks like this:
"start": "server start --host $DEV_HOST"
There are lots of other scripts that also reference the $DEV_HOST env.
Currently $DEV_HOST is exported in my ~/.bashrc, but I would like to find a way of defining it locally to the project, for example in a .env file.
I wondered if npm offered a preall hook which would allow a simple bash file to be called which could load in the local envs, but no such hook exists.
It also appears that NPM doesn't offer any load mechanism for local envs out of the box.
The only solutions I can currently think of are:
Move all the scripts that need the local env to their own bash files and load in the .env file in each of these.
Call a separate script before each script that needs the local env that loads in the envs from the .env file.
Both of these seem unnecessarily cumbersome and don't scale well.
Is there any way of loading envs defined in a project-local file so that they are available for use in NPM scripts?
Note: I'm not asking how to load envs into an app. I'm asking how to make envs available to npm scripts. The two things are completely different. Dot-env adds envs to the current process. Even if you created a node script that used dot-env to load some envs, those envs wouldn't be available via $ variables as they are not loaded into the environment. They would only be available within the same process via process.env.

You can simply echo an environment variable in your NPM script.
For example, run the following on your command line in your project root:
export SOME_ENV=blalala
then in your package.json you can use it like so:
"scrips:" {
"print-env": "echo $SOME_ENV"
}
this outputs blalala to the console.
If you want to define environment variables in a .env to be available in your scripts use something like this: https://www.npmjs.com/package/better-npm-run
npm i better-npm-run
create your .env file then use the variables exactly as shown above

Related

What is the best practice to reference JavaScript libraries that when installed via NPM (in the node_modules folder)?

For example, I created folder, opened it with VS Code. Opened a terminal, used the command npm install jquery, it creates a folder node_modules within my created folder. I then create an HTML file, put HTML template in and now I want to reference jQuery. I know how to reference the files syntactically and all that, I am just looking to understand best practices.
Do I just reference jQuery... JavaScript files within there? Or am I missing a step?
before starting on a new project you should use npm init. this will initialize the project and generate a package.json file. This package.json file is used for managing the project's dependencies(libraries), scripts, version etc.
And after this every time you install a library using npm it will get listed in this package.json file under dependencies section.
example after initializing the npm:
npm i jquery
and you can get it using
const jquery = require('jquery')
or
import jquery from 'jquery';
i.e; without using the relative path, example:
import jquery from '../../node_modules/jquery..'
It sounds like you are missing the build step.
When developing with npm, you usually use a toolchain with compilers, bundlers and minifiers, which read the libraries from the node_modules folder and put the resources in a build folder which actually gets deployed, and from where the js file will be loaded.

Using tsconfig-paths with a project?

I'd like to setup tsconfig-paths for this project.
I'm not sure what I need to do after installing tsconfig-paths as a dev dependency.
Thoughts?
The plugin has to be registered dynamically via the command line for each script that is run. For example I have a data generate script in test/data/generate/index.ts. In order to run this script, which imports from #fs/utilities I need to do:
npx ts-node -r tsconfig-paths/register test/data/generate/index.ts
For my use cases this is enough as I have few scripts that need to be run dynamically inside the typescript project. For example for #fireflysemantics/validator everything exported is intended to be used by external dependencies, thus there are no cases where I need to run data generation scripts.

How to make electron-packager to use outer directory files while packaging

I am trying to package my electron app, which is basically two npm directories one inside other. The internal npm directory is my electron app and it makes use of the outer directory scripts. My internal package.json file which is associated with electron app is where I define my electron-packager scripts. I have a question here, I have given my source file for the package as '.' which means present directory, does this also consider the files in the outer directory? I tried this and my app is working fine for now, but I doubt if somewhere something can go wrong if I am not doing this properly. If this is not the proper way how can I tell electron-packager to consider files outside of the current directory? or Does it automatically consider all the required files and scripts irrespective of their path while packaging?
It automatically considers all the files present in the current directory which includes the package.json file. Also I found 'Bolt' useful while working with multiple npm packages.
https://www.npmjs.com/package/bolt

How to resolve path in env variable in package.json?

In node I want to set START_DIR on process.env to process.cwd().
How to that within scripts package.json?
I can't use env file for example. this app not using env file loader and I can't change that.
for example:
"scripts": {
"start": "set SOMEDIR=process.cwd() && node app",
....
console.log('res', process.env.START_DIR);
Just to be clear, process.env represents the environment of the Node process at runtime, so whatever environment variables are visible to the Node process can be accessed in your modules as process.env.WHATEVER_VAR.
And why not just call process.cwd() from your app's code? It will return the path from which you execute the node command, or in this case npm start. It would be helpful to know more about what you're trying to accomplish, as I don't see why you would want to do what I think you're trying to do.
If you really want to do exactly what you described, you can use node -e "console.log('something')" To output something to the shell. Here's how it might look when you run npm start from a bash shell in the directory you want process.cwd() to return. (I'm not sure of the Windows equivalent):
"start": "export START_DIR=$(node -e \"console.log(process.cwd());\") && node app"
There are other options though. You could refer to the operating system's built-in variable representing the working directory. Looks like you may be using Windows, so that variable's name would be CD. I believe the full command would look something like this:
set SOMEDIR=%CD% && node app
Or, if you're starting the process from a bash shell (Linux and MacOS):
export SOMEDIR=$PWD && node app
You can also just access these variables directly in your scripts using process.env.CD or process.env.PWD.
The only danger with this method is that it assumes CD / PWD hasn't been manually set to some other value. In Windows, one way to circumvent this is to create a batch file wherever you're calling npm start from. In the file, execute the same command but replace %CD% with %~dp0, which refers to the path containing the file. Then set start to a Windows command to execute the file, something like call ./file.bat.
Similarly, in a bash environment create a shell script and use $(dirname $0) instead of $PWD. Make it executable with chmod +x name_of_file and set start to bash ./name_of_file.
One last thing: if the name of the variable doesn't matter, package.json can tell npm to create environment variables prefixed by npm_config_. More info in the npm config documentation.

Change Directory in Node REPL not working?

Just earlier, I posted my question:
https://stackoverflow.com/questions/28336443/how-to-not-put-my-js-files-in-user-myuser-for-node-js
I have a file, hello.js, located in /Users/MyUser/Desktop/Node/
I can see that my default directory is /Users/MyUser/
Okay, so I get that I need to change my working directory. What I have been able to find so far is to use >process.chrdir('/Users/MyUser/Desktop/Node/');
Cool, that works, but now when I get out of the REPL shell, the directory resets.
The person who responded to my question said that I needed to run >node init and later npm install <name of dependency> --save
My first question: I have ran >node init and see that I can create this package.json file, what does this do exactly?
Secondly: I was told that I need to add dependancies. Could someone please explain to me what this means in Node terms? Does a dependancy simply mean a folder that I want node to include? Do I want to add this Node folder on my Desktop to be able to run my scripts?
I am currently trying to go through the learnyounode courses, however I do not want to have to save all of these test files in my /User/MyUser directory, so any advice would be greatly appreciated.
Thanks
I have ran >node init and see that I can create
this package.json file, what does this do exactly?
npm init is used to create a package.json file interactively. This will ask you a bunch of questions, and then write a package.json for you.
package.json is just a file that handle the project's dependencies and holds various metadata relevant to the project[ project description, version, license information etc]
I was told that I need to add dependencies. Could someone please
explain to me what this means in Node terms?
Lets say you're building an application that is dependent on a number of NPM modules, you can specify them in your package.json file this way:
"dependencies": {
"express": "2.3.12",
"jade": ">= 0.0.1",
"redis": "0.6.0"
}
Now doing npm install would install a package, and any packages that it depends on.
A package is:
a folder containing a program described by a package.json file
a gzipped tarball containing (1)
a url that resolves to (2)
a # that is published on the registry with (3)
a # that points to (4)
a that has a "latest" tag satisfying (5)
a that resolves to (2)
If you need to install a dependency that haven't been included in package.json, simply do npm install <packageName>. Whether or not you want to include this newly installed package in package.json is completely your take. You can also decide how this newly installed package shall appear in your package.json
npm install <packageName> [--save|--save-dev|--save-optional]:
--save: Package will appear in your dependencies.
--save-dev: Package will appear in your devDependencies.
--save-optional: Package will appear in your optionalDependencies.
Does a dependency simply mean a folder that I want node to include?
Umm, partly yes. You may consider dependencies as folders, typically stored in node_modules directory.
Do I want to add this Node folder on my Desktop to be able to run my
scripts?
No, node manages it all. npm install will automatically create node_modules directory and you can refer to those dependencies with
require() in your .js files
var express = require('express');
Node REPL simply provides a way to interactively run JavaScript and see the results. It can be used for debugging, testing, or just trying things out.
process.cwd() points to the directory from which REPL itself has been initiated. You may change it using process.chdir('/path'), but once you close the REPL session and restart, it would always re-instantiate process.cwd() to the directory from which it has been started.
If you are installing some packages/dependencies in node project1 and think those dependencies can also be useful for node project2,
install them again for project2 (to get independentnode_modules directory)
install them globally [using -g flag]. see this
reference packages in project2 as
var referencedDependency = require('/home/User/project1/node_modules/<dependency>')
Simply doing process.chdir('/home/User/project1/node_modules/') in REPL and referencing as
var referencedDependency = require('<dependency>') in your js file wont work.
>process.chdir('/Users/MyUser/Desktop/Node/'); change the working directory only for that particular REPL session.
Hope it helps!
This has nothing to do with node.js but is rather inherent in the design of Unix (which in turn influences the design of shells on other operating systems).
Processes inherit values from their parent's environment but their environments are distinct.
That terse description of how process environments work has a sometimes unexpected behavior: you cannot change your parent's environment. It was designed this way explicitly for security reasons.
What this means is, when you change the working directory in a process and quits that process your shell's working directory will not be affected. Indeed, your shell's working directory isn't affected even when the process (in this case, node REPL) is running.
This exact question is often asked by people writing shell scripts wanting to write a script that CDs into someplace. But it's also common to find this question asked by people writing other languages such as Perl, Tcl, Ruby etc. (even C).
The answer to this question is always the same regardless of language: it's not possible to CD from another program/script/process.
I'm not sure how Windows handles it so it may be possible to do it there. But it's not possible on Unixen.

Categories

Resources