{"id":119,"date":"2023-03-20T23:38:07","date_gmt":"2023-03-21T02:38:07","guid":{"rendered":"https:\/\/suspensao.blog.br\/disbelief\/?p=119"},"modified":"2023-03-21T15:22:18","modified_gmt":"2023-03-21T18:22:18","slug":"importing-es-6-modules-from-commonjs","status":"publish","type":"post","link":"https:\/\/suspensao.blog.br\/disbelief\/importing-es-6-modules-from-commonjs\/","title":{"rendered":"Importing ES 6 Modules from CommonJS"},"content":{"rendered":"\n<p>Here at Liferay, a few days ago, we needed to use the <a href=\"https:\/\/www.npmjs.com\/package\/p-map\">p-map<\/a> package. There was only one problem: our application still uses the <a rel=\"noreferrer noopener\" href=\"https:\/\/nodejs.org\/docs\/latest\/api\/modules.html\" target=\"_blank\">CommonJS<\/a> format, and p-map releases <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Guide\/Modules\" target=\"_blank\">ES6 modules<\/a> only. Even some of the best references I found (e.g. <a href=\"https:\/\/reflectoring.io\/nodejs-modules-imports\/\">this post<\/a>) made it clear that it would not be possible to import ES6 modules from CommonJS.<\/p>\n\n\n\n<p>The good news is that this is no longer true! Using <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Operators\/import\">dynamic <code>import<\/code><\/a>, we can load ES6 modules from CommonJS. Let&#8217;s look at an example.<\/p>\n\n\n\n<p>In this <a href=\"https:\/\/github.com\/brandizzi\/es6commonjs\/\">project<\/a>, the <a href=\"https:\/\/github.com\/brandizzi\/es6commonjs\/blob\/d7c3e3a69ef7828e6dcf714a5e83e77892294490\/importer.js\">importer.js<\/a> file tries to use <code>require()<\/code> to import an ES6 module:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const pmap = require('p-map');\n\nexports.importer = () =&gt; {\n  console.log('Yes, I could import p-map:', pmap);\n}<\/code><\/pre>\n\n\n\n<p>Of course, it doesn&#8217;t work:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ node index.js \ninternal\/modules\/cjs\/loader.js:1102\n      throw new ERR_REQUIRE_ESM(filename, parentPath, packageJsonPath);\n      ^\n\nError &#91;ERR_REQUIRE_ESM]: Must use import to load ES Module: \/home\/adam\/software\/es6commonjs\/node_modules\/p-map\/index.js\nrequire() of ES modules is not supported.\nrequire() of \/home\/adam\/software\/es6commonjs\/node_modules\/p-map\/index.js from \/home\/adam\/software\/es6commonjs\/importer.js is an ES module file as it is a .js file whose nearest parent package.json contains \"type\": \"module\" which defines all .js files in that package scope as ES modules.\nInstead rename index.js to end in .cjs, change the requiring code to use import(), or remove \"type\": \"module\" from \/home\/adam\/software\/es6commonjs\/node_modules\/p-map\/package.json.\n\n    at new NodeError (internal\/errors.js:322:7)\n    at Object.Module._extensions..js (internal\/modules\/cjs\/loader.js:1102:13)\n    at Module.load (internal\/modules\/cjs\/loader.js:950:32)\n    at Function.Module._load (internal\/modules\/cjs\/loader.js:790:12)\n    at Module.require (internal\/modules\/cjs\/loader.js:974:19)\n    at require (internal\/modules\/cjs\/helpers.js:101:18)\n    at Object.&lt;anonymous&gt; (\/home\/adam\/software\/es6commonjs\/importer.js:1:14)\n    at Module._compile (internal\/modules\/cjs\/loader.js:1085:14)\n    at Object.Module._extensions..js (internal\/modules\/cjs\/loader.js:1114:10)\n    at Module.load (internal\/modules\/cjs\/loader.js:950:32) {\n  code: 'ERR_REQUIRE_ESM'\n}\n<\/code><\/pre>\n\n\n\n<p>The solution is to convert <code>require()<\/code> into a dynamic <code>import<\/code>. But there is one detail: <code>import<\/code> imports return <code>Promise<\/code>s. There are many ways to deal with this; the simplest one is probably to make our function asynchronous, like in <a href=\"https:\/\/github.com\/brandizzi\/es6commonjs\/blob\/be491a9\/importer.js\">this version<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>exports.importer = async () =&gt; {\n  const pmap = await import('p-map');\n  console.log('Yes, I could import p-map:', pmap);\n}<\/code><\/pre>\n\n\n\n<p>Now our little app works!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ node index.js \nok\nYes, I could import p-map: &#91;Module: null prototype] {\n  AbortError: &#91;class AbortError extends Error],\n  default: &#91;AsyncFunction: pMap],\n  pMapSkip: Symbol(skip)\n}<\/code><\/pre>\n\n\n\n<p>Some other adjustments may be necessary. (I had to adjust the <a href=\"https:\/\/stackoverflow.com\/questions\/47815775\/dynamic-imports-for-code-splitting-cause-eslint-parsing-error-import\">eslint<\/a> settings, for example.) The important thing is that this is possible. And it&#8217;s not a kludge: <a href=\"https:\/\/nodejs.org\/api\/esm.html#import-expressions\">Node&#8217;s own documentation recommends this approach<\/a>.<\/p>\n\n\n\n<p>So, don&#8217;t be scared by outdated information: you won&#8217;t need to rewrite your entire application as ES 6 modules, at least for now. For us, this was quite a relief!<\/p>\n\n\n\n<p>(This post is a translation of <a href=\"https:\/\/suspensao.blog.br\/descrenca\/importando-modulos-es6-em-commonjs\/\"><em>Importando M\u00f3dulos ES6 em CommonJS<\/em><\/a>, first published in <a href=\"https:\/\/suspensao.blog.br\/descrenca\"><em>Suspens\u00e3o da Descren\u00e7a<\/em><\/a>.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Here at Liferay, a few days ago, we needed to use the p-map package. There was only one problem: our application still uses the CommonJS format, and p-map releases ES6 modules only. Even some of the best references I found (e.g. this post) made it clear that it would not be possible to import ES6 &hellip; <a href=\"https:\/\/suspensao.blog.br\/disbelief\/importing-es-6-modules-from-commonjs\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Importing ES 6 Modules from CommonJS&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[48,6,49,1],"tags":[53,57,52,54,56,50,51],"class_list":["post-119","post","type-post","status-publish","format-standard","hentry","category-javascript","category-programming","category-typescript","category-uncategorized","tag-asynchronous-programming","tag-commonjs","tag-dynamic-import","tag-ecmascript","tag-ecmascript-6","tag-javascript","tag-typescript"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9Ru6q-1V","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/suspensao.blog.br\/disbelief\/wp-json\/wp\/v2\/posts\/119","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/suspensao.blog.br\/disbelief\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/suspensao.blog.br\/disbelief\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/suspensao.blog.br\/disbelief\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/suspensao.blog.br\/disbelief\/wp-json\/wp\/v2\/comments?post=119"}],"version-history":[{"count":4,"href":"https:\/\/suspensao.blog.br\/disbelief\/wp-json\/wp\/v2\/posts\/119\/revisions"}],"predecessor-version":[{"id":142,"href":"https:\/\/suspensao.blog.br\/disbelief\/wp-json\/wp\/v2\/posts\/119\/revisions\/142"}],"wp:attachment":[{"href":"https:\/\/suspensao.blog.br\/disbelief\/wp-json\/wp\/v2\/media?parent=119"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/suspensao.blog.br\/disbelief\/wp-json\/wp\/v2\/categories?post=119"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/suspensao.blog.br\/disbelief\/wp-json\/wp\/v2\/tags?post=119"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}