WASM 和 Node.js 不能在模块外使用“import.meta”

Posted

技术标签:

【中文标题】WASM 和 Node.js 不能在模块外使用“import.meta”【英文标题】:WASM and Node.js Cannot use 'import.meta' outside a module 【发布时间】:2021-01-11 12:17:34 【问题描述】:

我使用提供的 make 文件将 FastText C++ 模块构建为 wasm 模块,该文件使用以下标志:

EMCXX = em++
EMCXXFLAGS = --bind --std=c++11 -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['addOnPostRun', 'FS']" -s "DISABLE_EXCEPTION_CATCHING=0" -s "EXCEPTION_DEBUG=1" -s "FORCE_FILESYSTEM=1" -s "MODULARIZE=1" -s "EXPORT_ES6=1" -s 'EXPORT_NAME="FastTextModule"' -Isrc/
EMOBJS = args.bc autotune.bc matrix.bc dictionary.bc loss.bc productquantizer.bc densematrix.bc quantmatrix.bc vector.bc model.bc utils.bc meter.bc fasttext.bc main.bc

已编译的 wasm 模块在 here 可用。当我在提供的示例predict.js 中运行模块时,我得到一个

  var _scriptDir = import.meta.url;
                          ^^^^

SyntaxError: Cannot use 'import.meta' outside a module
    at wrapSafe (internal/modules/cjs/loader.js:1072:16)
    at Module._compile (internal/modules/cjs/loader.js:1122:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
    at Module.load (internal/modules/cjs/loader.js:1002:32)
    at Function.Module._load (internal/modules/cjs/loader.js:901:14)
    at Module.require (internal/modules/cjs/loader.js:1044:19)
    at require (internal/modules/cjs/helpers.js:77:18)

引起

var FastTextModule = (function() 
  var _scriptDir = import.meta.url;
  
  return (
function(FastTextModule) 
  FastTextModule = FastTextModule || ;

...

注意。

为了支持require而不是import,我不得不将编译后的模块从原始版本改编为Node.JS,但这不应该与那个错误有关。

更新。

我已尝试将标志 USE_ES6_IMPORT_META 添加到 makefile -s "USE_ES6_IMPORT_META=0" 广告描述:

em++ --bind --std=c++11 -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['addOnPostRun', 'FS']" -s "DISABLE_EXCEPTION_CATCHING=0" -s "EXCEPTION_DEBUG=1" -s "FORCE_FILESYSTEM=1" -s "MODULARIZE=1" -s "EXPORT_ES6=1" -s 'EXPORT_NAME="FastTextModule"' -s "USE_ES6_IMPORT_META=0" -Isrc/  src/args.cc -o args.bc
em++: warning: assuming object file output, based on output filename alone.  Add an explict `-c`, `-r` or `-shared` to avoid this warning [-Wemcc]

这一次似乎有效,因为我得到一个不同的错误,与模块/代码有关:

TypeError: fastTextModule.addOnPostRun is not a function

违规行是here:

fastTextModule.addOnPostRun(() => 
  if (postRunFunc) 
    postRunFunc();
  
);

在模块化文件中定义函数here

Module["addOnPostRun"] = addOnPostRun;

here 提供了此问题的解决方案。最终的工作模型是here。

【问题讨论】:

【参考方案1】:

Emscripten 提供了一个USE_ES6_IMPORT_META 标志!也许这可以解决你的问题。 看看https://github.com/emscripten-core/emscripten/blob/master/src/settings.js。关于这个标志有一个简单的解释。

更新

使用USE_ES6_IMPORT_META=0

【讨论】:

好的,所以我应该修改 make 文件以支持这个标志。谢谢,我会尝试这种有意义的方式。 我忘了说你需要传递值 0,USE_ES6_IMPORT_META=0 因为默认是 1。 看来这并不能解决问题。事实上,它应该默认设置为1。也许设置中有相关的东西。 啊! (doh) 就是这样,那我再试一次! 所以它似乎工作,但我得到另一个错误,不确定它与同一问题有关。

以上是关于WASM 和 Node.js 不能在模块外使用“import.meta”的主要内容,如果未能解决你的问题,请参考以下文章

打字稿:不能在模块外使用导入语句

Typescript 和 Node.js 错误“SyntaxError:无法在模块外使用导入语句”

Node.js:语法错误:无法在模块外使用 import 语句

Webpack打包

Node.js处理I/O数据之Buffer模块缓冲数据

如何访问和测试 node.js 模块中的内部(非导出)函数?