まず、Webpackが必要な理由と、Webpackが解決しようとしている問題を理解してから、Webpackを操作する方法を学習します。 Webpackを使用すると、アプリケーションでお辞儀や口論/うなり声を取り除き、1つのツールに置き換えることができます。 クライアントの依存関係をインストールおよび管理するための手段ではなく、標準のNode Package Manager(npm)を使用して、すべてのフロントエンドの依存関係をインストールおよび管理できます。 webpackは、ほとんどのうなり声/ gulpタスクも実行できます。
Bowerは、クライアント側のパッケージマネージャーです。 JavaScript、HTML、CSSのコンポーネントの検索、インストール、削除に使用できます。 GruntJSは、開発者が反復タスクを自動化するのに役立つJavaScriptコマンドラインユーティリティです。 MakeまたはAntのJavaScriptの代替と考えることができます。 彼は縮小、コンパイル、単体テスト、リントなどのタスクを処理します。
Webアプリケーションで単純なユーザープロファイルページを作成しているとします。 jQueryおよびアンダースコアライブラリを使用します。 1つの方法は、両方のファイルをHTMLに含めることです。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>User Profile</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css" media="screen"> <link rel="stylesheet" href="/css/style.css" media="screen"> </head> <body> <div class="container"> <div class="page-header"> <h1 id="timeline"></h1> </div> <ul class="timeline"> </ul> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script> <script src="js/profile.js"></script> </body> </html>
これは、ブートストラップを備えた単純なHTMLです。 スクリプトタグを使用してjQueryとアンダースコアを接続しました。
接続したライブラリを使用するprofile.js
ファイルを見てみましょう。 コードは、アプリケーションのビジネスロジックを格納する匿名のクロージャー内にあります。 コードを関数にロックしないと、変数はグローバル環境になり、これは悪いことです。
(function(){ var user = { name : "Shekhar Gulati", messages : [ "hello", "bye", "good night" ] }; $("#timeline").text(user.name+ " Timeline"); _.each(user.messages, function(msg){ var html = "<li><div class='timeline-heading'><h4 class='timeline-title'>"+msg+"</h4></div></li>"; $(".timeline").append(html); }); }());
スクリプトが呼び出されると、コードが実行されます。 ブラウザでページを開くと、プロファイルは次のようになります。
このコードには2つのタスクがあります。
- ユーザー情報を取得する
- タイムラインを設定します。
コンセプトの混合は悪い習慣であることが知られているため、特定のタスクを担当する個別のモジュールを作成する必要があります。 profile.js
ファイルでは、匿名クロージャーを使用してすべてのコードを保存しました。 JavaScriptには、モジュールを改善する方法があります。 2つの一般的な方法は、CommonJSとAMDです。
- CommonJSモジュールは、特定のオブジェクトをエクスポートする大体の再利用可能なコードであり、
require
使用して他のモジュールで利用可能になります。 - 非同期モジュール定義(AMD)を使用すると、モジュールを非同期にロードできます。
JavaScriptのモジュールについて詳しく知りたい場合は、記事JavaScript Modules:A Beginner's Guideを読むことをお勧めします。
この記事では、CommonJSでモジュールを作成します。 ヘッダーとタイムラインを設定するメソッドを持つタイムラインモジュールを作成しましょう。 CommonJSでは、 require
関数を使用して依存関係をインポートできます。 タイムラインはjquery
とunderscore
依存しunderscore
。
var $ = require('jquery'); var _ = require('underscore'); function timeline(user){ this.setHeader = function(){ $("#timeline").text(user.name+ " Timeline"); } this.setTimeline = function(){ _.each(user.messages, function(msg){ var html = "<li><div class='timeline-heading'><h4 class='timeline-title'>"+msg+"</h4></div></li>"; $(".timeline").append(html); }); } } module.exports = timeline;
このコードは、新しいtimeline
モジュールを作成します。 setHeader
とsetTimeline
2つの関数があります。 特別なmodule
オブジェクトを使用し、 module.exports
リンクを追加しmodule.exports
。 このようにして、CommonJSモジュラーシステムに、他の機能がモジュールを使用できるようにすることを伝えます。
次にprofile.js
更新し、 timeline
モジュールを使用する必要があります。 ユーザーに関する情報をロードする新しいモジュールを作成できますが、ここでは、1つのモジュールに制限します。
var timeline = require('./timeline.js'); var user = { name : "Shekhar Gulati", messages : [ "hello", "bye", "good night" ] }; var timelineModule = new timeline(user); timelineModule.setHeader(user); timelineModule.setTimeline(user);
index.htmlをブラウザにロードすると、空白のページが表示されます。 コンソール(開発者ツール)でエラーを見つけることができます。
profile.js:1 Uncaught ReferenceError: require is not defined
問題は、ブラウザがCommonJSのようなモジュラーシステムを理解しないことです。 ブラウザに期待される形式を提供する必要があります。
モジュールバンドラーが助けになります
Webブラウザーは、これらのよく説明されているモジュールを理解しません。 すべてのJavaScriptコードを1つのファイルに追加してインポートするか、 script
タグを使用してすべてのファイルをページに手動で追加する必要があります。 この問題を解決するには、モジュールバンドラーを使用します。 Bundlerモジュールは、異なるモジュールとそれらの依存関係を正しい順序で1つのファイルに結合します。 さまざまなモジュラーシステムを使用して記述されたコードを解析し、ブラウザーが理解できる1つの形式に結合できます。 2つの一般的なモジュールバンドラーは次のとおりです。
- browserify :ブラウザーで後で使用するためにnpmモジュールをパックします。 browserifyの場合、リント、テストの実行などのためにGruntまたはGulpを追加で接続する必要があります。これは、いくつかのツールと統合の作業に時間を費やす必要があることを意味します。
- webpack :モジュールのバンドル(レイアウト)を提供するだけでなく、 Gulp / Gruntが実行するタスクも実行できるビルドシステム。 さらに、webpackはJavsScriptファイルに限定されず、CSS、画像、htmlコンポーネントなどの他の静的変数と連携できます。webpackは、
code splitting
(code splitting
)という非常に便利な機能もサポートします。 大規模なアプリケーションは、必要に応じてダウンロードされる断片に分割できます。
webpackとは何ですか?
公式の定義は次のとおりです。
webpackは依存関係のあるモジュールを受け取り、これらのモジュールが表す静的リソースを生成します
この定義は、解決される問題が理解されたときに意味をなします。 Webpackはリソースのセットを取得し、それらをセット(バンドル)に変換します。
リソースの変換には、webpackの心臓部であるローダーが関係していました。
動作中のWebpack
webpackをインストールするには、ノードが必要です。 公式サイトからノードをダウンロードできます。
これで、webpackをグローバルにインストールできます。
$ npm install -g webpack
npm init
コマンドで新しいモジュールを作成します。 彼女はpackage.json
ファイルを作成します。 npmを使用して依存関係をインストールします。
$ npm install -S jquery $ npm install -S underscore
さらに、webpackを依存関係としてインストールする必要があります。
$ npm install -S webpack
index.html
次のコードに置き換えます。 ご覧のとおり、jqueryとunderscoreのスクリプトタグをすべて削除しました。 また、 js/profile.js
をインポートする代わりにjs/profile.js
dist/bundle.js
ます。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>User Profile</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css" media="screen"> <link rel="stylesheet" href="/css/style.css" media="screen" title="no title"> </head> <body> <div class="container"> <div class="page-header"> <h1 id="timeline"></h1> </div> <ul class="timeline"> </ul> </div> <script src="dist/bundle.js" charset="utf-8"></script> </body> </html>
バンドルを作成しましょう。
$ webpack js/profile.js dist/bundle.js
Hash: 6d83c7db8ae0939be3d0 Version: webpack 1.13.2 Time: 350ms Asset Size Chunks Chunk Names bundle.js 329 kB 0 [emitted] main [0] ./js/profile.js 252 bytes {0} [built] [1] ./js/timeline.js 427 bytes {0} [built] + 2 hidden modules
これで、ページは正常に機能しています。
webpackモニターの変更を行い、自動的にバンドルを生成できます。 これを行うには、次のフラグを指定して実行します。
$ webpack -w js/profile.js dist/bundle.js
これで、webpackは自動的に終了しません。 ファイルを変更すると、新しいバンドルが生成されます。 ブラウザでページをリロードするだけです。 profile.js
変更しましょう:
var user = { name : "Shekhar Gulati!!!", messages : [ "hello", "bye", "good night" ] };
bundle.js
によって生成されたbundle.js
ファイルには、webpack自体に関連する多くのコードが含まれており、そこにあるコードは変更された形式になります。 ブラウザ、たとえば開発者ツールでアプリケーションをデバッグするのは非常に不便です。 生活を簡素化するために、devtoolsフラグを使用してwebpackを実行できます。
$ webpack -w --devtool source-map js/profile.js dist/bundle.js
webpackはbundle.jsファイルのソースマップを生成します。 ソースマップは、最小化およびコンパイルされたコードを、ソースのアセンブルされていないコードと単一のファイルに関連付けます。 テストのために、profile.jsにdebugger
行を追加できdebugger
var timeline = require('./timeline.js'); var user = { name : "Shekhar Gulati", messages : [ "hello", "bye", "good night" ] }; debugger; var timelineModule = new timeline(user); timelineModule.setHeader(user); timelineModule.setTimeline(user);
ページをリロードすると、アプリケーションはこの行で停止します。
CSSを追加する
上記のHTMLでは、 /css/style.css
を読み込んでいることが/css/style.css
ます。 Webpackは、JavaScriptだけでなく、CSSを含む他の静的変数でも機能します。 index.html
から/css/style.css
の行を削除します。 このように、 profile.js
にスタイルを含めます。
require('../css/style.css'); var timeline = require('./timeline.js'); var user = { name : "Shekhar Gulati", messages : [ "hello", "bye", "good night" ] }; var timelineModule = new timeline(user); timelineModule.setHeader(user); timelineModule.setTimeline(user);
webpackは変更をリロードし、コンソールにエラーメッセージが表示されます。
ERROR in ./css/style.css Module parse failed: /Users/shekhargulati/dev/52-technologies-in-2016/36-webpack/code/css/style.css Unexpected token (1:0) You may need an appropriate loader to handle this file type.
問題は、webpackがデフォルトでCSSを理解しないことです。 これには、いくつかのブートローダーをインストールする必要があります。 必要なブートローダーをインストールするコマンドは次のとおりです。
$ npm install style-loader css-loader --save-dev
Webpackはダウンローダーを使用して、テキストを目的の形式に変換します。 次に、 require
を更新require
。
require('style!css!../css/style.css');
構文style!css!
つまり、最初にcss
変換を適用してstyle.css
からCSSにテキストを変換し、次にstyle
変換を使用してページにスタイルを適用する必要があります。
Webpackを再度実行します。
$ webpack -w --devtool source-map js/profile.js dist/bundle.js
構成
コマンドラインですべてのオプションを指定しないために、アプリケーションルートにwebpack.config.js
構成ファイルを作成できます。
module.exports = { context: __dirname, devtool: "source-map", entry: "./js/profile.js", output: { path: __dirname + "/dist", filename: "bundle.js" } }
これで、シンプルなwebpack -w
コマンドでwebpackを実行できます。
style!css!
を追加したときstyle!css!
profile.js
では、量産コードとwebpack構成を混合しました。 このオプションを構成ファイルに転送できます。
構成の変更後、webpackを再起動する必要があります。
var webpack = require('webpack'); module.exports = { context: __dirname, devtool: "source-map", entry: "./js/profile.js", output: { path: __dirname + "/dist", filename: "bundle.js" }, module:{ loaders: [ {test : /\.css$/, loader: 'style!css!'} ] } }
ここで最も興味深いセクションは、モジュールの宣言です。 ここで、ファイルが.cssで終わる場合、 style!css!
を適用する必要があることを指摘しましたstyle!css!
。
ホットリブート
ホットリロードにはwebpack-dev-server
が必要webpack-dev-server
。 次のようにインストールします。
$ npm install -g webpack-dev-server
これで、 webpack-dev-server
コマンドを使用してサーバーを起動できwebpack-dev-server
。
http:// localhost:8080 / webpack-dev-server /でサーバーを起動し、 webpack.config.js
の構成を使用しwebpack.config.js
。
ポートは--port
オプションで変更できます。
$ webpack-dev-server --port 10000
http://localhost:10000/webpack-dev-server
webpack-dev-server
構成は、 devServer
セクションのwebpack.config.js
ファイルでも指定できます。
module.exports = { context: __dirname, devtool: "source-map", entry: "./js/profile.js", output: { path: __dirname + "/dist", filename: "bundle.js" }, module:{ loaders: [ {test : /\.css$/, loader: 'style!css!'} ] }, devServer: { inline:true, port: 10000 }, }
今日は以上です。 Webpackの詳細については、 ドキュメントをご覧ください。