What is the benefit of importing process in node? - javascript

I am used to simply using process.cwd() directly inside of node applications, however, I have recently read the node docs and saw that it recommends importing it from node:process.
So what is the difference from just calling it directly?
process.cwd()
vs importing it and calling it:
import {cwd} from 'node:process'
cwd()
I am currently building a CLI application in case that makes a difference.
Is there a difference?
Which one should I be using?

importing it from node:process guarentees that you get the built-in process module, not some global that some other code in the project has configured or overridden.
This may be done for safety reasons or just for robustness reasons so other modules in the project can't hack on a global process object before you get to use it.
It also may not normally be needed, but is considered good project hygiene as it deters certain types of hacking.

Related

How to integrate legacy JavaScript with NodeJS in the browser

Hypothetical legacy scenario:
Say I have 4 scripts that simply get concatenated together as a single script for deployment to provide a utility library with a global namespace in the browser.
I then have 1 separate application script that utilizes the library.
Something like:
<script src="library.js"></script>
<script src="app.js"></script>
In my app.js script, calls are made to the library methods through its namespace, like
var id = lib.id(prefix);
I see that 1 of the 4 library scripts is a useful utility that I want to turn into a Node module. I copy it and create a package and publish it to npm to use in new development.
Problem: Now I have two versions of this script to maintain - one for Node and one for the legacy library.
Is there a way to have one common file that I can include in both the Node module and the legacy library? Or am I stuck maintaining two versions of the file until we phase out the legacy code?
Additional info:
I looked at browserify and webpack, thinking they might be useful, but both suffer from a problem I don't know how to get around. Unless the end module defines global variables, I can't use the module in legacy code, as there is no require command available. In other words, I can't browserify a Node module, then drop it into a legacy web page and use it in my existing app.js, because I can't call var mymodule = require('mymodule'). Is there any way to get browserify or webpack to define and expose a require function to let me access my new Node module from a legacy codebase? Surely, this is not a unique scenario.
Your best bet is to use a UMD pattern to ensure that the module can be used both as a global and in commonJS (ie- node) systems.
The pattern that would fit best for you is returnExports. This ensures that all exported properties are either applied to the global object (ie- window) or to the module object in node.
Since you are not using AMD, you can simplify the pattern somewhat and remove the first chunk of the if statements on lines 18 and 42.
This will require you to reorganize your code so that it fits in with the pattern.
There are other patterns that you may use, such as commonJsStrictGlobal, but I personally prefer returnExports.

Can't find modules required in React

I was going through the React codebase, and I noticed how React's require doesn't quite behave like in Nodejs. I don't get what's going on here.
Looking at line 19 on ReactClass.js for instance, there's a require('emptyObject'), but emptyObject isn't listed in package.json, nor does it say anywhere where that module's coming from.
https://github.com/facebook/react/blob/master/src/isomorphic/classic/class/ReactClass.js#L19
I did find "emptyObject" on npmjs, but the API there seems different from the one used in React; the .isEmpty grepped in React isn't related to emptyObject.
So where is emptyObject getting loaded from, and how is React's require doing what it's doing? This is not intuitive. At all.
The location of the emptyObject module which React refers to is https://github.com/facebook/fbjs/blob/master/packages/fbjs/src/core/emptyObject.js#L9 Note that it doesn't follow the CommonJS module system.
To make it easier for Facebook to share and consume our own JavaScript. Primarily this will allow us to ship code without worrying too much about where it lives, keeping with the spirit of #providesModule but working in the broader JavaScript ecosystem.
From https://github.com/facebook/fbjs#purpose
The way of defining a module by adding #providesModule in the license header and loading those modules with require in Node is called Haste, a customized module system built for Facebook's open source projects.
In fact, unless you would like to understand the inner workings of React or contribute to Facebook's open source projects, you don't need to know that. In other words, it's not recommended to use Haste to write your own project.
Along the same lines, the invariant module being loaded at line 10 of ReactClass.js is declared at https://github.com/facebook/fbjs/blob/master/packages/fbjs/src/__forks__/invariant.js#L9
As far as I know, both Eclipse and WebStorm don't support Haste so IDE can't help. But with Haste, the name of file and module should be the same, so you can find a module by searching for the filename, i.e. double shift in Webstorm and Ctrl+Shift+r in Eclipse. However, the emptyObject you asked about or invariant are not part of React so it's still cumbersome to find their origin.
Otherwise, there is a team that shares and organizes what they learn from hacking React that I contribute to occasionally and they have linked those requires by following Haste to the corresponding origin file e.g. https://annot.io/github.com/facebook/react/blob/cc3dc21/src/isomorphic/classic/class/ReactClass.js?l=19 You may want to see that.
I noticed how React's require doesn't quite behave like in Nodejs.
Right. Facebook has its own module loader. All modules have unique identifiers, provided by the #providesModule directive in each module. This allows you to use the identifier to load the module, instead of the file path.
Of course that doesn't work in a Node.js based environment. So when React or any other Facebook project is published to npm, all require calls are rewritten automatically to something that Node understands.
This functionality is provided by fbjs which contains shared dependencies and build helpers for all Facebook projects. This is where you find the emptyObject module.
If you look at React's gulp file, you can see how the module maps are constructed and that a custom Babel plugin is used to convert all require calls.

ES6 code on Nodejs 4.x : Is V8 4.5 a native JS engine that runs ES6 directly?

I'm trying to upgrade a micro service that's on Nodejs 1.0.x to Nodejs 4.x.
The purpose is to enhance the functionality of this service & take advantage of ES6 features, especially avoid prototype clutter in new code segment.
While going through few blogs, I've come across a statement that ES6's module pattern is standardised and it's Asynchronous unlike require().
If the module loading is Asynchronous(with import of module syntax), I'm trying to understand how the code in that file take advantage of this feature? All the code that have dependency on this asynchronously imported module will also become asynchronous? If yes, instead of combination of require (synchronous) and import/module (asynchronous), I would like to change every thing to import/module assuming the performance gain.
I need some help in correcting or fine-tuning my thought process.
ES6 modules are loaded synchronously in Node.js (server). They are loaded asynchronously only in the browser. The advantage of import is that it's the same keyword for both use cases.

using requirejs with node

I'm currently working on a server side Node project. Although node has it's own module loader using CommonJS I'm evaluating whether to use RequireJS with it. Whilst there are advantages to using RequireJS with Node if the application that has some client side aspects to it, I can't find any benefits for a project which is entirely server side.
Is it commonly thought that for a 100% server side Node project, there are no real advantages to incorporating RequireJS?
There exist reasons to use RequireJS server-side but they are few. Unless you can state a reason, like:
I must use RequireJS because X
where "X" is a reason which justifies the use of RequireJS, then you should not do it.
Note that just wanting to write modules in the AMD format is not reason enough as there exist loaders (like node-amdl-loader) which allow loading AMD modules in Node. I actually use this when I want to test code which does not depend on a browser. I write the modules in AMD format and specify that if used in Node, an AMD loader like node-amd-loader should be used. This way the library works both in Node and in the browser but I test it in Node.
One reason to use RequireJS server-side is for instance, if you need to run code that needs a DOM implementation. If you use something like jsdom to provide the DOM and the code you want to load is a series of AMD modules, then using RequireJS to load the code into the DOM environment created by jsdom makes sense.
I've never found a good reason to use RequireJS in node. However, RequireJS can be run on node, and the documentation has a brief explanation of why you might want to run RequireJS on a Node server:
By using RequireJS on the server, you can use one format for all your
modules, whether they are running server side or in the browser. That
way you can preserve the speed benefits and easy debugging you get
with RequireJS in the browser, and not have to worry about extra
translation costs for moving between two formats.
Most of that is only useful in a project that also has a client element. If it were me, I'd stick with Node's internal module loader.

Using a browser-ified module in an app that then needs to be browser-ified

I have written a self contained angular js module using browserify in order to make use of the commonJS/Node style syntax.
The module works fantastic when tested by itself, so I then use gulp to minify and host that on GitHub.
I've then imported that into another app that is also using browserify. When I run browserify it seems to try and rebrowserify the module and causes no end of problems.
I believe this is because the module requires angular and jquery and qtip2. So it's obviously trying to re parse these.
Is there a standard to not parse modules, or is there a way to exclude the browserifying of the modules? Or is it best to not include things like angular and jquery within your modules? I was trying to make them perfectly stand alone, maybe that's unwise?
Many thanks!
I would suggest providing both options, if it is important for you to have a standalone version that includes angular. This will provide people using your code with a total of three ways of using your code: Using the standalone version, the version that only includes the module, and cloning the repository directly and including the source files as part their build process.
I generally use the third option, but people who don't have build processes will likely prefer the first or second.

Categories