如何在另一模块导入JS中条件导出的reticulateSplines函数?
解决ES模块导入CommonJS导出函数的报错问题
问题根源
你碰到的报错本质是模块系统不兼容:
workers.js用CommonJS的module.exports导出函数,这在ES模块体系里属于默认导出,不是命名导出。runner.js用ES模块的命名导入语法(import { reticulateSplines } from "./workers")去拿,自然找不到对应的导出项。
另外要确认你的项目已经通过package.json里的"type": "module"启用了ES模块,不然runner.js里的import语法本身就会报错。
方案一:修改导入方式(最小改动)
既然workers.js的导出是默认导出,直接在runner.js里用ES模块的默认导入语法:
// runner.js // 改成默认导入,去掉大括号 import reticulateSplines from "./workers"; // 后面的代码保持不变 function reticulate() { for (let i = 1; i < 100; ++i); } const splines = [ { reticulate: reticulate, reticulated: false, }, { reticulate: reticulate, reticulated: false, }, ]; reticulateSplines(splines).then(() => { console.log("Done reticulating"); });
方案二:把workers.js改成ES模块(统一模块风格)
如果想让整个项目都用ES模块,调整workers.js的语法,同时处理ES模块中没有__filename的问题:
// workers.js import { Worker, isMainThread, parentPort } from "worker_threads"; import { fileURLToPath } from "url"; import { dirname } from "path"; // ES模块里手动获取当前文件路径 const __filename = fileURLToPath(import.meta.url); if (isMainThread) { // ES模块默认导出函数 export default function reticulateSplines(splines) { return new Promise((resolve, reject) => { let reticulator = new Worker(__filename); reticulator.postMessage(splines); reticulator.on("message", resolve); reticulator.on("error", reject); }); }; } else { parentPort.once("message", (splines) => { for (let spline of splines) { spline.reticulate ? spline.reticulate() : (spline.reticulated = true); } parentPort.postMessage(splines); }); }
改完之后,runner.js的默认导入可以正常使用;如果偏好命名导出,也可以把export default改成export function reticulateSplines(...),然后runner.js用import { reticulateSplines } from "./workers"即可。
验证要点
- 确保项目根目录的
package.json里有"type": "module"字段,否则Node.js会把.js文件当作CommonJS处理,ES模块语法会报错。 - 直接用
node runner.js运行即可(Node.js 14及以上版本支持ES模块)。
内容的提问来源于stack exchange,提问作者Sebi
相关产品推荐
相关产品推荐

