如何发布同时具有 commonjs 和 es6 版本的 NPM 模块?
How can I publish an NPM module with both commonjs and es6 versions?
我有一个模块要发布到 npm。我发现了一些已有 4 年以上历史的“解决方案”,使用 babel 5.x 的示例,以及导致示例无法正常工作的其他问题。
理想情况下,我想使用 es6 和 build/transpile 和 babel 编写我的代码,这样它就可以在脚本中使用 require()
或在模块中使用 import
导入。
现在,这是我的(样本)模块,展示了我的尝试。
// index.js
export default function speak () {
console.log("Hello, World!");
}
// .babelrc
{
"comments":false,
"presets": [
["@babel/env", {"modules": "commonjs"}]
],
"plugins": [
"@babel/plugin-transform-modules-commonjs",
"add-module-exports"
]
}
// package.json
{
"name": "foo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "babel index.js -d dist"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/cli": "^7.10.5",
"@babel/core": "^7.10.5",
"@babel/plugin-transform-modules-commonjs": "^7.10.4",
"@babel/preset-env": "^7.10.4",
"babel-plugin-add-module-exports": "^1.0.2"
}
}
最后,一个演示脚本 (demo.js)
// demo.js
const speak = require('./dist/index.js');
speak();
当我执行 npm run build
然后 node demo.js
时,它按预期工作:
Hello, World!
我也希望能够拥有一个模块(将 "type":"module"
添加到 package.json)然后以这种方式使用 demo.js 文件:
import speak from './dist/index.js';
speak();
但是,我得到一个默认导出不可用的错误:
import speak from './dist/index.js';
^^^^^
SyntaxError: The requested module './dist/index.js' does not provide an export named 'default'
我真的不在乎答案是什么,我只想知道最佳做法是什么。我应该只导出为 ES6 吗?我应该只需要 commonjs 吗?有没有一种方法可以使用两个可用目标进行转译?
注:
- node v14.5.0
- npm v6.14.6
- @babel/core v7.10.5
您可以将 webpack
或 rollup
等捆绑器与 babel
结合使用。它们提供编译到多个目标的选项。通常任何库代码都编译为以下目标:
- ESM 或 MJS(Ecmascript 模块)
- UMD(通用模块)
你也可以编译成CJS(CommonJS模块)或IIFE(立即调用的函数表达式)。
UMD 和 ESM 现在几乎是标准的(特别是 UMD,因为它是 IIFE、CJS 和 AMD 的组合)。
您可以浏览 Webpack 或 Rollup 的官方文档。但是,我已经创建了一个工具,您可以使用它来实现您正在寻找的输出。 https://www.npmjs.com/package/rollup-boilerplate
你可以检查它,玩弄它,破解它。我认为这可能是一个很好的起点。您可以查看这篇文章开始:https://medium.com/@contactsachinsingh/setting-up-a-rollup-project-under-two-minutes-fc838be02d0e
我有一个模块要发布到 npm。我发现了一些已有 4 年以上历史的“解决方案”,使用 babel 5.x 的示例,以及导致示例无法正常工作的其他问题。
理想情况下,我想使用 es6 和 build/transpile 和 babel 编写我的代码,这样它就可以在脚本中使用 require()
或在模块中使用 import
导入。
现在,这是我的(样本)模块,展示了我的尝试。
// index.js
export default function speak () {
console.log("Hello, World!");
}
// .babelrc
{
"comments":false,
"presets": [
["@babel/env", {"modules": "commonjs"}]
],
"plugins": [
"@babel/plugin-transform-modules-commonjs",
"add-module-exports"
]
}
// package.json
{
"name": "foo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "babel index.js -d dist"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/cli": "^7.10.5",
"@babel/core": "^7.10.5",
"@babel/plugin-transform-modules-commonjs": "^7.10.4",
"@babel/preset-env": "^7.10.4",
"babel-plugin-add-module-exports": "^1.0.2"
}
}
最后,一个演示脚本 (demo.js)
// demo.js
const speak = require('./dist/index.js');
speak();
当我执行 npm run build
然后 node demo.js
时,它按预期工作:
Hello, World!
我也希望能够拥有一个模块(将 "type":"module"
添加到 package.json)然后以这种方式使用 demo.js 文件:
import speak from './dist/index.js';
speak();
但是,我得到一个默认导出不可用的错误:
import speak from './dist/index.js';
^^^^^
SyntaxError: The requested module './dist/index.js' does not provide an export named 'default'
我真的不在乎答案是什么,我只想知道最佳做法是什么。我应该只导出为 ES6 吗?我应该只需要 commonjs 吗?有没有一种方法可以使用两个可用目标进行转译?
注:
- node v14.5.0
- npm v6.14.6
- @babel/core v7.10.5
您可以将 webpack
或 rollup
等捆绑器与 babel
结合使用。它们提供编译到多个目标的选项。通常任何库代码都编译为以下目标:
- ESM 或 MJS(Ecmascript 模块)
- UMD(通用模块)
你也可以编译成CJS(CommonJS模块)或IIFE(立即调用的函数表达式)。
UMD 和 ESM 现在几乎是标准的(特别是 UMD,因为它是 IIFE、CJS 和 AMD 的组合)。
您可以浏览 Webpack 或 Rollup 的官方文档。但是,我已经创建了一个工具,您可以使用它来实现您正在寻找的输出。 https://www.npmjs.com/package/rollup-boilerplate
你可以检查它,玩弄它,破解它。我认为这可能是一个很好的起点。您可以查看这篇文章开始:https://medium.com/@contactsachinsingh/setting-up-a-rollup-project-under-two-minutes-fc838be02d0e