163

モジュールをNPMに公開しようとしていたとき、ES6で書き直し、将来の保証とES6の学習の両方を考えていました。Babel を使用して ES5 にトランスパイルし、テストを実行しました。しかし、どうすればよいかわかりません:

  1. トランスパイルして、結果の /out フォルダーを NPM に公開しますか?
  2. Github リポジトリに結果フォルダーを含めますか?
  3. それとも、2 つのリポジトリを維持する必要がありますか?

要するに、ES6 で記述されたモジュールを NPM に公開するには、どのような手順を踏む必要がありますか?

4

11 に答える 11

90

私がこれまで見てきたパターンは、es6 ファイルをディレクトリに保持し、srcnpm の prepublish でディレクトリにビルドするというものlibです。

src.gitignore に似ていますが、代わりに無視する .npmignore ファイルが必要ですlib

于 2015-04-20T02:32:51.250 に答える
85

ホセの答えが好きです。いくつかのモジュールがすでにそのパターンに従っていることに気付きました。Babel6 で簡単に実装する方法を次に示します。babel-cliグローバルなバベルのバージョンを変更してもビルドが壊れないように、ローカルにインストールします。

.npmignore

/src/

.gitignore

/lib/
/node_modules/

バベルをインストールする

npm install --save-dev babel-core babel-cli babel-preset-es2015

パッケージ.json

{
  "main": "lib/index.js",
  "scripts": {
    "prepublish": "babel src --out-dir lib"
  },
  "babel": {
    "presets": ["es2015"]
  }
}
于 2015-11-28T20:46:09.623 に答える
54

TL;DR - 2019 年 10 月まではしないでください。Node.jsモジュール チームは次のように求めています。

[2019 年 10 月] までは、Node.js での使用を目的とした ES モジュール パッケージを公開しないでください。

2019年5月更新

この質問がされた2015年以来、モジュールのJavaScriptサポートは大幅に成熟しており、うまくいけば2019年10月に正式に安定する予定です。他のすべての回答は現在廃止されているか、過度に複雑です。これが現在の状況とベスト プラクティスです。

ES6 サポート

ES6 (aka 2015) の 99% は、バージョン 6 以降の Node でサポートされています。Node の現在のバージョンは 12 です。すべてのエバーグリーン ブラウザーは、ES6 機能の大部分をサポートしています。ECMAScript は現在バージョン 2019であり、バージョン管理スキームは現在、年を使用することを優先しています。

ブラウザの ES モジュール (別名 ECMAScript モジュール)

すべてのエバーグリーン ブラウザーは、2017 年以降、ES6 モジュールをサポートし ています。動的インポートは、Chrome (+ Opera や Samsung Internet などのフォーク) と Safari でサポートされています。Firefox のサポートは、次のバージョン 67 で予定されています。import

モジュールをロードするために Webpack/rollup/Parcel などは必要ありません。これらは他の目的にも役立つ可能性がありますが、コードをロードするために必須ではありません。ES モジュール コードを指す URL を直接インポートできます。

ノード内の ES モジュール

ES モジュール ( /.mjsを含むファイル) は、Node v8.5.0 以降、フラグを指定して呼び出すことでサポートされています。2019 年 4 月にリリースされたノード v12 では、実験的なモジュールのサポートが書き直されました。最も目に見える変更は、インポート時にデフォルトでファイル拡張子を指定する必要があることです。importexportnode--experimental-modules

// lib.mjs 

export const hello = 'Hello world!';

// index.mjs:

import { hello } from './lib.mjs';
console.log(hello);

全体を通して必須の.mjs拡張子に注意してください。次のように実行します。

node --experimental-modules index.mjs

Node 12 リリースは、Modules チーム開発者に、Node.js で使用することを意図したES モジュール パッケージを、 との両方を介してパッケージを使用するための解決策が見つかるまで公開しないように依頼したときでもrequire('pkg')ありimport 'pkg'ます。ブラウザー向けのネイティブ ES モジュールを引き続き公開できます。

ネイティブ ES モジュールのエコシステム サポート

2019 年 5 月の時点で、ES モジュールのエコシステム サポートは未熟です。たとえば、JestAvaなどのテスト フレームワークは をサポートしていません--experimental-modules。トランスパイラーを使用する必要があり、名前付きインポート ( ) 構文 (ほとんどの npm パッケージではまだ機能しません) を使用するか、デフォルトのインポート構文 ( ) を使用するかを決定する必要がありimport { symbol }ますimport Package from 'package'。 TypeScript で作成されたパッケージ(graphql-tools、node-influx、faast など) の場合。ただし、Jest/Ava/Mocha などでテストできるように、Babel がコードをトランスパイルする場合と両方で機能する回避策があります。--experimental-modules

import * as ApolloServerM from 'apollo-server'; const ApolloServer = ApolloServerM.default || ApolloServerM;

間違いなく醜いですが、この方法では、トランスパイラーなしで、import/を使用して独自の ES モジュール コードを記述し、exportそれを で実行できます。node --experimental-modulesまだ ESM に対応していない依存関係がある場合は、上記のようにインポートすると、Babel を介してテスト フレームワークやその他のツールを使用できるようになります。


質問に対する以前の回答 - Node が require/import の問題を解決するまで、できれば 2019 年 10 月頃にこれを行わないでください。

下位互換性を備えた ES6 モジュールの npm への公開

ES モジュールを npmjs.org に公開して、Babel や他のトランスパイラーを使用せずに直接インポートできるようにするには、単にmainフィールドをpackage.jsonファイル.mjsに指定しますが、拡張子は省略します。

{
  "name": "mjs-example",
  "main": "index"
}

それが唯一の変更点です。拡張子を省略することにより、Node は --experimental-modules で実行された場合に最初に mjs ファイルを探します。それ以外の場合は .js ファイルにフォールバックするため、古い Node バージョンをサポートするための既存の変換プロセス.mjsは以前と同じように機能します — Babel がファイルを指すようにしてください。

これは、NPM に公開したNode < 8.5.0 の下位互換性を備えたネイティブ ES モジュールのソースです。Babel などを使わなくても、すぐに使用できます。

モジュールをインストールします。

npm install local-iso-dt
# or, yarn add local-iso-dt

テスト ファイルtest.mjsを作成します。

import { localISOdt } from 'local-iso-dt/index.mjs';
console.log(localISOdt(), 'Starting job...');

--experimental-modules フラグを指定してノード (v8.5.0+) を実行します。

node --experimental-modules test.mjs

TypeScript

TypeScript で開発する場合は、ES6 コードを生成して ES6 モジュールを使用できます。

tsc index.js --target es6 --modules es2015

*.js次に、出力の名前を に変更する必要があります。これは、ファイルを直接出力できるように、すぐに修正されることが期待さ.mjsれる既知の問題です。tsc.mjs

于 2018-09-26T04:30:36.653 に答える
18

@ホセは正しいです。ES6/ES2015 を NPM に公開することに問題はありませんが、特にパッケージを使用している人が Webpack を使用している場合、パフォーマンス上の理由からnode_modules前処理中にフォルダーを無視するため、問題が発生する可能性があります。babel

したがって、単にgulpgruntまたは単に Node.js を使用して、 libES5 のフォルダーを作成します。

これが私の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));

最後のアドバイス:プロジェクトに .npmignore を追加する必要がありますnpm publishでこのファイルが見つからない場合は、.gitignore代わりに使用されます。通常、.gitignoreファイルには が除外./libされて含まれているため、問題が発生します./src。これは、NPM に公開する場合とは正反対です。ファイルの.npmignore構文は基本的に.gitignore(AFAIK)と同じです。

于 2015-09-19T15:04:37.907 に答える
6

非常に単純な小さなオープン ソース Node モジュールでこれを実際に見たい場合は、nth-dayを見てください(これは私が始めたもので、他の貢献者もいます)。package.json ファイルと、これを行う場所と方法につながる prepublish ステップを調べます。そのモジュールを複製すると、ローカルで実行してテンプレートとして使用できます。

于 2016-06-17T14:19:40.467 に答える
3

NPM パッケージの 2 つの基準は、それがただで使用できることと、require( 'package' )ソフトウェアのようなことを行うことです。

この 2 つの要件を満たせば、やりたいことは何でもできます。モジュールが ES6 で記述されていても、エンド ユーザーがそれを知る必要がない場合は、最大限のサポートを得るために今のところトランスパイルします。

ただし、koaのように、モジュールが ES6 機能を使用するユーザーとの互換性を必要とする場合は、おそらく 2 つのパッケージ ソリューションの方が適切です。

取り除く

  1. 作業に必要なコードだけを公開してくださいrequire( 'your-package' )
  2. ユーザーにとって ES5 と 6 の間が重要でない限り、1 つのパッケージのみを公開します。必要に応じてトランスパイルしてください。
于 2015-04-20T02:33:28.447 に答える