英文:
NPM Package path is not exported from package
问题
我正在尝试创建我的第一个NPM包,以教育为目的,我已经在手册和查看其他项目上卡了好几个小时,试图让事情运转起来。
项目设置
我的包成功构建,从我所能看到的情况来看,所有文件都分别为ESM和CommonJS目标生成。
该包还可以成功安装,使用yarn
和npm
都试过,我两者都尝试了,只是为了确保我不是针对其中一个。我的“成功”意味着包安装时一切正常,出现在node_modules
下。
但是,当我尝试使用项目中的任何对象时,会出现错误,提示模块未导出:
// 加载应用程序对象并附加UX
import {app} from "@myproject/package/src/Application";
document.body.onload = () => {
app.attachUx(document.body);
};
// 编译器错误:
// 未找到模块:错误:包路径./src/Application未从包中导出
目标环境
假设我正确理解“npm包”,IDE不应该导入@myproject/package/src/Application
,而应该导入@myproject/package/Application
,因为编译目标应该“决定”是否使用TypeScript源代码,dist/cjs
用于CommonJS,或dist/esm
用于Emac?
如果我正确理解NPM包的目标环境,那么在使用“emac”目标时应该使用export.import
条目,而在使用“CommonJS”目标时应该使用export.require
?
最后
为什么我的项目没有导出任何内容?NPM不识别任何文件或定义,这意味着我尝试了以下每种组合来导入我的Application
:
import {app} from "@myproject/package/src/Application";
import {app} from "@myproject/package/src/Application.js";
import {app} from "@myproject/package/Application";
import {app} from "@myproject/package/Application.js";
import {app} from "@myproject/package/dist/cjs/Application";
import {app} from "@myproject/package/dist/cjs/Application.js";
import {app} from "@myproject/package/dist/esm/Application";
import {app} from "@myproject/package/dist/esm/Application.js";
解决方案
感谢 @morganney 指出导出条目需要更精确。最终,我得到了下面的导出条目,适用于任何情况,包括
- 从节点、ESM和CJS导入
- 明确/dist导入ESM和CJS
- 明确/src导入TypeScript源代码
- 适用于IDE(如PHPStorm和VSCode)中的类型提示
"exports": {
"./*": {
"import": "./dist/esm/*.js",
"require": "./dist/cjs/*.js",
"node": "./src/*.ts"
},
"./dist/*": {
"import": "./dist/esm/*",
"require": "./dist/cjs/*"
},
"./src/*": "./src/*.ts"
}
英文:
I'm attempting to building my first NPM package for educational purposes, and I've been stuck in the manuals and looking at other projects for hours now trying to make things work.
Project setup
My package builds successfully and from what I can tell all files are generated respectively for ESM and CommonJS targets.
The package also installs successfully using both yarn
and npm
, I tried both flavors just to make sure I'm not targeting one or the other. My "successfully" means the package installs with all green, and appears under node_modules
.
But when I try to use any object from my project I get an error saying the module is not exported:
// Load application object and attach UX
import {app} from "@myproject/package/src/Application";
document.body.onload = () => {
app.attachUx(document.body);
};
// Compiler error:
// Module not found: Error: Package path ./src/Application is not exported from package
Target environment
Assuming I understand "npm packages" correctly, the IDE shouldn't be importing @myproject/package/src/Application
but rather @myproject/package/Application
since the compile target should "decide" if it uses TypeScript sources, dist/cjs
for CommonJS or dist/esm
for Emac?
If I do understand NPM package targeting correctly, the export.import
entry should be used when used by a "emac"-target, and export.require
used by an "CommonJS" target?
Finally
Why is nothing from my project exported? NPM doesn't recognize any file or definition, meaning I have tried each combination of the following lines to import my Application
:
import {app} from "@myproject/package/src/Application";
import {app} from "@myproject/package/src/Application.js";
import {app} from "@myproject/package/Application";
import {app} from "@myproject/package/Application.js";
import {app} from "@myproject/package/dist/cjs/Application";
import {app} from "@myproject/package/dist/cjs/Application.js";
import {app} from "@myproject/package/dist/esm/Application";
import {app} from "@myproject/package/dist/esm/Application.js";
Solution
Thank you @morganney for indicating that the exports entry needs to be more precise. I finally ended up with the exports entry below, which works on any scenario including
- Importing from node, ESM and CJS
- Explicit /dist import for ESM and CJS
- Explicit /src import for TypeScript sources
- Works for type hinting in IDE's such as PHPStorm and VSCode
"exports": {
"./*": {
"import": "./dist/esm/*.js",
"require": "./dist/cjs/*.js",
"node": "./src/*.ts"
},
"./dist/*": {
"import": "./dist/esm/*",
"require": "./dist/cjs/*"
},
"./src/*": "./src/*.ts"
}
答案1
得分: 1
Assuming your build is correct, the thing that stands out is your files
definition in your package.json. That should probably be changed to:
"files": ["dist"]
Since that is where your build output is going, at least based on your exports
definition since you haven't shared your tsconfig.json files.
You should probably update your exports
to be more specific about the conditional subpaths you want to use. It doesn't seem you have one primary index export, and so try something like this:
"exports": {
"import": {
"./Application.js": "./dist/esm/Application.js"
},
"require": {
"./Application.js": "./dist/cjs/Application.js"
}
}
Then you should update your import
statements to look like this:
import { app } from '@mypackage/Application.js'
Finally, you can simplify your dual build by needing less npm run scripts and only one tsconfig.json file if you try @knighted/duel
. Your updated build script would look like this:
"build": "npm run clean && npm run duel --dirs"
英文:
Assuming your build is correct, the thing that stands out is your files
definition in your package.json. That should probably be changed to
"files": ["dist"]
Since that is where your build output is going, at least based on your exports
definition since you haven't shared your tsconfig.json files.
You should probably update your exports
to be more specific about the conditional subpaths you want to use. It doesn't seem you have one primary index export, and so try something like this:
"exports": {
"import": {
"./Application.js": "./dist/esm/Application.js"
},
"require": {
"./Application.js": "./dist/cjs/Application.js"
}
}
Then you should update your import
statements to look like this:
import {app} from '@mypackage/Application.js'
Finally, you can simplify your dual build by needing less npm run scripts and only one tsconfig.json file if you try @knighted/duel
. Your updated build script would look like this:
"build": "npm run clean && npm run duel --dirs"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论