{"id":498,"date":"2022-11-23T11:45:00","date_gmt":"2022-11-23T14:45:00","guid":{"rendered":"https:\/\/suspensao.blog.br\/descrenca\/?p=498"},"modified":"2023-03-20T23:32:02","modified_gmt":"2023-03-21T02:32:02","slug":"importando-modulos-es6-em-commonjs","status":"publish","type":"post","link":"https:\/\/suspensao.blog.br\/descrenca\/importando-modulos-es6-em-commonjs\/","title":{"rendered":"Importando M\u00f3dulos ES6 em CommonJS"},"content":{"rendered":"\n<p>Aqui na Liferay, alguns dias atr\u00e1s, necessit\u00e1vamos utilizar o pacote <a href=\"https:\/\/www.npmjs.com\/package\/p-map\">p-map<\/a>. S\u00f3 tinha um problema: esta aplica\u00e7\u00e3o em espec\u00edfico utilizava m\u00f3dulos no padr\u00e3o <a href=\"https:\/\/nodejs.org\/docs\/latest\/api\/modules.html\">CommonJS<\/a>, e p-map utiliza <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Guide\/Modules\">m\u00f3dulos ES6<\/a>. At\u00e9 algumas das melhores refer\u00eancias que encontrei (por exemplo, <a href=\"https:\/\/reflectoring.io\/nodejs-modules-imports\/\">este post<\/a>) deixavam claro que n\u00e3o seria poss\u00edvel importar m\u00f3dulos ES6 a partir de CommonJS.<\/p>\n\n\n\n<p>A boa not\u00edcia \u00e9 que isto n\u00e3o \u00e9 mais verdade! Usando <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Operators\/import\"><code>import<\/code> din\u00e2mico<\/a>, podemos carregar m\u00f3dulos ES6 a partir de CommonJS. Vejamos um exemplo.<\/p>\n\n\n\n<p>Neste <a href=\"https:\/\/github.com\/brandizzi\/es6commonjs\/\">projeto<\/a>, o arquivo <a href=\"https:\/\/github.com\/brandizzi\/es6commonjs\/blob\/d7c3e3a69ef7828e6dcf714a5e83e77892294490\/importer.js\">importer.js<\/a> tenta utilizar <code>require()<\/code> para importar um m\u00f3dulo ES6:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">const<\/span> pmap = <span class=\"hljs-built_in\">require<\/span>(<span class=\"hljs-string\">'p-map'<\/span>);\n\nexports.importer = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n  <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'Yes, I could import p-map:'<\/span>, pmap);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Naturalmente, isto n\u00e3o funciona:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">$ 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 <span class=\"hljs-string\">\"type\"<\/span>: <span class=\"hljs-string\">\"module\"<\/span> <span class=\"hljs-built_in\">which<\/span> defines all .js files <span class=\"hljs-keyword\">in<\/span> that package scope as ES modules.\nInstead rename index.js to end <span class=\"hljs-keyword\">in<\/span> .cjs, change the requiring code to use import(), or remove <span class=\"hljs-string\">\"type\"<\/span>: <span class=\"hljs-string\">\"module\"<\/span> 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: <span class=\"hljs-string\">'ERR_REQUIRE_ESM'<\/span>\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>A solu\u00e7\u00e3o \u00e9 converter o <code>require()<\/code> em um <code>import<\/code> din\u00e2mico. Mas tem um detalhe: <code>import<\/code> din\u00e2micos retornam uma <code>Promise<\/code>. H\u00e1 v\u00e1rias maneiras de lidar com isso; a mais simples provavelmente \u00e9 tornar nossa fun\u00e7\u00e3o ass\u00edncrona, como <a href=\"https:\/\/github.com\/brandizzi\/es6commonjs\/blob\/be491a9\/importer.js\">nessa vers\u00e3o<\/a>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">exports.importer = <span class=\"hljs-keyword\">async<\/span> () =&gt; {\n  <span class=\"hljs-keyword\">const<\/span> pmap = <span class=\"hljs-keyword\">await<\/span> <span class=\"hljs-keyword\">import<\/span>(<span class=\"hljs-string\">'p-map'<\/span>);\n  <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'Yes, I could import p-map:'<\/span>, pmap);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Agora nossa pequena aplica\u00e7\u00e3o funciona!<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">$ 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><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Outros ajustes podem ser necess\u00e1rios; eu mesmo precisei ajustar as configura\u00e7\u00f5es do <a href=\"https:\/\/stackoverflow.com\/questions\/47815775\/dynamic-imports-for-code-splitting-cause-eslint-parsing-error-import\">eslint<\/a>. O importante \u00e9 que isto \u00e9 poss\u00edvel. E n\u00e3o \u00e9 uma gambiarra: <a href=\"https:\/\/nodejs.org\/api\/esm.html#import-expressions\">a pr\u00f3pria documenta\u00e7\u00e3o de Node recomenda essa abordagem<\/a>.<\/p>\n\n\n\n<p>Ent\u00e3o, n\u00e3o se assuste com informa\u00e7\u00f5es desatualizadas: voc\u00ea <em>n\u00e3o<\/em> vai precisar reescrever sua aplica\u00e7\u00e3o toda como m\u00f3dulos ES 6, ao menos por enquanto.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Aqui na Liferay, alguns dias atr\u00e1s, necessit\u00e1vamos utilizar o pacote p-map. S\u00f3 tinha um problema: esta aplica\u00e7\u00e3o em espec\u00edfico utilizava m\u00f3dulos no padr\u00e3o CommonJS, e p-map utiliza m\u00f3dulos ES6. At\u00e9 algumas das melhores refer\u00eancias que encontrei (por exemplo, este post) deixavam claro que n\u00e3o seria poss\u00edvel importar m\u00f3dulos ES6 a partir de CommonJS. A boa [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"Por um tempo, n\u00e3o era poss\u00edvel utilizar m\u00f3dulos ES6 em CommonJS. N\u00e3o \u00e9 mais o caso! Se voc\u00ea teve esse problema com Node.js, veja como solucionar.","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}},"categories":[156],"tags":[162,159,163,160,161,157,158],"class_list":["post-498","post","type-post","status-publish","format-standard","hentry","category-javascript","tag-commonjs","tag-ecmascript","tag-ecmascript-6","tag-javascript","tag-js","tag-node","tag-node-js"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p23QLV-82","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts\/498","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/comments?post=498"}],"version-history":[{"count":5,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts\/498\/revisions"}],"predecessor-version":[{"id":507,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts\/498\/revisions\/507"}],"wp:attachment":[{"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/media?parent=498"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/categories?post=498"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/tags?post=498"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}