web-dev-qa-db-ja.com

WebpackとBabelを使用したES6動的インポート

私はES6JSプロジェクトにWebpackを使用しており、動的インポートを使い始めるまで順調に進んでいます。

私がそれを機能させたもの(router.js):

_import { navigo } from "Navigo"; // router
import { clients } from "Controllers/clients.js";

const navigo = new Navigo();

navigo_router.on({
  '/clients': () => {
    clients.init();
  }
});
_

ただし、追加するページ/ルートが多いほど、モジュールの先頭に多くのインポートが積み上げられます。これは比較的大きなアプリであり、追加するページ/ルートがたくさんあるため、最初のページ読み込みのサイズを減らすためにそれらを動的に読み込む必要があります。

したがって、 動的インポートに関するWebpackのドキュメント に従って、コントローラーモジュールをロードする次のことを試しましたonly相対ルートが呼び出されたとき:

_import { navigo } from "Navigo"; // router

const navigo = new Navigo();

navigo_router.on({
  '/clients': () => {
    import("Controllers/clients.js").then((clients) => {
      clients.init();
    });
  }
});
_

しかし、これをエディターに保存すると、Babelトランスパイルエラーが発生しました。 SyntaxError: 'import'および 'export'はトップレベルにのみ表示される可能性があり、clients.init()はテスト時に呼び出されませんブラウザ。

少し読んだ後、動的なimport()を_require.ensure_にトランスパイルするには Babelプラグイン が必要であることがわかりました。そこで、次のコマンドを使用してプラグインをインストールしました。

_npm install babel-plugin-dynamic-import-webpack --save-dev
_

そして私の_babel.rc_ファイルでプラグインを宣言しました

_{ "plugins": ["dynamic-import-webpack"] }
_

プラグインをインストールした後、トランスパイルエラーが消え、トランスパイルされたコードを確認したところ、動的なimport() sが実際には_require.ensure_に変更されていることがわかりました。しかし、テスト時に次のブラウザエラーが発生します。

_Error: Loading chunk 0 failed.
Stack trace:
u@https://<mydomain.com>/js/app.bundle.js:1:871
SyntaxError: expected expression, got '<' 0.app.bundle.js:1
Error: Loading chunk 0 failed.
_

なぜ_0.app.bundle.js_を_0._プレフィックスで参照しているのか理解できなかったので、output/distフォルダーを確認すると、そこに_0.app.bundle.js_という新しいファイルがあります。

_0.app.bundle.js      1,962bytes
app.bundle.js        110,656bytes
_

この新しいバンドルファイルは、動的にインポートされたモジュール_clients.js_だと思います。

その1つのルートに動的インポートを追加しただけで、他のすべてのルートはそのままにしました。したがって、テスト中に、上記のエラーをスローする1つの_/clients_ルートを除くすべてのルートを表示できます。

私はこの時点で完全に迷子になっていて、誰かが私をフィニッシュラインに押し上げるのを手伝ってくれることを望んでいました。この新しいファイル_0.app.bundle.js_とは何ですか?また、どのように使用するか、アプリケーションに含めることになっていますか?

私は自分自身を十分に明確に説明したことを望み、どんな反応も楽しみにしています。

8
Martin James

最終的には自分の問題を解決できたので、発見したことを回答で共有します。

チャンクファイルがロードされなかった理由は、Webpackが間違ったディレクトリを探していたためです。開発者コンソールの[ネットワーク]タブで、チャンクファイル/モジュールが、それが属する_/_ディレクトリではなく、ルートディレクトリ_/js_から呼び出されていることに気付きました。

Webpackのドキュメントに従って、Webpack構成ファイルに以下を追加しました。

_output: {
  path: path.resolve(__dirname, 'dist/js'),
  publicPath: "/js/", //<---------------- added this
  filename: 'app.bundle.js'
},
_

私の理解では、pathはWebpackの静的モジュール用であり、publicPathは動的モジュール用です。

これによりチャンクが正しく読み込まれましたが、client.init()が呼び出されず、次のエラーが発生したため、さらに対処する必要がありました。

_TypeError: e.init is not a function
_

これを修正するには、次の変更も必要でした。

_import("Controllers/clients.js").then((clients) => {
  clients.init();
});
_

に:

_import("Controllers/clients.js").then(({clients}) => {
  clients.init();
});
_

矢印関数パラメーターの中括弧に注意してください。

これが他の誰かに役立つことを願っています。

4
Martin James

デバッグするには、次のことを行う必要があります

import("Controllers/clients.js").then((clients) => {
    console.log(clients);
});

多分働いている

import("Controllers/clients.js").then((clients) => {
    clients.default.init();
});
0
Igor Ognichenko