【问题标题】:How to get babel-node to convert files referenced by Workers to commonjs? (like babel does)如何让 babel-node 将 Workers 引用的文件转换为 commonjs? (就像 babel 一样)
【发布时间】:2020-01-09 10:53:49
【问题描述】:

在 Express.js 应用程序中,我使用 Babel 在启动之前预编译为 commonjs。编译步骤如下所示:

babel ./src --out-dir dist
node ./dist/bin

作为项目的一部分,我有一个名为 my-worker.js 的文件,我在其中使用 import syntax

# my-worker.js

import { parentPort, workerData } from 'worker_threads'
import axios from 'axios'
...

这是other-file.js使用的:

#other-file.js

...
const worker = new Worker(__dirname + '/my-worker.js', { workerData: ... })
...

这很好用。 Babel 将所有文件转换为 commonjs,并且加载工作脚本工作

但是

当我使用@babel/node 时,这不起作用:

babel-node ./src/bin

我收到警告:

(node:4865) 警告:要加载 ES 模块,请在 package.json 中设置 "type": "module" 或使用 .mjs 扩展名。

连同错误:

不能在模块外使用 import 语句

我不想使用"type": "module",从那时起我必须明确命名文件扩展名,而且我不确定是否支持import X, { y } from ... 语法(我喜欢)。

如果我将工作文件更改为 my-worker.mjs,并相应地更改 new Worker 语句,那么这适用于 @babel/node,但不适用于我的生产版本,因为文件名已更改回 .js

我怎样才能让@babel/node 加载和缓存(我想这是它需要做的?)由 Worker 加载的文件?为什么这适用于 @babel 而不是 @babel/node


我的.babelrc 文件如下所示:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "corejs": 3,
        "targets": {
          "node": "13"
        },
        "modules": "commonjs"
      }
    ]
  ]
}

【问题讨论】:

  • 我目前使用的解决方案是在应用启动时通过fs.readFileSync 获取我想要运行的文件的名称。然后在开发中我可以使用.mjs,这对于Node 13 来说很好,在生产中,commonjs 输出是.jsfs.readFileSync 找到.js 文件。
  • 对于更面向 babel 的方法:github.com/babel/babel/issues/10972

标签: javascript node.js babeljs babel-node


【解决方案1】:

@babel/register API 可以帮助动态转译脚本源,正如https://github.com/babel/babel/issues/10972#issuecomment-572608142 中所指出的那样

您可以将此方法与 eval 模式一起使用来制作单文件脚本。如果您使用 babel-node 运行命令行实用程序脚本,这可能会很有用。

import { isMainThread, Worker, workerData } from "worker_threads";

function createTranspiledWorker(filename, options) {
  const transpile = `
    require('@babel/register');
    require(${JSON.stringify(filename)});
  `;
  return new Worker(transpile, { ...options, eval: true });
}

async function main() {
  const w = createTranspiledWorker(__filename, { workerData: { hello: "world" } });
  const exit = new Promise(resolve => w.on("exit", resolve));
  await exit;
}

function worker() {
  console.log("worker", workerData);
}

if (isMainThread) {
  main();
} else {
  worker();
}

【讨论】:

    猜你喜欢
    • 2022-07-06
    • 2017-01-13
    • 2016-08-23
    • 1970-01-01
    • 2021-02-27
    • 2018-11-03
    • 2021-12-18
    • 2017-06-09
    • 2017-08-24
    相关资源
    最近更新 更多