此问题在此处已有答案:
Module not found: Can't resolve 'fs' in Next.js application(16个答案)
2天前关闭。
这篇文章是编辑和提交审查2天前。
我在一个monorepo中工作,使用bolt来管理软件包的安装。我也使用preconstruct
来构建与 module 和 common 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文件夹中的somePage
的index.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.json
和tsconfig
文件如下所示:
/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
模块。
“你知道什么?
1条答案
按热度按时间fcy6dtqo1#
如果您在Next.js应用中使用
fs
,则需要使用import ... from 'package'
将其作为ESM模块导入,而不是使用CommonJS语法require()
。您可以查看docs了解更多信息。