NPM Package path is not exported from package

huangapple go评论184阅读模式
英文:

NPM Package path is not exported from package

问题

我正在尝试创建我的第一个NPM包,以教育为目的,我已经在手册和查看其他项目上卡了好几个小时,试图让事情运转起来。

项目设置

NPM Package path is not exported from package

我的包成功构建,从我所能看到的情况来看,所有文件都分别为ESM和CommonJS目标生成。

该包还可以成功安装,使用yarnnpm都试过,我两者都尝试了,只是为了确保我不是针对其中一个。我的“成功”意味着包安装时一切正常,出现在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

NPM Package path is not exported from package

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"

huangapple
  • 本文由 发表于 2023年8月5日 03:03:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76838576.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定