我正在做一个项目,我有以下结构:
/ # repository root
/core # A local, unpublished npm package used by both projectA and projectB
/projectA # A Next.js app
/projectB # Another Next.js app
字符串
我有一个/core/package.json
和/core/tsconfig.json
,它把tsc && npm pack
'd转换成一个core-1.0.0.tgz
文件。这个 * 看起来 * 都在工作; tsc
和npm pack
命令没有错误地完成,.tgz
文件似乎有我所期望的所有转译的.js
代码。/core/tsconfig.json
个
{
"compilerOptions": {
"lib": ["es2022", "DOM"],
"module": "commonjs",
"target": "es2022",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"outDir": ".compiled",
"declaration": true,
"jsx": "react"
},
"include": ["./index.ts"]
}
型/core/package.json
个
{
"name": "core",
"version": "1.0.0",
"engines": {
"node": "18.15.0"
},
"main": "./.compiled/index.js",
"types": "./.compiled/index.d.ts",
"files":[
"./.compiled/**"
],
"scripts": {
"test": "ts-node ./tests.ts",
"build": "npm install && npm run test && tsc && npm pack"
},
"dependencies": {
...
"@uppy/aws-s3": "3.3.1",
...
}
...
}
型
然后,我将core
包添加到projectA
,方法是将以下内容添加到/projectA/package.json
:
...
"dependencies": {
...
"core": "../core/core-1.0.0.tgz",
...
},
...
型
我在/projectA
中运行npm install
,事情似乎也在工作。我在projectA/node_modules
中查看,我不仅看到我的core
文件夹和编译的JS,而且我还看到core
中的dependencies
已经被取出并安装到projectA/node_modules
中。
然而,当我 * 运行 * projectA
时,我立即收到一个来自core
导入的错误:
Error: require() of ES Module C:\dev\repo\projectA\node_modules\@uppy\aws-s3\lib\index.js from C:\dev\repo\projectA\node_modules\core\.compiled\library\components\file-uploader\FileUploader.js not supported.
Instead change the require of index.js in C:\dev\repo\projectA\node_modules\core\.compiled\library\components\file-uploader\FileUploader.js to a dynamic import() which is available in all CommonJS modules.
型@uppy/aws-s3
是core
的子依赖之一。FileUploader.js
是我创建的FileUploader.ts
React组件的转译版本,它提供了一个围绕@uppy
的小UI Package 器。我看到了错误消息中的文字,但我有点迷失在层之间。我怀疑我需要改变我的/core/tsconfig.json
中的一些东西,但我还没找到具体需要改变的地方/core/.../FileUploader.ts
import UppyAwsS3 from '@uppy/aws-s3'
import Uppy, { SuccessResponse, UppyFile } from '@uppy/core'
import UppyDashboard from '@uppy/dashboard'
import cx from 'classnames'
import React from 'react'
interface Props {
className?: string
fullWidth: boolean
...
}
interface State {}
class FileUploader extends React.Component<Props, State> {
...
render = () => {
return (
<div className={cx('FileUploader', this.props.className, this.props.fullWidth && 'FileUploader--fullWidth')}>
...
</div>
)
}
}
export default FileUploader
型/projectA/tsconfig.json
,供参考
{
"compilerOptions": {
"strict": true,
"esModuleInterop": true,
"jsx": "preserve",
"lib": ["ES2022", "dom"],
},
"exclude": [
"node_modules"
]
}
型
有没有人对我如何设置这个共享的TypeScript包有什么见解?我有什么看起来不对劲吗?
编辑有人建议看看this question。不幸的是,这是不一样的。我写的是TypeScript,而不是原始的vanilla JS。我问的是如何让tsc
编译正确的导入语法,以便Next.js可以利用我的core
CommonJS包中的共享FileReader组件,该组件依赖于ESM包@uppy/aws-s3
。
**更新:**我已经创建了一个显示错误的最小示例项目。它是available here。
5条答案
按热度按时间6mzjoqzu1#
您可能需要使用lerna
Lerna是一个快速、现代的构建系统,用于管理和发布来自同一存储库的多个JavaScript/TypeScript包。
Lerna主要用于管理多项目包。
字符串
将创建包目录和你的地方包在这里.你可以链接这些包与
型
您可以将
shared
模块添加到packageA
节点模块中。当您添加此依赖项时,您将在共享模块的package.json
中使用name
型
此时,您应该能够在
packageA
中使用shared
模块型
如果这不起作用,你可以构建每个包并在导入模块时使用构建目录.假设你构建了
shared
模块,在shared
模块的package.json
中,添加这个型
disho6za2#
您需要在
compilerOptions
中使用"module": "commonjs"
。您可能需要根据您的确切配置稍微修改其他内容。但是,我想鼓励你使用TurboRepo安装程序,这是由Next.js官方支持的。如果有帮助,你可以查看this template repo。
我发布的一些软件包使用了这个设置
请随意探索更多。
x33g5p2x3#
您遇到的错误与Node.js中ES模块(ESM)和CommonJS模块之间的差异有关。您的共享包
/core
似乎使用ESM,而消费项目/projectA
可能被配置为使用CommonJS,这可能导致兼容性问题。要解决此问题,您需要确保共享包和使用项目都使用相同的模块系统,无论是ESM还是CommonJS。由于Next.js支持ESM,因此最好相应地更新配置。
1.更新共享软件包
/core
:在您的
/core/tsconfig.json
中,您应该将module
选项设置为"ESNext"
或"ES6"
,以指示您的软件包使用ESM。请确保将outDir
设置为将保存生成的ESM文件的位置。字符串
1.更新消耗项目
/projectA
:在
/projectA/tsconfig.json
中,通过将module
选项设置为"ESNext"
或"ES6"
,确保模块系统设置为ESM。型
通过进行这些更改,您可以确保共享包和使用项目使用相同的ESM模块系统,这应该可以解决兼容性问题。
hgqdbh6s4#
使用pnpm而不是npm。它将依赖项打包,以便直接在其他项目中使用
https://pnpm.io/的一个。
edqdpe6u5#
我能够让我的示例成功地编译和链接!在大量的死胡同和工具研究之后,我能够让事情运行 * 而无需 * 安装任何额外的包,依赖项或工具。
以下是变化:
compilerOptions.module
和compilerOptions.target
更改为ES6
。compilerOptions.moduleResolution: "Node"
;没有这个TypeScript似乎不喜欢我在运行tsc
时的import
语句。projectA/next.config.js
个transpilePackages: ['core']
. This is a quirk of Next.js;它的编译器不会自动将本地导入的ES6模块转译到tsconfig.json
上。(这是一个ES6模块)在projectA
* 中手动编译似乎正确,没有来自Next.js的抱怨。我不知道为什么有些包能够自动编译,但我的自定义本地core
包需要手动告诉得到转译。就这样,其他的设置都能保持。