HUI*_*ANG 7 commonjs node.js typescript es6-modules
我按照本教程创建了一个双包。包文件结构如下所示:
my-awesome-lib
package.json
dist
|-- mjs
|-- package.json
|-- index.js
|-- cjs
|-- package.json
|-- index.js
Run Code Online (Sandbox Code Playgroud)
在package.json:
"main": "dist/cjs/index.js",
"module": "dist/mjs/index.js",
"exports": {
".": {
"require": "./dist/cjs/index.js",
"import": "./dist/mjs/index.js"
}
},
Run Code Online (Sandbox Code Playgroud)
文件夹package.json中的mjs:
{
"type": "module"
}
Run Code Online (Sandbox Code Playgroud)
文件夹package.json中的cjs:
{
"type": "commonjs"
}
Run Code Online (Sandbox Code Playgroud)
在我的 Typescript 应用程序中,我安装了自己的包,并尝试导入它。然而,我观察到一件奇怪的事情:
// src/index.ts
import { Class } from 'my-awesome-lib'
import { Class } from '../node_modules/my-awesome-lib/dist/mjs/index.js';
Run Code Online (Sandbox Code Playgroud)
第一个导入语句指向而../node_modules/my-awesome-lib/dist/cjs/index.js不是mjs文件夹。第二个导入语句是我真正想要的。
谁能告诉我出了什么问题吗?是因为我以错误的方式发布了我的库吗?
附注
这是我的 tsconfig.json
{
"compilerOptions": {
"target": "es2020",
"module": "es2020",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"moduleResolution": "node",
"outDir": "dist"
},
"include": ["src"]
}
Run Code Online (Sandbox Code Playgroud)
ps 添加{"type": "module"}到应用程序的 package.json 也不会使此错误消失。
一切都按照设计的方式进行。你遇到的问题是你所期望的问题。您的“tsconfig.json”文件未正确配置 ESM 模块,但您希望它加载 ESM 包。
\n看起来你正在使用它node16-strictest-esm-combined作为参考,如果你是这样,我可以告诉你这个配置大约一年前也让我失望了。
我真的很喜欢 base/tsconfig 存储库,但仅适用于 CJS 配置。我不知道为什么他们使用 来配置名称中包含 ESM 的 tsconfig "moduleResolution": "node",但使用"node"作为值是告诉 TypeScript 发出解析为 CommonJS 模块的 JavaScript。
moduleResolution”它表明下面的配置(这是我 100% 确定可以转换为 ESM 的配置)是要使用的正确配置。
\n这直接来自我的一个项目,即“ESM”包。
\n\n{\n "compilerOptions": {\n "lib": ["ESNext"], // Why not use NodeNext if it compiles down anyways\n "target": "ES2021",\n\n // Runtime/Module\n "module": "Node16", // <- ESM Module Type\n "moduleResolution": "Node16", // <- ESM Resolution\n "esModuleInterop": false, // I added this to show what not to do\n\n // Project Structure\n "rootDir": "src",\n "outDir": "build",\n "declarationDir": "types",\n\n "strict": true,\n "alwaysStrict": false, // <- you can set this to false if your writing ESM\n "skipLibCheck": true,\n "forceConsistentCasingInFileNames": true\n },\n\n "include": ["src/**/*.ts", "src/**/*.mts"], // You might want to change this\n "exclude": ["build", "types", "node_modules"]\n} \n\nRun Code Online (Sandbox Code Playgroud)\n 数字 1: \xc2\xa0 \xc2\xa0 要确保您的项目是 ES 模块:您需要重新编译您的项目。你有两个选择。您可以按照我喜欢的方式进行操作,如下所示:使用构建清理和强制标志。这些额外的标志确保删除所有不必要的内容,并且重新编译所有必要的内容,即使它没有被修改。这很重要,因为您正在改变模块类型。
\n在“ESM”中,您的.js文件应该使用关键字导入import,而不是“CJS” require()方法调用。\n因为tsc试图提高效率,所以它不会重新编译其中包含 require 的文件,因为相应的.ts文档没有被修改过。
$ tsc -b --clean\n $ tsc -b --force\nRun Code Online (Sandbox Code Playgroud)\n数字 2: \xc2\xa0 \xc2\xa0 您可以采取的另一条路线是删除您的构建和类型目录,然后运行$ tsc. 这种方法也有效,但它需要额外的 shell 命令,或者单击鼠标,另一种方法是两个tsc命令。此外,第一个方法可以添加到 package.json 脚本属性中,稍后可以使用 快速再次调用npm run。您还可以为--build、--force、 &--clean标志创建打字稿任务。
\xc2\xa0 \xc2\xa0 \xc2\xa0 \xc2\xa0无论如何...
\n确保重新编译整个项目(包括所有文件)后,您的 javascript 文件使用import&export关键字,而不是requires("...")&module.exports属性 & 方法。只有这样您才会知道您确实拥有 ESM 模块。
如果没有,那么您就知道您的软件包配置有问题,在这种情况下您可以给我发消息,我可以看看是否可以进一步提供帮助。
\n| 归档时间: |
|
| 查看次数: |
6633 次 |
| 最近记录: |