12

次のようなファイルがありますd3.custom.build.js(簡略化):

import { range } from 'd3-array';
import { select, selectAll, event } from 'd3-selection';
import { transition } from 'd3-transition';

export default {
    range,
    select,
    selectAll,
    event,
    transition
};

そして、rollup.config.jsこのような:

import nodeResolve from 'rollup-plugin-node-resolve';

export default {
    entry: './js/vendor/d3-custom-build.js',
    dest: './js/vendor/d3-custom-built.js',
    format: 'iife',
    globals: {
        d3: 'd3'
    },
    moduleId: 'd3',
    moduleName: 'd3',
    plugins: [nodeResolve({ jsnext: true })]
};

「d3」という名前のプレーンな古いブラウザー グローバルにエクスポートしたいと考えています。簡単な npm スクリプトからロールアップを呼び出しています。良いニュースは、1 つのことを除いて、ほとんどすべてが出力ファイルで機能することです:d3.eventブラウザーでは常に null です。いいえ、ページでイベントがハイジャックされても問題ありません。標準の完全な d3 4.0 ライブラリをスクリプト タグにスワップすると、すべて正常に動作します。それは間違いなくビルドの問題です。

d3 docsは、バンドルeventが難しいことを警告しています:

Babel、Webpack、または別の ES6-to-ES5 バンドラーを使用する場合は、イベント中に d3.event の値が変化することに注意してください。d3.event のインポートはライブ バインディングでなければならないため、生成された UMD バンドルからではなく、D3 の ES6 モジュールからインポートするようにバンドラーを構成する必要がある場合があります。すべてのバンドラーが jsnext:main を監視するわけではありません。また、window.event グローバルとの競合にも注意してください。

設定nodeResolve({ jsnext: true })が不十分なようです。バンドルでライブ バインディングを取得するにはどうすればよいですか? どんなガイダンスでも大歓迎です。

4

1 に答える 1

14

デフォルトのエクスポートとして、ES2015 の省略形のオブジェクト リテラル構文を使用して定義されたオブジェクトをエクスポートしています。あなたが書いたものと同等の長い形式は次のとおりです。

export default {
  range: range,
  select: select,
  selectAll: selectAll,
  event: event,
  transition: transition
}

したがって、オブジェクトeventは、null である on load の値をキャプチャします。これはライブ バインディングではなく、現在のイベントを反映しません。

event修正の 1 つは、getter を使用してプロパティを定義することです。

export default {
  range,
  select,
  selectAll,
  get event() { return event; },
  transition
}

デフォルトのエクスポートの代わりに名前付きのエクスポートを使用することをお勧めします。そうすれば、Rollup によってライブ バインディングが自動的に生成されます。

export {
  range,
  select,
  selectAll,
  event,
  transition
}

これは単に短いだけでなく、ES2015 の省略形オブジェクト リテラル構文をサポートするブラウザーに依存しなくなりました。

于 2016-10-14T16:51:18.340 に答える