浏览器和Node导入语句不兼容

huangapple go评论86阅读模式
英文:

Browser and Node import statement incompatibility

问题

在Node中,可以以多种方式对require()语句进行条件化处理,例如将它们放在if或其他条件语句中,使用?:来指定需要引用的目标,或者将它们放在在条件情况下调用的函数中。相比之下,import语句没有这种灵活性。因此,如果我有一个模块,当在Node上运行时将引用一个文件,但在浏览器中以不同的方式运行时,我不能执行类似于const fs = inBrowser ? null : require("fs");的等效操作。

那么,当需要这种条件性时,如何在Node和浏览器中使用模块呢?

另外,在Node中,require()import语句通常使用相对路径。在浏览器中,似乎是使用绝对URL的规范。那么,我是否可以在浏览器中使用类似于import { x } from "./specialPlace/mod2.mjs";这样的方式来导入位于URL /assets/mod1.mjs的模块,或者每个import都必须是绝对路径?如果我们在浏览器中这样做,那么在Node中将无法正常工作,因为除了类似于/usr/person/...之类的绝对路径之外,绝对路径在浏览器中无法使用。

英文:

In Node, one can conditionalize require() statements in several ways -- put them inside if or other conditional statements, use ?: for the target to be required, put them in a function that is conditionally called. By contrast, import statements have no such flexibility. So, if I have a module that will that will refer to a file when running on Node but will work in a different way when running in the browser, I cannot do anything equivalent to const fs = inBrowser ? null : require("fs");

So, how does one use a module in Node and also in the browser when such conditionality is needed?

Also, require() and import statements within Node commonly use relative paths. In the browser, it seems the norm (the requirement?) is to use absolute url's. So, can I have a module, say at the url /assets/mod1.mjs, import another module with something like import { x } from "./specialPlace/mod2.mjs"; and have that work in the browser, or must every import be an absolute path? If we do that for the browser, it won't work in Node since there is not root from an absolute path other than something like /usr/person/... and that won't work in the browser.

答案1

得分: 1

要像require一样按需使用import,可以将其作为一个函数调用。这被称为动态导入。返回导入模块的 Promise(模块实例)。通常与之一起使用await。在模块的顶层也支持不带asyncawait

现在我推荐在 Node.js 中也使用 ESM,并从require迁移。许多 NPM 模块的最新版本已放弃对 CommonJS 的支持,转而支持 ESM。

<script type="module" src="main.js"></script>

main.js

const {default: myModule} = doINeedModule ? await import('myModule') : {default: null};

此外,管理、捆绑和解析裸模块和文件系统导入是由打包器完成的。如果目标是浏览器,不使用打包器就像还停留在石器时代一样。

我推荐使用 Vite。通过插件,甚至可以不用操心导入任何东西,这将自动完成。您可以编写自定义的裸模块和文件系统解析器,可能性是无限的。甚至可以按文件名模式导入模块:https://vitejs.dev/guide/features.html#glob-import

英文:

To use import on demand like require you can call it as a function. It's called dynamic import. Returns a promise of the imported module (Module instance). Usually you use await with it. await without async is supported on the top-level of modules.

Nowadays I recommend using ESM in node.js too and migrate from require. Recent version of many NPM modules dropped support for CommonJS in favor of ESM.

&lt;script type=&quot;module&quot; src=&quot;main.js&quot;&gt;&lt;/script&gt;

main.js

const {default: myModule} = doINeedModule ? await import(&#39;myModule&#39;) : {default: null};

Also managing, bundling and resolving bare and file-system imports is done by bundlers. Working without a bundler is like stone-aged currently if the target is the browser.

I recommend Vite. With plugins you could not bother even importing anything, that will be done for you automatically. You can write custom bare and file-system resolvers, possibilities are endless. You can even import modules by file name patterns: https://vitejs.dev/guide/features.html#glob-import

huangapple
  • 本文由 发表于 2023年6月26日 00:11:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76551335.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定