节点--experimental-modules-错误:找不到模块

时间:2019-06-23 12:04:21

标签: javascript node.js ecmascript-6 google-chrome-devtools

尝试导入本地文件时出现错误,尽管使用npm软件包时没有问题。

server.js

import express from 'express'
import next from 'next'

import apis from './src/server/api'

api.js

export default {
  ello: 'bye',
  jamie: 'hey'
}

启动应用

node --experimental-modules --inspect server.js

错误

For help, see: https://nodejs.org/en/docs/inspector
(node:20153) ExperimentalWarning: The ESM module loader is experimental.
internal/modules/esm/default_resolve.js:59
  let url = moduleWrapResolve(specifier, parentURL);
            ^

Error: Cannot find module '/var/www/goldendemon.hutber.com/src/server/api' imported from /var/www/goldendemon.hutber.com/server.js
    at Loader.resolve [as _resolve] (internal/modules/esm/default_resolve.js:59:13)
    at Loader.resolve (internal/modules/esm/loader.js:70:33)
    at Loader.getModuleJob (internal/modules/esm/loader.js:143:40)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:43:40)
    at link (internal/modules/esm/module_job.js:42:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

4 个答案:

答案 0 :(得分:7)

在节点12上,您有2个选项:

  1. 在package.json,实验模块上使用type =“ module”并指定具有特殊分辨率的扩展名,如下所示: node --experimental-modules --es-module-specifier-resolution=node src/index

  2. 或不使用说明符重新排序。请记住,您必须在每个位置指定文件的扩展名。

答案 1 :(得分:0)

如果有人遇到这个问题,我正在回答自己的问题。

事实证明,在实验模型中,您需要定义带有扩展名的完整路径。因此,我尝试导入index.js以为它会知道。

要修复它:

import express from 'express'
import next from 'next'
import api from './src/server/api/index.js'

答案 2 :(得分:0)

如果您使用扩展名.mjs命名模块文件,它也应该起作用。另外,here中提到了其他启用ESM的方法。

  

在作为初始输入传递给节点或被ES模块代码中的import语句引用时,Node.js将把以下内容视为ES模块:

     
      
  • 以.mjs结尾的文件。

  •   
  • 以.js结尾的文件或无扩展名的文件,如果最近的父package.json文件包含具有“模块”值的顶级字段“类型”。

  •   
  • 作为参数传递给--eval或--print的字符串,或者通过带有标志--input-type = module的STDIN通过管道传递给节点。

  •   

答案 3 :(得分:0)

或者像我一样,在源代码处理 ES 样式模块导入或其他一些非标准 JavaScript 代码(例如 TypeScript)的那一刻使用转译。作为参考,请参阅我编写的这个快速 bash 脚本,在我的 Node 项目中保存为 .script/run-it.sh

#!/bin/bash

script=$1
out_path==/tmp/$script-out.js
npx esbuild --platform=node --bundle --outfile=$out_path $script
node $out_path 

我将它作为运行脚本添加到我的 package.json 中:

"scripts": {
    "test": "sst test",
    "start": "sst start",
    "build": "sst build",
    "deploy": "sst deploy",
    "remove": "sst remove",
    "run-it": "./.script/run-it.sh"
  },

还有我的目标脚本 (import-test.js),我想作为 JavaScript 代码发出/转译的内容:

import { default as myImport } from './lib/index.js'
console.log(myImport)

现在我运行它:

$ npm run run-it ./import-test.js 

> my-nop@0.1.0 run-it /Users/jmquij0106/git/a-rebalancing-act
> ./.script/run-it.sh "./import-test.js"

[Function: main]

无论何时处理 Node.js 上的 ES 模块,Bottomline 都免除您的痛苦,只需发出符合 CommonJS 的代码,请参阅 this comment/issue