ES5モジュールでのES6インポートのサポート


8

初年度の学生のために、私は明らかにモジュールパターンを使用して書かれたシンプルなES5ベースのライブラリを提供しました。以下は、「メイン」モジュール/名前空間のスニペットで、他の拡張機能を収容します。

window.Library = (function ($) {
    if (!$) {
        alert("The Library is dependent on jQuery, which is not loaded!");
    }

    return {};
})(window.jQuery);

これは、Web開発に不慣れで、ES6などのファンシーなものをWebpackやBabelと組み合わせて使用​​していない学生のほぼ99.9%に役立ちます。

0.1%から、適切にインポートできるES6ベースのバージョンを提供するように要求されました。私はこれを提供できれば幸いですが、これに最善のアプローチをする方法にちょっとこだわっています。

私は明らかにES5の方法を維持したいので、生徒はスクリプトタグを使用してファイルを含め、Library.SomeExtension.aFunction();好きな場所に入力することができます。その上、一部の拡張機能はjQueryに依存しており、jQueryは上記のスニペットと同様の方法で挿入されます。

現在、jQueryを依存関係として使用して、1つのコードベースで両方の世界を最大限に活用するための保守可能な方法を探しています。99.9%をa window.Libraryにしたいのに対し、0.1%に使用方法を与えたいimport Library from 'library'

両方を行う単一のJSファイルでこれを実現できますか?それとも特別なES6バージョンが必要ですか(問題はありません)?そして何よりも、両方の状況をサポートできるように、コード(すべて上記のスニペットと同様)をどのように改造しますか?

どんなポインタでも大歓迎です!

編集:ただ、サイドノートとして、私はすでに持っているgulpfile.jsこのによるライブラリ走る場所でBabelminifiers他のものを。したがって、上記の問題を解決するためにそれを拡張する必要はありません!


おそらく、自分でES6を使用し、グローバルリビールモジュールを生成するトランスパイラー/バンドラーを使用することで最もよく解決します。次に、ソースモジュールを0.1%に提供します。はい、単一のソースファイルですが、2つの分散ファイルです。
Bergi

両方を行う単一のJSファイルでこれを実現できますか?への回答を期待していますか?-これが可能で、それが可能でない場合、スクリプトはどのようになりますか?

@雪現在回答で提供されているリソースで遊んでいます。私が満足しているものを得るためにもう少し時間を費やす必要がありますが、あなたがスクリプトを作成する少し創造的であるならそれは可能であるようです!私の特定のケースでは、Library.SubLibrary.functionName誰かがそれをES6としてインポートした場合でも、セットアップを個別のファイルに保存したいと思っています。(これは主に、拡張機能が相互に使用でき、標準のES6セットアップを使用すると循環参照が発生するためです)。
Lennard Fonteijn

はい、個別のファイルを使用してこれを達成するのは簡単です。1つの用途exportを持ち、もう1つの用途をに割り当てwindowます。私はそれが可能だろうと考えた偉大なことはそんなによりエレガントな感じだろうので、両方は、単一のファイルで行うことができれば、しかし、export内部だけの仕事にキーワードルックスtype=module。回避策があるのか​​、それとも不可能なのかわかりません。

@LennardFonteijn循環依存関係はES6モジュールで完全に機能します。エクスポートされた機能のみを宣言し、最上位レベルで初期化コード(モジュールの評価順序に依存)を実行しないようにしてください。ネストされた名前空間オブジェクトを使用しないことをお勧めします。これはES6ではかなり慣用的です。
Bergi、

回答:


5

数夜コードを移動し、たくさんのgulpパッケージをインストールした後、試したすべてのパッケージを覚えていませんでしたが、最終的には自分がある程度満足しているものに落ち着きました。

まず、コメントで@Bergiによって裏付けられた自分の質問に答えます。

短い答え:いいえ、ブラウザはを使用するとエラーになるため、どのような方法でも(現時点では)ES6構文とES5(モジュール)を1つのファイルに混在させることはできませんexport

長い答え:技術的には、スクリプト要素のタイプを「モジュール」に設定できますexport。これにより、ブラウザがキーワードを受け入れるようになります。ただし、コードは単純に2回実行されます(ロード時に1回、インポート後に1回)。これで我慢できれば、いやいや、はいはい。

それで私は何をしましたか?まず、出力ES5ファイルで(今のところ)持っていたIIFEモジュールの設定を維持したいと思っていました。私はコードベースを純粋なES6に更新し、プラグインのあらゆる種類の組み合わせ(@David Bradshawによって言及されたRollup.jsを含む)を試しました。しかし、私は単にそれらを機能させることができなかったか、ブラウザがモジュールをロードできなくなったり、ソースマップのサポートをドロップできなくなったりして、出力を完全に壊してしまいました。学生たちが今行っているプロジェクトで終わりに近づいているので、私はすでに0.1%の学生のために十分な時間を無駄にしています。来年は「より良い」解決策が見つかるでしょう。

  1. 私はUMDパターン(@Sly_cardinalで言及)をjQueryに基づいており、そのコードをにスローしましたLibrary.umd.js。ES6のパーツについては、a Library.es6.jsのみのを作成しexport default Libraryました。

  2. どちらのファイルにも/*[Library.js]*/、連結された縮小されていないLibrary.jsを挿入する場所に複数行コメントを配置しました。

  3. 私はちょうど構築するために私の既存のがぶ飲みタスクを修正Library.jsしてconcatBabelし、一時的な場所にそれを保存します。連結されたコードは出力で完全に読み取り可能だったので、このプロセスではソースマップのサポートを犠牲にすることにしました。技術的にはソースマップのサポートは「機能しました」が、デバッガーから解放されすぎます。

  4. tempの内容を読み取るためにGulpタスクを追加しましたLibrary.js。次に、ステップ1の各ファイルについて、複数行のコメントを見つけて内容で置き換えます。結果のファイルを保存してから、最終的なファイルconcat(jQueryとのバンドルterserなど)とソースマップの生成を実行します。

最終結果は2つのファイルです。

  • UMD / ES5ブラウザーをサポートするもの
  • ES6をサポートするもの

結果には満足していますが、Gulpタスクチェーンと、プロセスの前半でのソースマップサポートの喪失は好きではありません。前に述べたように、同じ効果を達成するために多数のgulpプラグインを試しました(例gulp-inject:)が、それらが適切に機能しなかったか、ソースマップに奇妙なことをした(たとえサポートすると主張したとしても)。

次の試みとして、Gulpとは異なるものを調べるか、上記を実行する独自のプラグインを作成しますが、適切に:P


0

Rollup.jsを使用して、コードをES5ライブラリーおよび付随するES6モジュールとしてバンドルできます。

RollupにはGulpのサポート組み込まれているため、次のようなものが妥当な出発点になります(RollupのGulpの例に基づく)。

    const gulp = require('gulp');
    const rollup = require('rollup');
    const rollupTypescript = require('rollup-plugin-typescript');

    gulp.task('bundle', () => {
      return rollup.rollup({
        input: './src/main.ts',
        plugins: [
          rollupTypescript()
        ]
      }).then(bundle => {
          return Promise.all([
              // Build for ES5
              bundle.write({
                file: './dist/library.js',
                format: 'umd',
                name: 'Library',
                sourcemap: true
            }),

            // Build for ES6 modules
            bundle.write({
                file: './dist/library.esm.js',
                format: 'esm',
                sourcemap: true
            })
          ]);
      });
    });

利用可能なさまざまな出力形式の詳細については、https//rollupjs.org/guide/en/#outputformatをご覧ください。

ライブラリソースがESモジュールを使用して記述され、次にES5バンドルにバンドル/トランスパイルされる場合が最も簡単です。


これは素晴らしく、まさに私が必要とするものです!スピンしてレポートを返します:)
Lennard Fonteijn
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.