why node uses require not import? - node.js

I'm learning node.js and am wondering why it uses the require syntax rather than the import syntax which React uses.
i.e.
const Validator = require("validator");
VS
import Validator from "validator";
I believed import is es6 but I don't think that explains why it's not used in node.

the import and default are newer ES6 features, not yet used by node. Node is actually already implementing the new features as experiment though: with the --experimental-modules flag and only for files saved with .mjs extension.
Transpilers like babel make it possible to write modern, spec approved and /or experimental ECMAScript. In an ecosystem of bundlers like Webpack with transpilers like babel, it becomes easy to write maintainable, future-proof javascript, while the code remains widely suported because it's transformed to commonjs (the format you see recognizable byrequire (the old-school import) and module.exports (the old-school export).

Probably for historical reasons. node.js and chrome (v8 engine) are older than ES6 standard.
On the other hand, see:
How can I use an es6 import in node?
You may use import, too.

I believed import is es6 but I don't think that explains why it's not
used in node.
Just like the way NodeJS implements their entire library which tons of asynchronous functions which only support callback-based approach. Thinking this way and you'll realize that, sooner or later, the NodeJS framework will definitely support the import syntax and upgrade all of those asynchronous functions to support promise-based.

Related

Node.js: "In Node.js, each file is treated as a separate module." What breaks that rule? [duplicate]

I have started working on an existing project based on Node.js. I was just trying to understand the flow of execution, where I encountered with some *.mjs files. I have searched the web where I found that these are module based JS-files.
I want to know how is it different from *.js files (how does it benefit)?
It indicates an ES6 module file.
Node.js's original module system is CommonJs (which uses require and module.exports).
Since Node.js was created, the ECMAScript module system (which uses import and export) has become standard and Node.js has added support for it.
Node.js will treat .cjs files as CommonJS modules and .mjs files as ECMAScript modules. It will treat .js files as whatever the default module system for the project is (which is CommonJS unless package.json says "type": "module",).
See also: Differences between ES6 module system and CommonJs
.MJS file
mjs an extension for EcmaScript modules
An MJS file is a source code file containing an ES Module (ECMAScript Module) for use with a Node.js application.
MJS files are written in JavaScript, and may also use the .JS extension outside of the Node.js context.
ES Modules allow web and application developers to organize code into smaller reusable components.
ECMAScript 6 (ES6) introduced the specification for ES Modules, providing a standard for implementing modules in JavaScript. As of 2018, all major web browsers support ES Modules.
However, the popularity of modularized JavaScript pre-dates ES6. Node.js, a JavaScript runtime environment, used CommonJS as the specification for modules. Because so many existing applications were built with CommonJS, when Node.js added support for native ES modules, it controversially introduced the MJS file extension to differentiate the two and prevent applications from breaking.
NOTE: Some developers informally refer to MJS files as "Michael Jackson Script" files.
For clarity. As for devs/humans, it's easy to distinguish between a module file(.mjs) and a normal javascript file(.js)... because it's not always easy to determine even if you examine the code in the file.
There are also performance benefits which gives you more reason to consider using it.
V8(JavaScript engine that powers Google Chrome) recommends the use of .mjs but it still depends on your situation. If you want to know more of it's advantages, check https://v8.dev/features/modules#mjs

What to use in tsconfig, commonjs, umd, or es6 module?

What module to use in tsconfig, commonjs or es6?
How to make desicion? I need that output module will work in client/back sides.
So here we are talking about the module option that will be used by typescript to determine what is the name of the module that will compile your code to the targeted version of javascript you specified with the option target.
So the underlying question you are asking is, what is my target ? Should I target ES3, ES5, ES6, ES7, ES8 or ... ES42 ?
Answer : the compatibility.
In 2020 you propably target ES5 or ES6 (which is the default value).
(You can ignore CommonJS because it relate to ES3 which is 99% chance irrelevant to you)
some article
If your code is made to be executed on browsers, I would recommand you to look which is the latest version supported by all your targeted browser and take the one that is supported by all.
Ex: Safari ES6, Firefox ES8, Chrome ES8 : so you choose ES6 as target so your code works on every targeted browser.
The website caniuse.com is usefull to know which features are supported and which are not
If your code is made to run on backend (node.js), look at which version of node.js is running. Every version of node have different capabilities.
You can have a look here
Additionnal materials :
What version of Javascript is supported in node.js

What are the trade-offs of writing conventional node modules in ES6 with a babel workflow?

When developing front-end code for the browser, I often use the es2017 preset when transpiling down to a distribution bundle, which allows me all the conveniences of the included transformers. For conventional modules, I usually stick to whatever the required node engine I've specified for that particular module supports.
I would like to start developing these "conventional" modules using babel transformers as well, but I can foresee drawbacks to this, including:
It might inhibit the debugging workflow (more specifically when working with an IDE)
The performance of the module might suffer
What's the current state on this matter - would you say it makes sense to use babel in conventional modules given the aforementioned and other trade-offs? What are the pros/cons for your preferred workflow?
Bonus question: What are some reputable modules and/or module authors out there that are already using this technique? I've seen Facebook do it for their react ecosystem but I guess that makes sense since those are mostly modules for the browser.
It is converted back to vanilla JS (babel does that part).
What you get is that you can utilize Classes which I found useful.
Hopefully with time, browsers will support ES6 and we will not need babel.
The only drawback is that when debugging, you have to produce a source map, but that is temporary, see above.
To answer your second question: I'm using React in one of the websites, and most of the modules I needed (from npm) are using ES6.
I believe that the trade-offs or drawbacks that you mention both do not apply to developing nodejs code using babel as ES7 transpiler. Personally, I find using ES7 features with node tremendously productive.
There is source map support for debugging. I use karma for testing and it comes with excellent source map support (I use IntelliJ but I believe most IDEs will do). You can checkout this REST-API repository on github. It's a nice stack for building nodejs data backend. It uses karma for testing - even comes with code coverage support. It also integrates with pm2 for scaling and availability.
Regarding performance: I think transpiled code has been shown to run faster in many scenarios than the code a developer would write when not having advanced language features available. I will post some links later.

How can code that might run under NodeJS, JXcore, etc detect whether it's running in an environment that supports native ES6 promises?

For example, I have pretty current versions of official Joyent NodeJS installed with of course the Google V8 JavaScript engine and also JXcore with the Mozilla SpiderMonkey JavaScript engine.
The former seems to come with native Promises support, the latter seems not to.
(And of course these are not the only two possible environments nodeJS code might run under.
How can my code test its environment to see whether it can use native Promises or not?
It's OK if it detects a proper polyfill as "native" in this case. But it shouldn't detect something like Q as native promises. (Or let me know if I'm wrong about this.)
To directly answer your question, use this to detect the availability of ES6 promises:
typeof global.Promise === 'function'
Alternatively use a lightweight ES6 promise polyfill instead of relying on a larger partially-incompatible library.
With a polyfill you can just use the normal Promise API and simply remove the require once it's no longer needed — no refactor necessary.
A longer but trustworthier alternative is something like what this package uses:
global.Promise && Object.prototype.toString.call(global.Promise.resolve()) === '[object Promise]')
Well, you can use a package that uses native promises if they're available and if they're not it shims them.
Alternatively, since it's the server, you might be better off using a compatible userland library until all your environments support native promises.
Note that jxcore does not support some standard NodeJS promise features like unhandledRejection that userland polyfills and libraries support.
As for detecting native promises - it can be hard across environments. Technically you could check if there is a global Promise object as the first line of code in your program but that's messy compared to the alternative of just using a compatible faster userland library.
This might do it:
Promise.resolve() instanceof Promise
From comments to this other answer, it seems this only returns true for native ES6 promises.
This solution would likely reject a polyfill however.

To Babel or Not - Confused

I don't know with web apps if you still have to use Babel if Node 4 is out which supports ES6 so why would I need babel anymore for any web related code? Or maybe I don't?
I see most apps are using babel but I wonder if people are pulling it out now or is there middleware people typically use in web apps that still rely on it, thus you have to keep it and keep using babel?
Node v4 doesn't support the full feature set of ES2015 (aka ES6). For those that aren't supported you still can use Babel. You can find a list of node's support of ES2015 features in this page.
You say "web related code", which is too broad, but I assume you're interested in browser support as well. No browser supports all ES2015 features yet, so you should use a transpiler like Babel. You can find a table of feature compatibility here.
You will also find that no transpiler has full support either, so be careful when introducing new features.
It's not likely that projects will stop using transpilers yet. Even less so if they want to support older versions of node.

Resources