[英]Package.json with multiple entrypoints
I have a library which was used as follows我有一个使用如下的库
import { Foo } from '@me/core';
const foo = new Foo();
The package.json
of that library looks like该库的
package.json
看起来像
"name": "@me/core",
"version": "1.0.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"license": "MIT",
...
With dist/index.js
its entrypoint.使用
dist/index.js
作为入口点。 Now, however, I would provide an import for NodeJs projects only and one for web projects.但是,现在我将只为 NodeJs 项目提供一个导入,为 web 项目提供一个导入。 Ideally I would have something like this for NodeJs
理想情况下,我会为 NodeJs 准备这样的东西
import { Foo } from '@me/core/nodejs';
and if you're working on a web-project you could do如果你正在做一个网络项目,你可以做
import { Foo } from '@me/core/web';
My understanding is that both @me/core/nodejs
and @me/core/web
will be different NPM packages this way, which is not what I want.我的理解是,
@me/core/nodejs
和@me/core/web
这样都会有不同的 NPM 包,这不是我想要的。 I want it to be in 1 npm package.我希望它在 1 npm package 中。
I tried to changed the library's index.ts file, from我试图改变图书馆的 index.ts 文件,从
export * from './foo';
into进入
import * as nodejs from './nodejs';
import * as web from './web';
export { web, nodejs };
This actually works, but I have to use it now (in a NODEJS project) as follows这确实有效,但我现在必须使用它(在 NODEJS 项目中),如下所示
import { nodejs } from '@me/core';
const foo = new nodejs.Foo();
Is there maybe a way to import this such that I don't need the nodejs
everytime?有没有办法导入这个,这样我就不需要每次都需要
nodejs
了?
As you can see I'm not so sure what I should do here so any help would be appreciated!如您所见,我不太确定我应该在这里做什么,所以我们将不胜感激!
UPDATE: Based on the suggestions by @Klaycon I see the following error:更新:根据@Klaycon 的建议,我看到以下错误:
As you're using ECMAScript modules, please refer to node.js docs on package entry points :当您使用 ECMAScript 模块时,请参阅package 入口点上的 node.js 文档:
In a package's package.json file, two fields can define entry points for a package: "main" and "exports".
在包的 package.json 文件中,两个字段可以定义 package 的入口点:“main”和“exports”。 The "main" field is supported in all versions of Node.js, but its capabilities are limited: it only defines the main entry point of the package.
Node.js 的所有版本都支持“main”字段,但它的功能是有限的:它只定义了 package 的主入口点。
The "exports" field provides an alternative to "main" where the package main entry point can be defined while also encapsulating the package, preventing any other entry points besides those defined in "exports".“exports”字段提供了“main”的替代方案,其中可以定义 package 主入口点,同时还封装 package,防止除“exports”中定义的入口点之外的任何其他入口点。 This encapsulation allows module authors to define a public interface for their package.
这种封装允许模块作者为其 package 定义一个公共接口。
So, in your package.json, you could define exports
like this:因此,在您的 package.json 中,您可以像这样定义
exports
:
"main": "dist/index.js",
"exports": {
".": "dist/index.js",
"./nodejs": "dist/nodejs",
"./web": "dist/web",
}
The accepted answer, using the exports
field, is one way to do it, but not the only way -- and as you've found, isn't currently supported by Typescript.使用
exports
字段的公认答案是一种方法,但不是唯一方法 - 正如您所发现的,Typescript 目前不支持。
Look at the @angular/material
package, which works similarly to what you have in mind.查看
@angular/material
package,它的工作原理与您的想法相似。 In @angular/material/package.json
, you've got a module
field that points to an empty JS file, and a typings
field that points to an empty .d.ts
file.在
@angular/material/package.json
中,您有一个指向空 JS 文件的module
字段和一个指向空typings
文件的.d.ts
字段。 But you've also got @angular/material/button/package.json
which points (indirectly) to the implementation of MatButton
(and a bunch of other stuff).但是你也有
@angular/material/button/package.json
它(间接地)指向MatButton
的实现(以及一堆其他的东西)。 When you import {MatButton} from "@angular/material/button"
, it resolves this package file, looks at its module
and typings
fields, and uses those to resolve the runtime code and exported types, respectively.当您
import {MatButton} from "@angular/material/button"
,它会解析此typings
文件,查看其module
和类型字段,并使用它们分别解析运行时代码和导出类型。
You could do the same thing: @me/core/package.json
would have module
and typings
fields that point to empty files;你可以做同样的事情:
@me/core/package.json
会有指向空文件的module
和typings
字段; @me/core/node/package.json
would point to code for your Node-specific Foo
class, and @me/core/web/package.json
would point to code for your browser version of Foo
. @me/core/node/package.json
将指向您的特定于节点的Foo
Foo
的代码, @me/core/web/package.json
将指向您的浏览器版本的代码。
Try to add the following code to the tsconfig.json
:尝试将以下代码添加到
tsconfig.json
:
{
"compilerOptions": {
"moduleResolution": "NodeNext"
}
}
And then you can import the module like this:然后你可以像这样导入模块:
import { Foo } from '@me/core/nodejs';
If you Don't Want to Touch the tsconfig.json
you can use the following for the import:如果您不想触摸
tsconfig.json
,您可以使用以下内容进行导入:
import { Foo } from '@me/core/dist/nodejs';
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.