简体   繁体   English

错误 [ERR_MODULE_NOT_FOUND]:找不到模块

[英]Error [ERR_MODULE_NOT_FOUND]: Cannot find module

在此处输入图像描述

I'm working on a node project (screenshot).我正在开发一个节点项目(屏幕截图)。 I have a single function (urls) in helpers.js which I'm exporting at the bottom as:我在 helpers.js 中有一个 function (网址),我在底部导出为:

module.exports = {
urls: urls,
};

In my index.js I'm trying to import it with:在我的 index.js 中,我尝试使用以下命令导入它:

import { urls } from './helpers';
const myUrls = urls(1,3);

When I run it I get当我运行它时,我得到

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/home/optionhomes11/nodeprojects/hayes/helpers' imported from /home/optionhomes11/nodeprojects/hayes/index.js Did you mean to import ../helpers.js?

What am I doing wrong?我究竟做错了什么?

You have used你用过

"type":"module"

then make sure you have import file must be .js extension然后确保你有import文件必须是.js扩展名

You should be importing from './helpers' , not '.helpers' .您应该从'./helpers'导入,而不是'.helpers'

Try this as below试试这个如下

search in your "/home/optionhomes11/nodeprojects/hayes/index.js"在您的"/home/optionhomes11/nodeprojects/hayes/index.js"中搜索

And looking for "/home/optionhomes11/nodeprojects/hayes/helpers"并寻找"/home/optionhomes11/nodeprojects/hayes/helpers"

change改变

"/home/optionhomes11/nodeprojects/hayes/helpers"

to

"/home/optionhomes11/nodeprojects/hayes/helpers.js"

You're not doing anything wrong.你没有做错什么。 The current resolution algorithm for EcmaScript Modules of file extensions and the ability to import directories that have an index file requires using an experimental flag.文件扩展名的 EcmaScript 模块的当前解析算法和导入具有索引文件的目录的能力需要使用实验标志。 see esm , the bottom part.esm ,底部。

so to make your work as it is, instead of所以让你的工作保持原样,而不是

$ node index.js

you do:你做:

$ node --experimental-specifier-resolution=node index.js

You can also create a script in your package.json您还可以在 package.json 中创建脚本

like so:像这样:

     "scripts": {
  "start": "NODE_OPTIONS='--experimental-specifier-resolution=node' node src/index.js

I would also recommend you install the Path Intellisense VS code extension.我还建议您安装Path Intellisense VS 代码扩展。 It will really help when handling nested paths.它在处理嵌套路径时真的很有帮助。

When you are using ECMAScript modules you are forced to provide the file extension: https://nodejs.org/api/esm.html#esm_mandatory_file_extensions当您使用 ECMAScript 模块时,您必须提供文件扩展名: https://nodejs.org/api/esm.html#esm_mandatory_file_extensions

So, on top of what other suggested of using "type": "module" on package.json you also need to specify the file extension import {urls} from './helpers.js' .因此,除了在 package.json 上使用"type": "module"的其他建议之外,您还需要指定文件扩展名import {urls} from './helpers.js' You can also use the flag --es-module-specifier-resolution=node to make it resolve js files as modules just like it did before with require您还可以使用标志--es-module-specifier-resolution=node使其将 js 文件解析为模块,就像之前使用require所做的那样

//helpers.js //helpers.js

export default urls;

//index.js //index.js

import urls from './helpers.js';

//package.json (under name) //package.json(名称下)

"type": "module"

This Happens because when using ES Modules we are enforced to specify the file extension in the import statement发生这种情况是因为在使用 ES 模块时,我们被强制在 import 语句中指定文件扩展名

import * from "./demo.js" // Works fine
import * from "./demo" // Will throw error as you see

Note that: The above two options are both valid when using commonJs instead注意:以上两个选项在使用 commonJs 时都有效

//try this if yoг change package.json //如果你改变package.json试试这个

npm i npm i

Answer 1答案 1

This answer does not require using a runtime flag --es-module-specifier-resolution=node at execution time此答案不需要在执行时使用运行时标志--es-module-specifier-resolution=node

However, you have to modify your ts source code, which is a pain if there is are a lot of files.但是,你必须修改你的 ts 源代码,如果有很多文件,这会很痛苦。 And, the modified files will no longer compile in "commonjs" mode, if you want to go back or use dual "commonjs"/"module" modes.而且,修改后的文件将不再在“commonjs”模式下编译,如果你想 go 回来或使用双重“commonjs”/“module”模式。

Modify your tsconfig.json to ensure at least these setting versions:修改您的tsconfig.json以确保至少以下设置版本:

   compilerOptions:{
    "lib": ["es2020"],
    "module": "ES2022",
    "moduleResolution": "node",
    "target": "es2022",
   }

Works with typescript 4.6.3.适用于 typescript 4.6.3。 (Note sure about 4.6.1 or lower). (请注意 4.6.1 或更低版本)。 * *

Modify index.js修改index.js

import {urls} from "#helpers";

Modify package.json修改package.json

  "imports": {
    "#helpers": "./helpers.js"
  }

The leading "#" is mandatory前导“#”是强制性

Answer 2答案 2

In addition to not requiring the node runtime execution flag, this answer also satisifes:除了不需要节点运行时执行标志之外,这个答案还满足:

  1. does not require changing your *.*ts source code (thus leaving it compilable under commonjs if you ever chose to do so(*note))不需要更改您的*.*ts源代码(因此,如果您选择这样做(*note),则可以在 commonjs 下编译它)
  2. In case you are producing a library, it produces output which can be consumed by either "commonjs" or "module" clients.如果您正在生成一个库,它会生成 output 可以由“commonjs”或“模块”客户端使用。

(*note) When using rollup, inline maps are required - so there may sometimes be advantage to using commonjs during development and switching to "module" for release. (*note) 使用 rollup 时,需要内联映射 - 因此在开发期间使用 commonjs 并切换到“模块”进行发布有时可能会有优势。

First modify package.json , create rollup.config.js , and then perform a post tsc action using rollup .首先修改package.json ,创建rollup.config.js ,然后使用rollup执行 post tsc动作。

package.json

...
"exports":{
  "require":"./index.cjs",
  "import":"./index.js"
},
"types": "./index.d.ts",
"type": "module"    // you already had this

rollup.config.js

// import resolve from "@rollup/plugin-node-resolve";
import dts from "rollup-plugin-dts";
import commonjs from "@rollup/plugin-commonjs";
import * as path from "path";
import pkg from "./package.json";

export default [
  {
    input: "index.js",
    external:[], // you may quash 'unresolved' warning by adding here
    output: [
      { file: pkg.exports.require, format: "cjs" },
      { file: pkg.exports.import, format: "es" },
    ],
    plugins: [
      commonjs(),
    ],
  },
  {
    input: "./index.d.ts",
    output: [
      { file: pkg.types, format: "es" }, 
    ],
    plugins: [dts()],
  },
];

Call tsc then rollup :调用tsc然后rollup

npx tsc 
npx rollup -c

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM