Webpack組織モジュールの原理-externalモジュール
5088 ワード
この記事では、Webpackがlibraryをパッケージ化する際によく使用するオプション
前の記事の例を使用して、ライブラリ
Webpackパッケージを使用してこのライブラリを公開します.
このようにパッケージされた
したがって、通常、ライブラリが
これはWebpackに教えています:このモジュールをコンパイルしたJSファイルに注入しないでください.私のソースコードに現れた
コンパイルされたbundleファイルの構造を見てみましょう.
もちろん、完全に修正されていないわけではありません.例えば、
externalの依存モジュールでは、npmを使用してライブラリをパブリッシュするなど、通常はこのようにすることができます.jqueryを
umd形式でのパッケージ
このような書き方は、上記のCommonJSのコンパイルバージョンとは構造が異なるようですが、実際には本質は同じです.現在umdは異なる運転環境に配慮しているため、 CommonJS: AMD: Var:
いずれの場合も、ロードされた
Webpackがコードを生成する部分については、少し迂回しているかもしれませんが、Webpackパッケージモジュールのメカニズムと原理を比較する必要があります.この部分については、この文章で詳しく議論しました.
以上,Webpackの
external
について説明します.これは、一般的なモジュールをパブリッシュしたlibraryにパッケージ化するのを避けるために使用されます.externalと宣言するモジュールを選択します.libraryが上位層で使用された後、最後段でWebpackがこのexternalの依存モジュールを統一的にパッケージ化します.external
オプションは一般的にlibraryのパッケージに使用されますが、libraryではなく最終的なappのパブリケーションJSファイルであれば、externalも意味がありません.Webpackパッケージlibraryの分析といくつかのオプションの役割について、前の文章で議論しました.externalオプション
前の記事の例を使用して、ライブラリ
util.js
を定義します.import $ from 'jquery'
function hideImages() {
$('img').hide();
}
export default {
"hideImages": hideImages
}
Webpackパッケージを使用してこのライブラリを公開します.
//
entry: {
util: './util.js',
}
//
output: {
path: './dist',
filename: '[name].dist.js'
library: 'util',
libraryTarget: commonjs2,
targetExport: 'default'
}
このようにパッケージされた
util.dist.js
ファイルは、ソースコードが使用されているため、jquery
のコードを完全に注入します.しかし、これは往々にして私たちが望んでいないため、jquery
は汎用的なモジュールであり、1つのappでは、他のライブラリもそれを使用する可能性が高い.最上位のエントリファイルappもそれを使用する可能性がある.各ライブラリモジュールのリリースバージョンがjqueryをそのまま自分のbundleにパッケージし、最後につづると、最終的なappリリースコードにはjqueryのコピーがたくさんある.もちろん、通常の機能には影響しませんが、コードボリュームが大きくなります.したがって、通常、ライブラリが
jquery
bootstrap
のような汎用JSモジュールに依存する必要がある場合、bundleにパッケージ化するのではなく、Webpackの構成でexternal
を宣言することができます.externals: {
jquery: {
root: 'jquery',
commonjs: 'jquery',
commonjs2: 'jquery',
amd: 'jquery',
},
},
これはWebpackに教えています:このモジュールをコンパイルしたJSファイルに注入しないでください.私のソースコードに現れた
import/require
というモジュールの文に対して、それを残してください.コンパイルされたbundleファイルの構造を見てみましょう.
module.exports = (function(modules) {
var installedModules = {};
function webpack_require(moduleId) {
// ...
}
return webpack_require('./util.js');
}) ({
'./util.js': generated_util,
// '/path/to/jquery.js': generated_jquery , 。
});
jquery
モジュールはbundleファイルにパッケージ化されていないが、util
の場合、その生成コードであるgenerated_util
関数のimport jquery
に関連する文も元の意味を保持していることがわかる.function generated_util(module, exports, webpack_require) {
var $ = require('jquery');
// util
// ...
}
もちろん、完全に修正されていないわけではありません.例えば、
import
を伝統的なrequire
キーワードに戻しました.ここではCommonJSスタイルのパッケージ方式を使っていますから.しかし、これらは二次的であり、重要なのはrequire
というキーワードを保持し、webpack_require
を使用してjqueryを本当に導入しないことです.つまり、現在のJSファイルのモジュール管理システムにはjqueryはありません.これはexternalのモジュールであり、このJSファイルが他の人に引用され、上層部でコンパイルされる必要がある場合、jqueryが本当に導入される可能性があります.そのとき、ここのrequire
キーワードはwebpack_require
に置き換えられます.externalの依存モジュールでは、npmを使用してライブラリをパブリッシュするなど、通常はこのようにすることができます.jqueryを
package.json
ファイルにdependencies
追加することができます.これにより、他の人のnpm install
がパブリッシュしたライブラリの場合、jqueryはnode_に自動的にダウンロードされます.modulesは他の人にパッケージして使用されます.umd形式でのパッケージ
umd
形式でパッケージ化すると、externalモジュールがどのように機能しているかがわかります.(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object') // commonjs2
module.exports = factory(require('jquery'));
else if(typeof define === 'function' && define.amd)
define("util", ['jquery'], factory); // amd
else if(typeof exports === 'object')
exports["util"] = factory(require('jquery')); // commonjs
else
root["util"] = factory(root['jquery']); // var
}) (window, function(__webpack_external_module_jquery__) {
return (function(modules) {
var installedModules = {};
function webpack_require(moduleId) {
// ...
}
return webpack_require('./util.js');
}) ({
'./util.js': generated_util,
});
}
generated_util
もそれに応じてパラメータ__webpack_external_module_jquery__
を追加する.function generated_util(module, exports, webpack_require,
__webpack_external_module_jquery__) {
var $ = __webpack_external_module_jquery__;
// util
// ...
}
このような書き方は、上記のCommonJSのコンパイルバージョンとは構造が異なるようですが、実際には本質は同じです.現在umdは異なる運転環境に配慮しているため、
require('jquery')
をfactoryのパラメータとして早める.実行環境ごとに、それぞれの方法があります.require('jquery')
文を保持します.define
においてjquery
を依存モジュールとして定義する.jquery
変数を全ローカルドメインから取り出します.これには、jqueryがモジュールの前にロードされている必要があります.いずれの場合も、ロードされた
jquery
モジュールをパラメータとしてfactory
関数に入力し、util
モジュールを正しくロードすることができます.Webpackがコードを生成する部分については、少し迂回しているかもしれませんが、Webpackパッケージモジュールのメカニズムと原理を比較する必要があります.この部分については、この文章で詳しく議論しました.
まとめ
以上,Webpackの
external
オプションの使用について述べ,コンパイル後のJSコードからどのように機能しているのかを解析した.Webpack関連の生成コードを読むことが大切だと思います.そうすれば、externalのメカニズムを本当に理解し、いくつかの穴にぶつかったときにdebugに行く方法を知ることができます.