We announce support for ECMAScript modules in Node.js

Node.js 13.2.0 comes with ECMAScript support for modules known for their import and export syntax. Previously, this functionality was behind the --experimental-modules flag, which is no longer required. However, the implementation is still experimental and is subject to change.


From a translator: this long-awaited feature will finally allow us to use the standard modular syntax already available in modern browsers, and now also in Node.js without flags and transpilers


Activation


Node.js will process the code as ES modules in the following cases:



In all other cases, the code will be considered CommonJS. This applies to .js files without "type": "module" in the nearest package.json and to the code passed through the command line without specifying --input-type . This is done in order to maintain backward compatibility. However, since we now have two kinds of modules, CommonJS and ES, it will be better to specify the type of modules explicitly.


You can explicitly mark your code as CommonJS with the following features:



To learn more about these features, see the "Package Scope and File Extensions" documentation sections and --input-type


Syntax import and export


In the context of the ES module, you can use import , pointing to other Javascript files. They can be specified in one of the following formats:



In imports, you can use default ( import _ from "es-module-package" ) and named values ​​( import { shuffle } from "es-module-package" ), as well as import everything as one namespace ( import * as fs from "fs" ). All built-in Node.js packages, like fs or path , support all three types of imports.


Imports that point to CommonJS code (that is, all current JavaScript written for Node.js require and module.exports ) can only use the default option ( import _ from "commonjs-package" ).


Importing other file formats such as JSON and WASM remains experimental, and requires the flags --experimental-json-modules and --experimental-wasm-modules respectively. However, you can download these files using the module.createRequire API, which is available without additional flags.


In your ES modules, you can use the export keyword to export default and named values.


Dynamic expressions with import() can be used to load ES modules from either CommonJS or ES code. Note that import() does not return a module but its promise (Promise).


import.meta.url is import.meta.url available in the modules, which contains the absolute URL of the current ES module.


Files and the new "type" field in package.json


Add "type": "module" to the package.json of your project, and Node.js will begin to perceive all .js files of your project as ES modules.


If some files of your project still use CommonJS and you cannot migrate the whole project at once, you can either use the .cjs extension for this code, or put it in a separate directory and add package.json containing { "type": "commonjs" } , which tells Node.js that it should be treated as CommonJS.


For each downloaded file, Node.js will look at package.json in the directory containing it, then one level up, and so on until it reaches the root directory. This mechanism is similar to how Babel .babelrc files . This approach allows Node.js to use package.json as a source of various metadata about the package and configuration, similar to how it already works in Babel and other tools.


We recommend that all package developers specify a type field, even if commonjs is written commonjs .


Package entry points and the "exports" field in package.json


Now we have two fields for specifying the entry point into the package: main and exports . The main field is supported by all versions of Node.js, but its capabilities are limited: with it you can define only one main entry point in the package. The new exports field also allows you to define the main entry point, as well as additional paths. This gives additional encapsulation for packages where only the explicit exports paths are available for import from outside the package. exports applies to both types of modules, CommonJS and ES, it doesn't matter if they are used through require or import .


This functionality will allow pkg/feature type imports to point to a real path like ./node_modules/pkg/esm/feature.js . Also, Node.js will throw an error if the import refers to pkg/esm/feature.js which is not specified in exports .


An additional, still experimental, feature, conditional exports provides the ability to export different files for different environments. This will allow the package to give CommonJS code to call require("pkg") and the ES module code to import through import "pkg" , although writing such a package is not without other problems . You can enable conditional exports with the —-experimental-conditional-exports flag.


The main rake of the new modules


Required file extensions


When using imports, you must specify the file extension. When importing an index file from a directory, you must also completely specify the path to the file, that is, "./startup/index.js".


This behavior coincides with how imports work in browsers when accessing a regular server without additional configuration.


module.exports , exports , module.exports , __filename , __dirname


These values ​​from CommonJS are not available in the context of ES modules. However, require can be imported into an ES module through module.createRequire() . The equivalents __filename and __dirname can be obtained from import.meta.url .


Creating packages


At the moment, we recommend that package authors use either fully CommonJS or fully ES modules for their Node.js projects. The module working group for Node.js continues to look for ways to improve support for dual packages, with CommonJS for legacy users and ES modules for new ones. Conditional exports are now experimental and we hope to roll out this functionality or its alternative by the end of January 2020, or even earlier.


To learn more about this, see our examples and recommendations for creating dual CommonJS / ES Module packages.


What will happen next


Loaders. Work continues on the API for writing custom loaders, for implementing module transpilation in runtime, redefining import paths (packages or individual files), and also instrumentation of code. The experimental API, accessible under the —-experimental-loader flag, will be subject to significant alterations before we remove it from the flag.


Dual CommonJS / ES module packages. We want to provide a standard way to publish a package that can be used both through require in CommonJS and through import in ES modules. We have more information about this in the documentation . We plan to complete the work and withdraw from the flag by the end of January 2020, if not earlier.


That's all! We hope ECMAScript module support brings Node.js closer to JavaScript standards and brings new compatibility features across the JavaScript ecosystem. The workflow for improving module support is being done publicly here: https://github.com/nodejs/modules .



Source: https://habr.com/ru/post/477168/


All Articles