ES6でモジュールを書き直そうと考えたときに、モジュールをNPMに公開しようとしていました。それは、将来を保証し、ES6を学習するためです。 Babelを使用してES5にトランスパイルし、テストを実行しました。しかし、私はどのように進むべきかわかりません:
要するに、ES6で記述されたモジュールをNPMに公開するために、元のコードを閲覧/フォークできるようにするために、どのような手順を踏む必要がありますか?
これまでに見てきたパターンは、es6ファイルをsrc
ディレクトリに保存し、npmのlib
ディレクトリへの事前公開で作成します。
.gitignoreに似ていますが、src
の代わりにlib
を無視する.npmignoreファイルが必要になります。
ホセの答えが好きです。いくつかのモジュールが既にそのパターンに従っていることに気付きました。 Babel6で簡単に実装する方法は次のとおりです。 babel-cli
をローカルにインストールして、グローバルなbabelバージョンを変更してもビルドが壊れないようにします。
。npmignore
/src/
。gitignore
/lib/
/node_modules/
バベルのインストール
npm install --save-dev babel-core babel-cli babel-preset-es2015
package.json
{
"main": "lib/index.js",
"scripts": {
"prepublish": "node_modules/babel-cli/bin/babel.js src --out-dir lib"
},
"babel": {
"presets": ["es2015"]
}
}
TL; DR-しないでください、2019年10月まで。Node.js モジュールチーム には 質問 :
[2019年10月]まで、Node.jsでの使用を目的としたESモジュールパッケージを公開しないでください。
この質問が行われた2015年以降、モジュールのJavaScriptサポートは大幅に成熟しており、2019年10月に公式に安定することが期待されています。他のすべての回答は現在廃止されているか、過度に複雑です。これが現在の状況とベストプラクティスです。
ES6の99%(別名2015)はNode バージョン6以降 でサポートされています。 Nodeの現在のバージョンは12です。すべての常緑ブラウザは、ES6機能の大部分をサポートしています。 ECMAScriptは現在 バージョン2019 であり、バージョン管理スキームは現在、年を使用することを支持しています。
すべての常緑ブラウザ は サポートimport
- 2017年からES6モジュールを実行しています。 ダイナミックインポート は サポート Chrome(OperaやSamsung Internetなどの+フォーク)およびSafari。 Firefoxのサポートは、次のバージョンである67で予定されています。
モジュールをロードするためにneed Webpack/rollup/Parcelなどがなくなりました。これらは他の目的にも使用できますが、コードをロードするために必要なわけではありません。 ESモジュールコードを指すURLを直接インポートできます。
ESモジュール(import
/export
を含む.mjs
ファイル)は、Node v8.5.0以降、--experimental-modules
フラグでnode
を呼び出すことでサポートされています。 2019年4月にリリースされたNode v12は、実験モジュールのサポートを書き直しました。最も目に見える変更は、インポート時にデフォルトでファイル拡張子を指定する必要があることです。
// 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リリースは、モジュールチーム 要求 開発者が公開しない場合ESモジュールパッケージ node.jsで使用するためのものrequire('pkg')
とimport 'pkg'
の両方を介してパッケージを使用するためのソリューションが見つかるまで。ブラウザ用のネイティブESモジュールを引き続き公開できます。
2019年5月現在、ESモジュールのエコシステムサポートは未完成です。たとえば、 Jest や Ava などのテストフレームワークは--experimental-modules
をサポートしません。トランスパイラーを使用する必要があり、名前付きインポート(import { symbol }
)構文(ほとんどのnpmパッケージではまだ動作しない)とデフォルトのインポート構文(import Package from 'package'
)のどちらを使用するかを決定する必要があります。これは動作しますが、 Babelが解析するときではありません for TypeScriptで作成されたパッケージ (graphql-tools、node-influx、faastなど)ただし、両方で動作する回避策があります--experimental-modules
を使用し、BabelがコードをトランスコンパイルしてJest/Ava/Mochaなどでテストできるようにする場合:
import * as ApolloServerM from 'apollo-server'; const ApolloServer = ApolloServerM.default || ApolloServerM;
おそらくugいですが、この方法では、import
/export
で独自のESモジュールコードを記述し、トランスパイラーなしでnode --experimental-modules
で実行できます。まだESMに対応していない依存関係がある場合は、上記のようにインポートすると、Babelを介してテストフレームワークやその他のツールを使用できるようになります。
質問に対する以前の回答-Nodeがrequire/importの問題を解決するまでこれを行わないでください。できれば2019年10月頃です。
ESモジュールをnpmjs.orgに公開して、Babelや他のトランスパイラーなしで直接インポートできるようにするには、package.json
のmain
フィールドを.mjs
ファイルにポイントしますが、拡張機能:
{
"name": "mjs-example",
"main": "index"
}
それが唯一の変更です。拡張機能を省略すると、Nodeは--experimental-modulesを使用して実行された場合に最初にmjsファイルを探します。そうしないと、.jsファイルにフォールバックするため、古いNodeバージョンをサポートするための既存の transpilation process は以前と同じように機能します— Babelが.mjs
を指すようにしてくださいファイル。
Node <8.5.0との後方互換性を備えたネイティブESモジュールのソース NPMに公開したものです。 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で開発する場合、ES6コードを生成し、ES6モジュールを使用できます。
tsc index.js --target es6 --modules es2015
次に、*.js
出力を.mjs
に名前変更する必要があります。これは、既知の issue すぐに修正されるので、tsc
が.mjs
ファイルを直接出力できます。 。
@Joseは正しい。 ES6/ES2015をNPMに公開することには何の問題もありませんが、特にパッケージを使用している人がWebpackを使用している場合、特にパフォーマンス上の理由でbabel
での前処理中にnode_modules
フォルダーを無視するため、問題が発生する可能性があります.
したがって、gulp
、grunt
、または単にNode.jsを使用して、ES5であるlib
フォルダーを作成します。
これが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)と同じです。
これを非常に単純な小さなオープンソースNodeモジュールで実際に見たい場合は、 nth-day (私が始めた-他の貢献者も)を見てください。 package.jsonファイルと、これを行う場所と方法につながる事前公開ステップを確認します。そのモジュールのクローンを作成すると、ローカルで実行し、それをテンプレートとして使用できます。
package.json
のメインキーは、パッケージが公開された後のエントリポイントを決定します。したがって、必要な場所にBabelの出力を配置し、main
キーに正しいパスを記述するだけで済みます。
"main": "./lib/index.js",
Npmパッケージの公開方法に関するよく書かれた記事を次に示します。
https://codeburst.io/publish-your-own-npm-package-ff918698d45
参照用に使用できるサンプルリポジトリを次に示します。
NPMパッケージの2つの基準は、require( 'package' )
のみで使用可能であり、ソフトウェアのように動作することです。
これらの2つの要件を満たせば、何でもできます。モジュールがES6で作成されている場合でも、エンドユーザーがそれを知る必要がない場合は、最大のサポートを得るために今のところそれを変換します。
ただし、 koa のように、モジュールにES6機能を使用するユーザーとの互換性が必要な場合は、おそらく2つのパッケージソリューションの方が良いでしょう。
require( 'your-package' )
を機能させるために必要なコードだけを公開してください。モジュールの構造に依存しているため、このソリューションは機能しない場合がありますが、モジュールが単一のファイル内に含まれ、依存関係がない(importを使用しない場合) )、次のパターンを使用すると、コードをそのままリリースでき、import(Browser ES6 Modules)およびrequire(Node CommonJS Modules)でインポートできます
おまけとして、SCRIPT HTML要素を使用してインポートするのが適切です。
main.js:
(function(){
'use strict';
const myModule = {
helloWorld : function(){ console.log('Hello World!' )}
};
// if running in NODE export module using NODEJS syntax
if(typeof module !== 'undefined') module.exports = myModule ;
// if running in Browser, set as a global variable.
else window.myModule = myModule ;
})()
my-module.js:
// import main.js (it will declare your Object in the global scope)
import './main.js';
// get a copy of your module object reference
let _myModule = window.myModule;
// delete the the reference from the global object
delete window.myModule;
// export it!
export {_myModule as myModule};
package.json: `
{
"name" : "my-module", // set module name
"main": "main.js", // set entry point
/* ...other package.json stuff here */
}
モジュールを使用するには、通常の構文を使用できます...
NODE ...にインポートされた場合.
let myModule = require('my-module');
myModule.helloWorld();
// outputs 'Hello World!'
BROWSER ...にインポートした場合.
import {myModule} from './my-module.js';
myModule.helloWorld();
// outputs 'Hello World!'
または、HTMLスクリプト要素 ...を使用して含まれている場合でも.
<script src="./main.js"></script>
<script>
myModule.helloWorld();
// outputs 'Hello World!'
</script>
ホセとマリウスのアプローチに従って(2019年にバベルの最新バージョンを更新):最新のJavaScriptファイルをsrcディレクトリに保持し、npmのprepublish
スクリプトを使用してビルドし、libディレクトリに出力します。
。npmignore
/src
。gitignore
/lib
/node_modules
バベルをインストール(私の場合はバージョン7.5.5)
$ npm install @babel/core @babel/cli @babel/preset-env --save-dev
package.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"
]
}
}
そして、矢印関数を使用するsrc/index.js
があります:
"use strict";
let NewOneWithParameters = (a, b) => {
console.log(a + b); // 30
};
NewOneWithParameters(10, 20);
GitHubのリポジトリ です。
これで、パッケージを公開できます。
$ npm publish
...
> [email protected] prepublish .
> babel src -d lib
Successfully compiled 1 file with Babel.
...
パッケージがnpmに公開される前に、lib/index.js
が生成され、es5に変換されていることがわかります。
"use strict";
var NewOneWithParameters = function NewOneWithParameters(a, b) {
console.log(a + b); // 30
};
NewOneWithParameters(10, 20);