{"id":414706,"date":"2022-03-11T14:00:20","date_gmt":"2022-03-11T11:00:20","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/how-to-use-ecmascript-modules-with-node-js-cloudsavvy-it\/"},"modified":"2022-03-11T14:00:20","modified_gmt":"2022-03-11T11:00:20","slug":"how-to-use-ecmascript-modules-with-node-js-cloudsavvy-it","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/how-to-use-ecmascript-modules-with-node-js-cloudsavvy-it\/","title":{"rendered":"#How to Use ECMAScript Modules With Node.js \u2013 CloudSavvy IT"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a368d9edee58\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #dd3333;color:#dd3333\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #dd3333;color:#dd3333\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a368d9edee58\" checked aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-use-ecmascript-modules-with-node-js-cloudsavvy-it\/#%E2%80%9CHow_to_Use_ECMAScript_Modules_With_Nodejs_%E2%80%93_CloudSavvy_IT%E2%80%9D\" >&#8220;How to Use ECMAScript Modules With Node.js \u2013 CloudSavvy IT&#8221;<\/a><ul class='ez-toc-list-level-2' ><li class='ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-use-ecmascript-modules-with-node-js-cloudsavvy-it\/#The_Basics\" >The Basics<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-use-ecmascript-modules-with-node-js-cloudsavvy-it\/#Importing_a_CommonJS_Module_From_ESM\" >Importing a CommonJS Module From ESM<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-use-ecmascript-modules-with-node-js-cloudsavvy-it\/#Importing_an_ESM_Module_From_CJS\" >Importing an ESM Module From CJS<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-use-ecmascript-modules-with-node-js-cloudsavvy-it\/#Retrieving_the_Current_Modules_Path_With_ES_Modules\" >Retrieving the Current Module\u2019s Path With ES Modules<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-use-ecmascript-modules-with-node-js-cloudsavvy-it\/#Why_All_The_Incompatibilities\" >Why All The Incompatibilities?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-use-ecmascript-modules-with-node-js-cloudsavvy-it\/#Should_You_Switch_to_ES_Modules\" >Should You Switch to ES Modules?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-use-ecmascript-modules-with-node-js-cloudsavvy-it\/#Summary\" >Summary<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h1><span class=\"ez-toc-section\" id=\"%E2%80%9CHow_to_Use_ECMAScript_Modules_With_Nodejs_%E2%80%93_CloudSavvy_IT%E2%80%9D\"><\/span>&#8220;How to Use ECMAScript Modules With Node.js \u2013 CloudSavvy IT&#8221;<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<div id=\"article-content-area\">\n<img loading=\"lazy\" decoding=\"async\" class=\"type:primaryImage aligncenter size-full wp-image-15530\" data-pagespeed-lazy-srcset=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2022\/02\/886260ee.jpeg?width=398&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1 400w, https:\/\/www.cloudsavvyit.com\/p\/uploads\/2022\/02\/886260ee.jpeg?width=1198&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1 1200w\" sizes=\"auto, 400w, 1200w\" data-pagespeed-lazy-src=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2022\/02\/886260ee.jpeg?width=1198&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"\" width=\"1202\" height=\"677\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>A standardized way to package code as reusable modules was missing from ECMA<a href=\"https:\/\/buradabiliyorum.com\/en\/category\/download-scripts-themes-apps\/\" data-internallinksmanager029f6b8e52c=\"9\" title=\"Download Scripts &amp; Themes &amp; Apps\" target=\"_blank\" rel=\"noopener\">Script<\/a> for most of its history. In the absence of an integrated solution, the <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/nodejs.org\/api\/modules.html#modules-commonjs-modules\">CommonJS (CJS)<\/a> approach became the de facto standard for Node.js development. This uses <code>require<\/code> and <code>module.exports<\/code> to consume and provide pieces of code:<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"co1\">\/\/ Import a module<\/span>\n<span class=\"kw1\">const<\/span> fs <span class=\"sy0\">=<\/span> require<span class=\"br0\">(<\/span><span class=\"st0\">\"fs\"<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"co1\">\/\/ Provide an export<\/span>\nmodule.<span class=\"me1\">exports<\/span> <span class=\"sy0\">=<\/span> <span class=\"br0\">(<\/span><span class=\"br0\">)<\/span> <span class=\"sy0\">=&gt;<\/span> <span class=\"st0\">\"Hello World\"<\/span><span class=\"sy0\">;<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>ES2015, alternatively known as ES6, finally introduced a built-in module system of its own. ECMAScript or <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/nodejs.org\/api\/esm.html\">ES Modules (ESM)<\/a> rely on the <code>import<\/code> and <code>export<\/code> syntax:<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"co1\">\/\/ Import a default export<\/span>\n<span class=\"kw5\">import<\/span> fs from <span class=\"st0\">\"fs\"<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"co1\">\/\/ Provide a default export<\/span>\n<span class=\"kw5\">export<\/span> <span class=\"kw1\">default<\/span> <span class=\"br0\">(<\/span><span class=\"br0\">)<\/span> <span class=\"sy0\">=&gt;<\/span> <span class=\"st0\">\"Hello World\"<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"co1\">\/\/ Import a named export<\/span>\n<span class=\"kw5\">import<\/span> <span class=\"br0\">{<\/span>helloWorld<span class=\"br0\">}<\/span> from <span class=\"st0\">\".\/hello-world.js\"<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"co1\">\/\/ Provide a named export<\/span>\n<span class=\"kw5\">export<\/span> <span class=\"kw1\">const<\/span> helloWorld <span class=\"sy0\">=<\/span> <span class=\"br0\">(<\/span><span class=\"br0\">)<\/span> <span class=\"sy0\">=&gt;<\/span> <span class=\"st0\">\"Hello World\"<\/span><span class=\"sy0\">;<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Node.js has offered on-by-default support for ESM since v16. In earlier versions you needed to use the <code>--experimental-modules<\/code> flag to activate the capability. While ES Modules are now marked as stable and ready for <a href=\"https:\/\/buradabiliyorum.com\/en\/category\/general\/\" data-internallinksmanager029f6b8e52c=\"3\" title=\"General\" target=\"_blank\" rel=\"noopener\">general<\/a> use, the presence of two different module loading mechanisms means it\u2019s challenging to consume both kinds of code in a single project.<\/p>\n<p>In this article we\u2019ll look at how to use ES Modules with Node and what you can do to maximize interoperability with CommonJS packages.<\/p>\n<h2 id=\"the-basics\"><span class=\"ez-toc-section\" id=\"The_Basics\"><\/span>The Basics<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Matters are relatively straightforward if you\u2019re starting a new project and want to rely on ESM. As Node.js now offers full support, you can split your code into separate files and use <code>import<\/code> and <code>export<\/code> statements to access your modules.<\/p>\n<p>Unfortunately you do need to make some conscious choices early on. By default Node doesn\u2019t support <code>import<\/code> and <code>export<\/code> inside files that end with the <code>.js<\/code> extension. You can either suffix your files as <code>.mjs<\/code>, where ESM is always available, or modify your <code>package.json<\/code> file to include <code>\"type\": \"module\"<\/code>.<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"json\">\n<pre class=\"de1\">{&#13;\n    \"name&amp;quot;: \"example-package\",&#13;\n    \"type\": \"module\",&#13;\n    \"dependencies\": {&#13;\n        \"...\"&#13;\n    }&#13;\n}<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Choosing the latter route is usually more convenient for projects that will exclusively use ESM. Node uses the <code>type<\/code> field to determine the default module system for your project. That module system is always used to handle plain <code>.js<\/code> files. When not manually set, CJS is the default module system to maximize compatibility with the existing ecosystem of Node code. Files with either <code>.cjs<\/code> or <code>.mjs<\/code> extensions will always be treated as source in CJS and ESM format respectively.<\/p>\n<h2 id=\"importing-a-commonjs-module-from-esm\"><span class=\"ez-toc-section\" id=\"Importing_a_CommonJS_Module_From_ESM\"><\/span>Importing a CommonJS Module From ESM<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>You can import CJS modules within ESM files using a regular <code>import<\/code> statement:<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"co1\">\/\/ cjs-module.cjs<\/span>\nmodule.<span class=\"me1\">exports<\/span>.<span class=\"me1\">helloWorld<\/span> <span class=\"sy0\">=<\/span> <span class=\"br0\">(<\/span><span class=\"br0\">)<\/span> <span class=\"sy0\">=&gt;<\/span> console.<span class=\"me1\">log<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\"Hello World\"<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"co1\">\/\/ esm-module.mjs<\/span>\n<span class=\"kw5\">import<\/span> component from <span class=\"st0\">\".\/cjs-module.cjs\"<\/span><span class=\"sy0\">;<\/span>\ncomponent.<span class=\"me1\">helloWorld<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><code>component<\/code> will be resolved to the value of the CJS module\u2019s <code>module.exports<\/code>. The example above shows how you can access named exports as object properties on the name of your import. You can also access specific exports using the ESM named import syntax:<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"kw5\">import<\/span> <span class=\"br0\">{<\/span>helloWorld<span class=\"br0\">}<\/span> from <span class=\"st0\">\".\/cjs-module.cjs\"<\/span><span class=\"sy0\">;<\/span>\nhelloWorld<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>This works by means of a static analysis system that scans CJS files to work out the exports they provide. This approach is necessary because CJS doesn\u2019t understand the \u201cnamed export\u201d concept. All CJS modules have one export \u2013 \u201cnamed\u201d exports are really an object with multiple property-value pairs.<\/p>\n<p>Because of the nature of the static analysis process, it\u2019s possible some rare syntax patterns might not be detected correctly. If this happens you\u2019ll have to access the properties you need via the default export object instead.<\/p>\n<h2 id=\"importing-an-esm-module-from-cjs\"><span class=\"ez-toc-section\" id=\"Importing_an_ESM_Module_From_CJS\"><\/span>Importing an ESM Module From CJS<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Things get trickier when you want to use a new ESM module within existing CJS code. You can\u2019t write the <code>import<\/code> statement within CJS files. However the <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Statements\/import#dynamic_imports\">dynamic <code>import()<\/code> syntax<\/a> does work and can be paired with <code>await<\/code> to access modules relatively conveniently:<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"co1\">\/\/ esm-module.mjs<\/span>\n<span class=\"kw1\">const<\/span> helloWorld <span class=\"sy0\">=<\/span> <span class=\"br0\">(<\/span><span class=\"br0\">)<\/span> <span class=\"sy0\">=&gt;<\/span> console.<span class=\"me1\">log<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\"Hello World\"<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n<span class=\"kw5\">export<\/span> <span class=\"br0\">{<\/span>helloWorld<span class=\"br0\">}<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"co1\">\/\/ esm-module-2.mjs<\/span>\n<span class=\"kw5\">export<\/span> <span class=\"kw1\">default<\/span> <span class=\"sy0\">=<\/span> <span class=\"br0\">(<\/span><span class=\"br0\">)<\/span> <span class=\"sy0\">=&gt;<\/span> console.<span class=\"me1\">log<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\"Hello World\"<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"co1\">\/\/ cjs-module.cjs<\/span>\n<span class=\"kw1\">const<\/span> loadHelloWorld <span class=\"sy0\">=<\/span> async <span class=\"br0\">(<\/span><span class=\"br0\">)<\/span> <span class=\"sy0\">=&gt;<\/span> <span class=\"br0\">{<\/span>\n    <span class=\"kw1\">const<\/span> <span class=\"br0\">{<\/span>helloWorld<span class=\"br0\">}<\/span> <span class=\"sy0\">=<\/span> await <span class=\"kw5\">import<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\".\/esm-module.mjs\"<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n    <span class=\"kw1\">return<\/span> helloWorld<span class=\"sy0\">;<\/span>\n<span class=\"br0\">}<\/span><span class=\"sy0\">;<\/span>\n<span class=\"kw1\">const<\/span> helloWorld <span class=\"sy0\">=<\/span> await loadHelloWorld<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\nhelloWorld<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"kw1\">const<\/span> loadHelloWorld2 <span class=\"sy0\">=<\/span> async<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span> <span class=\"sy0\">=&gt;<\/span> <span class=\"br0\">{<\/span>\n    <span class=\"kw1\">const<\/span> helloWorld2 <span class=\"sy0\">=<\/span> await <span class=\"kw5\">import<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\".\/esm-module-2.mjs\"<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n    <span class=\"kw1\">return<\/span> helloWorld2<span class=\"sy0\">;<\/span>\n<span class=\"br0\">}<\/span><span class=\"sy0\">;<\/span>\n<span class=\"kw1\">const<\/span> helloWorld2 <span class=\"sy0\">=<\/span> await loadHelloWorld2<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\nhelloWorld2<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>This structure can be used to asynchronously access both the default and named exports of your ESM modules.<\/p>\n<h2 id=\"accessing-the-current-modules-path-in-es-modules\"><span class=\"ez-toc-section\" id=\"Retrieving_the_Current_Modules_Path_With_ES_Modules\"><\/span>Retrieving the Current Module\u2019s Path With ES Modules<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>ES modules don\u2019t have access to all the familiar Node.js global variables available in CJS contexts. Besides <code>require()<\/code> and <code>module.exports<\/code>, you won\u2019t be able to access the <code>__dirname<\/code> or <code>__filename<\/code> constants either. These are commonly used by CJS modules that need to know the path to their own file.<\/p>\n<p>ESM files can read <code>import.meta.url<\/code> to obtain this information:<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\">console.<span class=\"me1\">log<\/span><span class=\"br0\">(<\/span><span class=\"kw5\">import<\/span>.<span class=\"me1\">meta<\/span>.<span class=\"me1\">url<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n<span class=\"co1\">\/\/ file:\/\/\/home\/demo\/module.mjs<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>The returned URL gives the absolute path to the current file.<\/p>\n<h2 id=\"why-all-the-incompatibilities\"><span class=\"ez-toc-section\" id=\"Why_All_The_Incompatibilities\"><\/span>Why All The Incompatibilities?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The differences between CJS and ESM run much deeper than simple syntactic changes. CJS is a synchronous system; when you <code>require()<\/code> a module, Node loads it straight from the disk and executes its content. ESM is <em>asynchronous<\/em> and splits script imports into several distinct phases. Imports are parsed, asynchronously loaded from their storage location, then executed once all their own imports have been retrieved in the same way.<\/p>\n<p>ESM is engineered as a modern module loading solution with broad applications. This is why ESM modules are suitable for use in web browsers: they\u2019re asynchronous by design, so slow networks aren\u2019t a problem.<\/p>\n<p>The asynchronous nature of ESM is also responsible for the limitations around its use in CJS code. CJS files don\u2019t support top-level <code>await<\/code> so you can\u2019t use <code>import<\/code> on its own:<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"co1\">\/\/ this...<\/span>\n<span class=\"kw5\">import<\/span> component from <span class=\"st0\">\"component.mjs\"<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"co1\">\/\/ ...can be seen as equivalent to this...<\/span>\n<span class=\"kw1\">const<\/span> component <span class=\"sy0\">=<\/span> await <span class=\"kw5\">import<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\"component.mjs\"<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"co1\">\/\/ ...but top-level \"await\" isn't available in CJS<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Hence you have to use the dynamic <code>import()<\/code> structure inside an <code>async<\/code> function.<\/p>\n<h2 id=\"should-you-switch-to-es-modules\"><span class=\"ez-toc-section\" id=\"Should_You_Switch_to_ES_Modules\"><\/span>Should You Switch to ES Modules?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The simple answer is yes. ES Modules are the standardized way to import and export JavaScript code. CJS gave Node a module system when the language lacked its own. Now one\u2019s available, it\u2019s best for the long-term health of the community to adopt the approach described by the ECMAScript standard.<\/p>\n<p>ESM is also the more powerful system. Because it\u2019s asynchronous you get dynamic imports, remote <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/nodejs.org\/api\/esm.html#https-and-http-imports\">imports from URLs<\/a>, and improved performance in some situations. You can reuse your modules with other JavaScript runtimes too, such as code that\u2019s delivered straight to web browsers via <code>&lt;script type=\"module\"&gt;<\/code> <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Guide\/Modules\">HTML tags<\/a>.<\/p>\n<p>Nonetheless migration remains challenging for many existing Node.js projects. CJS isn\u2019t going away any time soon. In the meantime, you can ease the transition by offering both CJS and ESM exports for your own libraries. This is best achieved by writing a thin ESM wrapper around any existing CJS exports:<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"kw5\">import<\/span> demoComponent from <span class=\"st0\">\"..\/cjs-component-demo.js\"<\/span><span class=\"sy0\">;<\/span>\n<span class=\"kw5\">import<\/span> exampleComponent from <span class=\"st0\">\"..\/cjs-component-example.js\"<\/span><span class=\"sy0\">;<\/span>\n<span class=\"kw5\">export<\/span> <span class=\"br0\">{<\/span>demoComponent<span class=\"sy0\">,<\/span> exampleComponent<span class=\"br0\">}<\/span><span class=\"sy0\">;<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Place this file inside a new <code>esm<\/code> subdirectory in your project. Add a <code>package.json<\/code> alongside it containing the <code>{\"type\": \"module\"}<\/code> field.<\/p>\n<p>Next update the <code>package.json<\/code> at your project\u2019s root to include the following content:<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"json\">\n<pre class=\"de1\">{&#13;\n    \"exports\": {&#13;\n        \"require\": \".\/cjs-index.js\",&#13;\n        \"import\": \".\/esm\/esm-index.js\"&#13;\n    }&#13;\n}<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>This tells Node to provide your CJS entrypoint when users of your package <code>require()<\/code> an export. When <code>import<\/code> is used, your ESM wrapper script will be offered instead. Beware that this <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/WICG\/import-maps\">import map<\/a> functionality brings along another side effect too: users will be limited to only the exports provided by your entrypoint file. Loading specific files via in-package paths (<code>import demo from \"example-package\/path\/to\/file.js<\/code>) is disabled when an import map is present.<\/p>\n<h2 id=\"summary\"><span class=\"ez-toc-section\" id=\"Summary\"><\/span>Summary<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The Node.js module landscape can be painful, especially when you need compatibility with both CJS and ESM. Although things have improved with the stabilization of ESM support, you still need to decide upfront which module system should be the \u201cdefault\u201d for your project. Loading code from the \u201cother\u201d system is possible but often uncomfortable, particularly when CJS depends on ESM.<\/p>\n<p>Matters will gradually improve as more major projects switch to adopting ESM as their preferred approach. Yet with so much CJS code in existence, wholesale migration is unrealistic and it\u2019s likely both mechanisms will be used side-by-side \u2013 with all the trade-offs that entails \u2013 for several more years to come.<\/p>\n<p>If you\u2019re starting a new library, make sure you\u2019re distributing ESM-compatible code and try to use it as your default system where possible. This should help the Node ecosystem converge on ESM, realigning it with ES standards.\n<\/p><\/div>\n<blockquote><p><strong><span style=\"color: #ff6600;\">If you liked the article, do not forget to share it with your friends. Follow us on\u00a0<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/news.google.com\/publications\/CAAqBwgKMLG0nwswvr63Aw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Google News<\/a><\/span>\u00a0too, click on the star and choose us from your favorites.<\/span><\/strong><\/p><\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\">For forums sites go to <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/forum.buradabiliyorum.com\/\" target=\"_blank\" rel=\"noopener\">Forum.BuradaBiliyorum.Com<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\"><strong>If you want to read more like this article, you can visit our <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/en.buradabiliyorum.com\/technology\/\" target=\"_blank\" rel=\"noopener\">Technology category.<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<p><span style=\"color: black;\"><a style=\"color: #ff9900;\" href=\"https:\/\/www.cloudsavvyit.com\/15762\/how-to-use-ecmascript-modules-with-node-js\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;How to Use ECMAScript Modules With Node.js \u2013 CloudSavvy IT&#8221; A standardized way to package code as reusable modules was missing from ECMAScript for most of its history. In the absence of an integrated solution, the CommonJS (CJS) approach became the de facto standard for Node.js development. This uses require and module.exports to consume and&#8230;<\/p>\n","protected":false},"author":1,"featured_media":414707,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2022\/02\/886260ee.jpeg","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[],"class_list":["post-414706","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology"],"_links":{"self":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/414706","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/comments?post=414706"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/414706\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/414707"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=414706"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=414706"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=414706"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}