NodeJS 无法解析“fs”导入自...正在Next.js中导入自定义包[duplicate]

wydwbb8l  于 2022-11-29  发布在  Node.js
关注(0)|答案(1)|浏览(404)

此问题在此处已有答案

Module not found: Can't resolve 'fs' in Next.js application(16个答案)
2天前关闭。
这篇文章是编辑和提交审查2天前。
我在一个monorepo中工作,使用bolt来管理软件包的安装。我也使用preconstruct来构建与 modulecommon js兼容的导出。使用preconstruct我也使用babel。monorepo文件夹结构看起来有点像这样:

root
├─apps
│ ├─someApp1
│ │ └─index.ts
│ └─someApp2
│   └─index.ts
└─packages
  ├─ui
  │ ├─src
  │ │ ├─components
  │ │ ├─pages
  │ │ │ └─index.tsx
  │ │ └─index.ts
  │ ├─package.json
  │ └─tsconfig.json
  └─utils
    ├─src
    │ └─index.ts
    ├─package.json
    └─tsconfig.json

我在node.js中构建了一个包,其中包含围绕fs模块构建的几个实用函数。
在同一个monorepo的另一个包中,我正在构建React组件,并使用Next构建应用程序。
如果我在组件库的Next文件夹中的somePageindex.tsx文件中使用fs一切正常
如果我导入正在构建的模块,它会给我一个错误:can't resolve fs..
我认为这与Next尝试从包中提取依赖关系有关,而它应该从客户端node_modules导入。
可能需要进行一些配置设置或执行一些操作。
我将试着做一个最小的可重复的例子:
根文件夹中的文件package.json如下所示:
/package.json

// package
{
  "name": "somename",
  "version": "0.0.1",
  "private": true,
  "bolt": {
    "workspaces": [
      "apps/*",
      "packages/*"
    ]
  },
  "scripts": {
    "postinstall": "manypkg check",
    "clean": "bolt ws clean",
    "build": "sh bin/build.working.sh",
    "typecheck": "bolt ws typecheck"
  },
}...

那么我的软件包文件夹中有2个软件包/packages/utils/packages/ui。这些软件包将在/apps工作区文件夹中的前端应用程序(浏览器和CLI)中使用。

utils包是一个常用函数(数组、字符串、文件处理)的库。
**ui包是一个React组件库,为了便于测试,我在该项目中运行了一个Next应用程序。这个应用程序没有与包的库文件一起导出,这可以在tsconfig文件中看到。

它们都继承自位于包的root中的公共tsconfig文件:
/tsconfig.base.json

{
  "compilerOptions": {
    "allowJs": false,
    "allowSyntheticDefaultImports": true,
    "downlevelIteration": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "isolatedModules": true,
    "jsx": "react-jsx",
    "lib": ["DOM", "DOM.Iterable", "ES2019"],
    "module": "CommonJS",
    "moduleResolution": "node",
    "noUncheckedIndexedAccess": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "preserveConstEnums": true,
    "removeComments": false,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "sourceMap": true,
    "strict": true,
    "target": "ES2017"
  },
  "exclude": ["node_modules"]
}

它们各自的package.jsontsconfig文件如下所示:
/packages/utils/package.json

{
  "name": "@somename/utils",
  "version": "0.0.1",
  "private": true,
  "description": "Somename utils",
  "source": "src/index.ts",
  "main": "dist/somename-utils.cjs.js",
  "module": "dist/somename-utils.js",
  "types": "dist/index.d.ts",
  "files": [
    "dist"
  ],
  "preconstruct": {
    "entrypoint": [
      "src/index.ts"
    ]
  },
  "scripts": {
    "clean": "rm -rf dist",
    "build": "yarn preconstruct build && run-p build:*",
    "build:types": "tsc --declaration --emitDeclarationOnly --outDir dist",
    "typecheck": "tsc --noEmit"
  },
} ....

/packages/utils/tsconfig.json

{
  "extends": "../../tsconfig.base.json",
  "include": ["src"],
  "exclude": ["dist", "node_modules"]
}

/packags/ui/package.json

{
  "name": "@somename/ui",
  "version": "0.0.1",
  "private": true,
  "source": "src/index.ts",
  "main": "dist/somename-ui.cjs.js",
  "module": "dist/somename-ui.esm.js",
  "types": "dist/index.d.ts",
  "files": [
    "dist"
  ],
  "scripts": {
    "clean": "rm -rf dist",
    "build": "yarn preconstruct build && run-p build:*",
    "build:types": "tsc --declaration --emitDeclarationOnly --outDir dist",
    "typecheck": "tsc --noEmit",
    "next_dev": "next dev",
    "next_build": "next build",
    "next_prod": "next start"
  },
} ....

/packages/ui/tsconfig.json

{
  "extends": "../../tsconfig.base.json",
  "include": ["src"],
  "exclude": ["dist", "src/pages", "src/somefolder"],
  "compilerOptions": {
    "incremental": true,
    "jsx": "preserve",
    "isolatedModules": true,
    "noEmit": true
  }
}
  • 请注意,在此ts配置中,我排除了src/pages文件夹,因为此包仅用于导出组件,而不是用于测试目的的内置应用程序。*

然后我在utils包中有一个函数,看起来像这样。
/软件包/实用程序/索引.ts

import fs from "fs"
// node/readDirSync.ts
export const readDirSync(...path:string[]){
  return fs.readdirsync(...path)
}

我希望在ui包中使用的代码,如下所示:
/软件包/用户界面/页面/索引.tsx

import { readDirSync } from "@somename/utils"; // my package
...

// Next getStatic
export async function getStaticProps() {
  const path = process.cwd();
  // retrieves a list of .md files
  console.log(readDirSync(path));
  return { props: { result: "should go here" } };
}

...
  • ps.我写了这些片段在这里,我没有实际测试它自己,我希望这是足够的澄清我所面临的问题.如果需要我可以做一个回购,重现的问题.*

因此,我很清楚这与transpiler或Next编译器有关,后者需要被告知从ui包内的node_modules文件夹中获取fs模块。
“你知道什么?

fcy6dtqo

fcy6dtqo1#

如果您在Next.js应用中使用fs,则需要使用import ... from 'package'将其作为ESM模块导入,而不是使用CommonJS语法require()
您可以查看docs了解更多信息。

相关问题