
NodeJS ESM
缘由H1
When importing CommonJS modules, the
module.exportsobject is provided as the default export. Named exports may be available, provided by static analysis as a convenience for better ecosystem compatibility.
For better compatibility with existing usage in the JS ecosystem, Node.js in addition attempts to determine the CommonJS named exports of every imported CommonJS module to provide them as separate ES module exports using a static analysis process.
NodeJS为把CommonJS模块的module.exports 对象导出到default ,但是为了更好的兼容性,也会导出到ES模块命名空间。这是使用的是静态分析进程来实现的,动态添加到module.exports 的对象是不起作用的。
jsx
import { name } from './cjs.cjs';console.log(name);// Prints: 'exported'import cjs from './cjs.cjs';console.log(cjs);// Prints: { name: 'exported' }import * as m from './cjs.cjs';console.log(m);// Prints: [Module] { default: { name: 'exported' }, name: 'exported' }
问题H2
jsx
// internal/modules/esm/translatorreturn new ModuleWrap(url, undefined, namesWithDefault, function() {debug(`Loading CJSModule ${url}`);let exports;if (asyncESM.esmLoader.cjsCache.has(module)) {exports = asyncESM.esmLoader.cjsCache.get(module);asyncESM.esmLoader.cjsCache.delete(module);} else {try {exports = CJSModule._load(filename, undefined, isMain);} catch (err) {enrichCJSError(err, undefined, filename);throw err;}}for (const exportName of exportNames) {if (!ObjectPrototypeHasOwnProperty(exports, exportName) ||exportName === 'default')continue;// We might trigger a getter -> dont fail.let value;try {value = exports[exportName];} catch {// Continue regardless of error.}this.setExport(exportName, value);}this.setExport('default', exports);});
exportNames为[]
原因H3
jsx
// rtk-query-react.cjs.development.js__export(exports, {ApiProvider: function () { return ApiProvider; },createApi: function () { return createApi; },reactHooksModule: function () { return reactHooksModule; }});
这里使用的动态导出,导致静态分析失败了
解决H2
配置deps.interopDefault为true
vitest使用vite-node(Vite as Node runtime)作为Node Runtime
jsx
async interopedImport(path: string) {const importedModule = await import(path)if (!this.shouldInterop(path, importedModule))return importedModuleconst { mod, defaultExport } = interopModule(importedModule)return new Proxy(mod, {get(mod, prop) {if (prop === 'default')return defaultExportreturn mod[prop] ?? defaultExport?.[prop]},has(mod, prop) {if (prop === 'default')return defaultExport !== undefinedreturn prop in mod || (defaultExport && prop in defaultExport)},getOwnPropertyDescriptor(mod, prop) {const descriptor = Reflect.getOwnPropertyDescriptor(mod, prop)if (descriptor)return descriptorif (prop === 'default' && defaultExport !== undefined) {return {value: defaultExport,enumerable: true,configurable: true,}}},})}
评论
新的评论
上一篇
京都大阪行
上次去日本还是结婚蜜月旅行去的,之后就是老婆怀孕,我宝年纪太小,疫情三年(也是穷),没想到这次来居然都快10年了。虽然本来就一直想来玩,但是总要找个好时机的,本来计划是5月份的。今年春节假期稍微长点,Cathy上学期每月之星的奖励要兑现坐飞机,暑假打算国内找个地方玩的,但是发现…
下一篇
Squash commits
Gitlab、Gitlab在进行Merge Pull Request都可以选择Squash将提交进行合并,但是他们在各自处理时却略有不同。 内部原理上,他们都需要使用 git merge --squash 来实现。这个命令本质上是会在当前HEAD指向的Commit节点之后,将…
