node程序commonjs模式下,如何使用动态import语句?
发布于 作者:苏南大叔 来源:程序如此灵动~以前曾经说过,在node
程序中引入第三方模块的方式,有两种。一种是commonjs
,使用require
语句。另外一种是es module
,使用import
语句。早期的node
代码,以require
语句居多。目前的趋势是:抛弃require
语句,使用import
语句。那么,问题就来了:一些代码库只支持最新的import
的方式引入代码(目前很常见)。
苏南大叔的程序如此灵动博客,记录苏南大叔和计算机代码的故事。本文记录在commonjs
环境中,使用import
语句的方式(本来是应该使用require
的)。本文测试环境:node@16.14.2
,nanoid@4.0.0
。本文的龙套项目是nanoid
,目前最新的版本中,已经不支持早期的require
方式,可以使用npm i nanoid
来进行安装。
require
和import
回顾文章:https://newsn.net/say/node-run-es6.html
- 通常来说使用
node xxx.js
来执行的代码,就是commonjs
标准的。使用require("xxx")
来导入第三方模块。 - 而使用
node xxx.mjs
来执行的代码,或者package.json
里面定义了type:module
,或者各种编译类型(例如webpack
)的,就都是属于es module
类型(或者称之为es
模块)。使用import("xxx")
来导入第三方模块。
报错信息
由于目前越来越多的第三方模块,不再支持commonjs
。所以,在使用传统的require
语句的时候,就会报错。那么,代码提示可以使用dynamic import
。提示信息如下:
require() of ES Module C:\Users\sunan\Desktop\demo\node_modules\nanoid\index.js from C:\Users\sunan\Desktop\demo\test.js not supported.
Instead change the require of index.js in C:\Users\sunan\Desktop\demo\test.js to a dynamic import() which is available in all CommonJS modules.
关键信息:
dynamic import() which is available in all CommonJS modules.
试图在es module
里面使用require()
字样,也是会报错的。
ReferenceError: require is not defined in ES module scope, you can use import instead
解决方案一:await
【推荐】
普通的commonjs
环境下,对比如下:
const { nanoid } = require('nanoid')
vs
const { nanoid } = await import('nanoid');
也就是require('xxx')
字样变成了await import('xxx')
字样。但是,由于使用了await
,大多数情况下,还需要一个async
包裹一下对应的语句。
(async ()=>{
const { nanoid } = await import('nanoid');
console.log(nanoid(5));
})();
在es module
里面,使用await import
的时候,是不需要async
字样的。
解决方案二:eval
也可以使用eval("import('xxx')")
的方式。但是本例的测试中,依然需要使用await
,所以没有啥特别的意义。
(async () => {
const { nanoid } = await eval("import('nanoid')");
console.log(nanoid(5));
})();
或者
(async () => {
const { nanoid } = await eval(import('nanoid'));
console.log(nanoid(5));
})();
结束语
好像在任何的编程语言里面,都存在着明显的两个对立门派。另外说一句,似乎require
导入比import
导入自由的多,import
强制要把所有的导入语句写到顶部,而commonjs
里面并没有这样的要求。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。