Tra*_*Guy 127 javascript node.js npm ecmascript-6 babeljs
当我考虑在ES6中重写它时,我正准备向NPM发布一个模块,以及面向未来的模型,并学习ES6.我使用Babel转换到ES5,然后运行测试.但我不确定如何继续:
简而言之:我需要采取哪些步骤将用ES6编写的模块发布到NPM,同时仍允许人们浏览/分叉原始代码?
Jos*_*llo 71
到目前为止我看到的模式是将es6文件保存在一个src目录中,并在npm的preublish中创建你的东西到lib目录.
您将需要一个.npmignore文件,类似于.gitignore但忽略src而不是lib.
小智 66
我喜欢何塞的回答.我已经注意到几个模块已经遵循这种模式.以下是使用Babel6轻松实现它的方法.我babel-cli在本地安装,所以如果我改变我的全球babel版本,构建不会破坏.
.npmignore
/src/
Run Code Online (Sandbox Code Playgroud)
的.gitignore
/lib/
/node_modules/
Run Code Online (Sandbox Code Playgroud)
安装Babel
npm install --save-dev babel-core babel-cli babel-preset-es2015
Run Code Online (Sandbox Code Playgroud)
的package.json
{
"main": "lib/index.js",
"scripts": {
"prepublish": "node_modules/babel-cli/bin/babel.js src --out-dir lib"
},
"babel": {
"presets": ["es2015"]
}
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*scu 27
自2015年提出此问题以来,对模块的JavaScript支持已经显着成熟.所有其他答案现在已经过时或过于复杂.这是目前的情况和最佳做法.
自版本6以来,Node支持99%的ES6(又名2015).目前的每晚版本为11.所有常绿浏览器都支持绝大多数ES6功能.ECMAScript现在是2018版本,版本控制方案现在更倾向于使用年份.
// lib.mjs
export const hello = 'Hello world!';
// index.mjs:
import { hello } from './lib.mjs';
console.log(hello);
Run Code Online (Sandbox Code Playgroud)
请注意强制性import扩展.运行方式:
node --experimental-modules index.mjs
Run Code Online (Sandbox Code Playgroud)
.mjs/ import自节点8.5.0以来已经实验性地支持,并且实验标志应该在v10 LTS中消失.
所有常青浏览器都支持 export ES6模块.欲了解更多信息,请访问https://jakearchibald.com/2017/es-modules-in-browsers/.动态的进口都支持通过Chrome和Safari.您不再需要 Webpack /汇总/包裹等.
现在回答这个问题.
要将ES模块发布到npmjs.org以便可以直接导入它,而不使用Babel或其他转换器,只需将该node字段指向您--experimental-modules的.mjs文件,但省略扩展名:
import * as ApolloServerM from 'apollo-server'; const ApolloServer = ApolloServerM.default || ApolloServerM;
Run Code Online (Sandbox Code Playgroud)
这是唯一的变化.通过省略扩展,如果使用--experimental-modules运行,Node将首先查找mjs文件.否则它将回退到.js文件,因此支持旧版Node的现有转换过程将像以前一样工作 - 只需确保将Babel指向require('pkg')文件即可.
这是我发布给NPM的Node <8.5.0的向后兼容性的本机ES模块的源代码.你现在可以使用它,没有Babel或其他任何东西.
安装模块:
{
"name": "mjs-example",
"main": "index"
}
Run Code Online (Sandbox Code Playgroud)
创建一个测试文件test.mjs:
npm install local-iso-dt
# or, yarn add local-iso-dt
Run Code Online (Sandbox Code Playgroud)
使用--experimental-modules标志运行节点(v8.5.0 +):
import { localISOdt } from 'local-iso-dt/index.mjs';
console.log(localISOdt(), 'Starting job...');
Run Code Online (Sandbox Code Playgroud)
如果使用TypeScript进行开发,则可以生成ES6代码并使用ES6模块:
node --experimental-modules test.mjs
Run Code Online (Sandbox Code Playgroud)
然后,您需要将import 'pkg'输出重命名为--experimental-modules,一个已知的问题,希望很快得到修复,以便直接import { symbol }输出import Package from 'package'文件.
And*_*ena 16
@Jose是对的.将ES6/ES2015发布到NPM没有任何问题,但这可能会带来麻烦,特别是如果使用您的软件包的人正在使用Webpack,例如,因为通常人们在出于性能原因node_modules进行预处理时会忽略该文件夹babel.
因此,只要使用gulp,grunt或者干脆Node.js加载建立一个lib文件夹是ES5.
这是我的build-lib.js脚本,我保留./tools/(没有gulp或grunt这里):
var rimraf = require('rimraf-promise');
var colors = require('colors');
var exec = require('child-process-promise').exec;
console.log('building lib'.green);
rimraf('./lib')
.then(function (error) {
let babelCli = 'babel --optional es7.objectRestSpread ./src --out-dir ./lib';
return exec(babelCli).fail(function (error) {
console.log(colors.red(error))
});
}).then(() => console.log('lib built'.green));
Run Code Online (Sandbox Code Playgroud)
这是最后的建议:您需要在项目中添加.npmignore.如果npm publish没有找到此文件,它将使用.gitignore,这将导致您遇到麻烦,因为通常您的.gitignore文件将被排除./lib和包含./src,这与您在发布到NPM时所需的完全相反.该.npmignore文件与.gitignore(AFAIK)的语法基本相同.
遵循 José 和 Marius 的方法,(2019 年更新了 Babel 的最新版本):将最新的 JavaScript 文件保存在 src 目录中,并使用 npm 的prepublish脚本构建并输出到 lib 目录。
.npmignore
/src
Run Code Online (Sandbox Code Playgroud)
.gitignore
/lib
/node_modules
Run Code Online (Sandbox Code Playgroud)
安装 Babel(在我的例子中是 7.5.5 版)
$ npm install @babel/core @babel/cli @babel/preset-env --save-dev
Run Code Online (Sandbox Code Playgroud)
包.json
{
"name": "latest-js-to-npm",
"version": "1.0.0",
"description": "Keep the latest JavaScript files in a src directory and build with npm's prepublish script and output to the lib directory.",
"main": "lib/index.js",
"scripts": {
"prepublish": "babel src -d lib"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/cli": "^7.5.5",
"@babel/core": "^7.5.5",
"@babel/preset-env": "^7.5.5"
},
"babel": {
"presets": [
"@babel/preset-env"
]
}
}
Run Code Online (Sandbox Code Playgroud)
我有src/index.js它使用箭头函数:
"use strict";
let NewOneWithParameters = (a, b) => {
console.log(a + b); // 30
};
NewOneWithParameters(10, 20);
Run Code Online (Sandbox Code Playgroud)
现在您可以发布包:
$ npm publish
...
> latest-js-to-npm@1.0.0 prepublish .
> babel src -d lib
Successfully compiled 1 file with Babel.
...
Run Code Online (Sandbox Code Playgroud)
在包发布到 npm 之前,你会看到lib/index.js已经生成了,它被转译为 es5:
"use strict";
var NewOneWithParameters = function NewOneWithParameters(a, b) {
console.log(a + b); // 30
};
NewOneWithParameters(10, 20);
Run Code Online (Sandbox Code Playgroud)
[Rollup 打包器的更新]
正如@kyw 所问的,您将如何集成 Rollup 捆绑器?
首先,安装rollup并rollup-plugin-babel
npm install -D rollup rollup-plugin-babel
Run Code Online (Sandbox Code Playgroud)
二、rollup.config.js在项目根目录下创建
import babel from "rollup-plugin-babel";
export default {
input: "./src/index.js",
output: {
file: "./lib/index.js",
format: "cjs",
name: "bundle"
},
plugins: [
babel({
exclude: "node_modules/**"
})
]
};
Run Code Online (Sandbox Code Playgroud)
最后,更新prepublish中package.json
{
...
"scripts": {
"prepublish": "rollup -c"
},
...
}
Run Code Online (Sandbox Code Playgroud)
现在可以运行了npm publish,在发布包到 npm 之前,你会看到 lib/index.js 已经生成,并被转译为 es5:
'use strict';
var NewOneWithParameters = function NewOneWithParameters(a, b) {
console.log(a + b); // 30
};
NewOneWithParameters(10, 20);
Run Code Online (Sandbox Code Playgroud)
注意:顺便说一下,@babel/cli如果您使用的是 Rollup 捆绑器,则不再需要。您可以安全地卸载它:
npm uninstall @babel/cli
Run Code Online (Sandbox Code Playgroud)
Node.js 13.2.0+ 支持没有实验标志的 ESM,并且有几个选项可以发布混合(ESM 和 CommonJS)NPM 包(取决于所需的向后兼容性级别):https : //2ality.com/2019 /10/hybrid-npm-packages.html
我建议采用完全向后兼容的方式,以便更轻松地使用您的包。这可能如下所示:
混合包具有以下文件:
mypkg/
package.json
esm/
entry.js
commonjs/
package.json
entry.js
Run Code Online (Sandbox Code Playgroud)
mypkg/package.json
{
"type": "module",
"main": "./commonjs/entry.js",
"exports": {
"./esm": "./esm/entry.js"
},
"module": "./esm/entry.js",
···
}
mypkg/commonjs/package.json
{
"type": "commonjs"
}
Run Code Online (Sandbox Code Playgroud)
从 CommonJS 导入:
const {x} = require('mypkg');
Run Code Online (Sandbox Code Playgroud)
从 ESM 导入:
import {x} from 'mypkg/esm';
Run Code Online (Sandbox Code Playgroud)
我们在 2019 年 5 月对 ESM 支持进行了调查,发现很多库都缺乏支持(因此建议向后兼容):
.mjs文件的本地支持
mocha@7.0.0-esm1.mjs文件问题: