gpt4 book ai didi

node.js - Node : loading ES Modules and native addons in the same project

转载 作者:行者123 更新时间:2023-12-02 18:54:17 25 4
gpt4 key购买 nike

在实际问题之前(见最后),请让我通过一个例子来展示导致该问题的步骤:

创建项目

tests$ mkdir esm && cd esm
tests/esm$ nvm -v
0.37.2
tests/esm$ nvm use v15
Now using node v15.6.0 (npm v7.5.6)
tests/esm$ node -v
v15.6.0
tests/esm$ npm -v
7.5.6
tests/esm$ npm init
package name: (esm) test-esm
entry point: (index.js)

正在安装 nodehun

tests/esm$ npm install nodehun
added 2 packages, and audited 3 packages in 11s
tests/esm$ npm ls
test-esm@1.0.0 tests/esm
└── nodehun@3.0.2
  • nodehun 的依赖项 here

index.js

import { suggest } from './checker.js'
suggest("misspeling");

checker.js

import Nodehun  from 'nodehun'
import fs from 'fs';

const affix = fs.readFileSync('dictionaries/en_NZ.aff')
const dictionary = fs.readFileSync('dictionaries/en_NZ.dic')
const nodehun = new Nodehun(affix, dictionary)

export const suggest = (word) => hun_suggest(word);

async function hun_suggest(word) {
let suggestions = await nodehun.suggest(word);
console.log(suggestions);
}

要获取所需的 Hunspell 词典 文件(aff ix 和 dic tionary):

tests/esm$ mkdir dictionaries && cd dictionaries
tests/esm/dictionaries$ curl https://www.softmaker.net/down/hunspell/softmaker-hunspell-english-nz-101.sox > en_NZ.sox
tests/esm/dictionaries$ unzip en_NZ.sox en_NZ.aff en_NZ.dic

运行项目

根据 nodejs文档 ( Determining Module System ) 以支持 import/export :

Node.js will treat the following as ES modules when passed to node as the initial input, or when referenced by import statements within ES module code:• Files ending in .js when the nearest parent package.json file contains a top-level "type" field with a value of "module".

我们添加 "type": "module" package.json 中的字段项目文件。

package.json

{
...
"main": "index.js",
"type": "module",
...
}

第一次失败的运行

tests/esm$ node index.js
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".node" for tests/esm/node_modules/nodehun/build/Release/Nodehun.node
... omitted ...
at async link (node:internal/modules/esm/module_job:64:9) {
code: 'ERR_UNKNOWN_FILE_EXTENSION'
}

深入了解上述错误的原因:

  • 在关于如何 load addons 的文档中,它指的是使用require

The filename extension of the compiled addon binary is .node (as opposed to .dll or .so). The require() function is written to look for files with the .node file extension and initialize those as dynamically-linked libraries.

  • 将 Node 项目定义为 "type": "module" 后, requireceases to be supported (如与 CommonJS 的互操作性 中所指定):

Using require to load an ES module is not supported because ES modules have asynchronous execution. Instead, use import() to load an ES module from a CommonJS module.

临时解决方案

经过一段时间搜索文档后,我找到了一个临时解决方案:Customizing ESM specifier resolution algorithm :

The current specifier resolution does not support all default behavior of the CommonJS loader. One of the behavior differences is automatic resolution of file extensions and the ability to import directories that have an index file.The --experimental-specifier-resolution=[mode] flag can be used to customize the extension resolution algorithm.To enable the automatic extension resolution and importing from directories that include an index file use the node mode.

tests/esm$ node --experimental-specifier-resolution=node index.js
(node:XXXXX) ExperimentalWarning: The Node.js specifier resolution in ESM is experimental.
(Use `node --trace-warnings ...` to show where the warning was created)
[
'misspelling',
'misspending',
'misspeaking',
'misspell',
'dispelling',
'misapplier',
'respelling'
]

有一些帖子达到了同样的分辨率(ref 1ref 2)。但是,使用实验标志似乎不是在生产环境中运行您的应用程序的正确方法。

失败的选择 esm包裹

从那时起,为了避免使用 --experimental-* 尝试了几次失败的尝试。旗帜。做了一些搜索,我发现一些帖子( ref 1ref 2 )推荐使用 esm包。

  • esm每周获得 130 万次下载。
  • 根据 GitHub 中的自述文件, 它不需要任何更改。

然而,此时,当我尝试这个 node -r esm index.js ,出现新的错误:

tests/esm$ npm install esm
added 1 package, and audited 4 packages in 709ms
tests/esm$ npm ls
test-esm@0.1.0 tests/esm
├── esm@3.2.25
└── nodehun@3.0.2
tests/esm$ node -r esm index.js
tests/esm/index.js:1
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: tests/esm/index.js
at new NodeError (node:internal/errors:329:5)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1125:13) {
code: 'ERR_REQUIRE_ESM'
}

以上可能是由于报告的问题 ( Error [ERR_REQUIRE_ESM]: Must use import to load ES Module / require() of ES modules is not supported )。

  • proposed patch 修复它,虽然我自己不知道如何使用它。
const module = require('module');
module.Module._extensions['.js'] = function(module, filename) {
const content = fs.readFileSync(filename, 'utf8');
module._compile(content, filename);
};

问题

  1. 有没有(标准的)方法来使用import/export (ES 模块)而不会引起 import 的问题插件
    • 避免使用 --experimental-specifier-resolution=node旗帜。
  2. 也许esm可能是上述问题的解决方案。我在使用 esm 方面做错了什么吗?包裹?
    • 如果用法正确,有没有办法使用the proposed patch我自己是一个变通人?

任何有助于解决它的提示都将不胜感激。

注意:示例的最终状态可以从https://github.com/rellampec/test-esm.git中克隆出来

最佳答案

我遇到了类似的问题,并以这种方式解决了它: https://nodejs.org/api/module.html#module_module_createrequire_filename

// The project is "type": "module" in package json
// createRequire is native in node version >= 12
import { createRequire } from 'module';
import path from 'path';
// Absolute path to node modules (or native addons)
const modulesPath = path.resolve(process.cwd(), 'node_modules');
// Create the require method
const localRequire = createRequire(modulesPath);
// require the native add-on
const myNativeAddon = localRequire('my-native-addon');

关于node.js - Node : loading ES Modules and native addons in the same project,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66378682/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com