webpack-dev-server
このサイトは作成途中のものを公開しています。 また、Webpackのバージョンが1.13.0の頃に作成されたものですが、2017年2月現在Webpackは1系を非推奨として2の使用を勧めています。
webpack-dev-server
は小さなnode.jsのExpressサーバーで、
webpack-dev-middlewareを使用してwebpackのバンドルを提供します。
これは小さなランタイムも持ち、Socket.IOを介してサーバーへ接続されます。 サーバーはイベントに反応して、クライアントへコンパイル状態についての情報を発行します。 これは必要に応じた異なるモードを選択することが可能です。
下記の設定ファイル(webpack.config.js
)があるとしましょう。
var path = require("path");
module.exports = {
entry: {
app: ["./app/main.js"]
},
output: {
path: path.resolve(__dirname, "build"),
publicPath: "/assets/",
filename: "bundle.js"
}
};
app
フォルダの中に初回のエントリポイントがあり、
webpackはbuild
フォルダの中にbundle.js
ファイルをバンドルします。
Content Base
webpack-dev-serverは、特定のContent Base(--content-base)を設定しない場合は、 現在のディレクトリ内のファイルをWebサーバーのファイルとして提供とします。
$ webpack-dev-server --content-base build/
上記のwebpack-dev-serverの設定を使用すると、build
フォルダの静的ファイルがWebサーバーのファイルとして提供されます。
これはソース・ファイルの変更の監視を行い、変更があればバンドルを再コンパイルします。
この再コンパイルされたバンドルは、publicPathで指定された相対パスのメモリーから提供され、 あなたが設定した出力先のディレクトリに書き込まれません。 同じURLのパスに既にバンドルが存在している場合、メモリ内のバンドルが優先されます。(デフォルト)
例えば上記の設定で、バンドルがlocalhost:8080/assets/bundle.js
で利用されているとします。
バンドルされたファイルを読み込むために、
静的ファイルをWebサーバーから提供する設定(--content-base
オプション)をしたbuild
フォルダ内に、
index.html
ファイルを作成する必要があります。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script src="assets/bundle.js"></script>
</body>
</html>
デフォルトでは、localhost:8080/
でアプリケーションが起動します。
上記の設定であれば、publicPath
はlocalhost:8080/assets/
になります。
自動再読み込み
webpack-dev-serverはページの自動再読み込みに、複数のモードをサポートしています。
- Iframeモード (ページはiframe内に埋め込まれる)
- Inlineモード (変更によってページを再読み込みする小さなwebpack-dev-serverクライアントのエントリが、バンドルに追加される)
また、どちらのモードもHot Module Replacementをサポートし、これによりページ全体をリロードする代わりに、変更が発生したことがバンドルに伝えられます。 Hot Module Replacementのランタイムは更新されたモジュールを読み込み、実行中のアプリケーションに注入することがあるかもしれません。
Iframeモード
iframeモードを使用する場合、設定の追加は必要ありません。
単に、ブラウザでhttp://<host>:<port>/webpack-dev-server/<path>
にアクセスするだけです。
上記の設定であれば、http://localhost:8080/webpack-dev-server/index.html
になります。
- 設定の変更が不要
- アプリケーションの上部のバーに便利な情報が提供されます。
- アプリケーションのURL変更がブラウザのURLバーに反映されません。
Inlineモード
Inlineモードを使用するには、コマンドライン上で--inline
を指定します。(設定で指定することは出来ません)
URLの変更はありません。
http://<host>:<port>
にアクセスするだけです。
例えば上記の設定であれば、http://localhost:8080/index.html
になります。
- コマンドラインのフラグが必要です。
- ブラウザのログに、ステータス情報が提供されます。
- アプリケーション内のURLの変更は、ブラウザのURLバーに反映されます。
node.jsのAPIを使用したインラインモード
webpack-dev-serverの設定にはinline: true
のフラグが存在しません。
これは、webpack-dev-serverのモジュールがwebpackの設定へのアクセスを持たないためです。
その代わりに、ユーザーはwebpack-dev-serverのクライアントのエントリーポイントを、設定に追加しなければなりません。
これを行うには、webpack-dev-server/client?http://<path>:<port>/</code>
を(全ての)エントリーポイントへ追加します。
例えば、上記の設定の場合は、下記のようにします。
var config = require("./webpack.config.js");
config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/");
var compiler = webpack(config);
var server = new WebpackDevServer(compiler, {...});
server.listen(8080);
HTMLでInlineモードを指定
また、webpack-dev-serverクライアント・スクリプトへの参照をHTMLページに追加するという選択肢もあります。
<script src="http://localhost:8080/webpack-dev-server.js"></script>
Hot Module Replacement
webpack-dev-serverで、Hot Module Replacementを有効にするには、コマンドライン上で--hot
を指定します。
これはwebpackの設定に、HotModuleReplacementPlugin
を追加します。
webpack-dev-serverでHot Module Replacementを一番簡単に使う方法は、Inlineモードを使用することです。
CLI上のInlineモードでのHot Module Replacement
特別に何かを行う必要はありません。
--inline --hot
は自動的に関する全ての作業を行います。
webpack-dev-serverのCLIは、自動的に特別なwebpack/hot/dev-server
エントリーポイントを、あなたの設定に追加します。
http://<host>:<port>/<path>
にアクセスして、何が起こるのか確認してみましょう。
ブラウザのログで、下記のメッセージが確認できるはずです。
[HMR] Waiting for update signal from WDS...
[WDS] Hot Module Replacement enabled.
[HMR]
が付くメッセージは、webpack/hot/dev-server
からのものです。
[WDS]
が付くメッセージは、webpack-dev-serverクライアントからのものです。
正しくoutput.publicPath
を指定することが重要になり、もし間違っているとHot Updateのチャンクの再読み込みが出来ません。
node.jsのAPIでのHot Module Replacement
Inlineモードと同じように、ユーザーはwebpackの設定を変更しなければいけません。 3箇所の変更が必要になります。
-
webpackの設定のエントリーポイントに
webpack/hot/dev-server
を追加。 -
webpackの設定に
new webpack.HotModuleReplacementPlugin()
を追加。 -
webpack-dev-server
の設定に、サーバーでHMRを有効にするために、hot: true
を追加。
例えば、上記の設定であれば次のようになります。
var config = require("./webpack.config.js");
config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/", "webpack/hot/dev-server");
var compiler = webpack(config);
var server = new webpackDevServer(compiler, {
hot: true
...
});
server.listen(8080);
"safe write"をサポートしているエディタ/IDEで使用する際の注意
多くのエディタは、開発サーバーがファイルを正しく監視することが出来なくなる"safe write"機能をサポートしており、 デフォルトでこれが有効になっています。 "safe write"は、元のファイルに変更が直接書き込まれない代わりに一時ファイルに書き込まれ、 保存処理が完全に成功した際に元のファイル名にリネームされ置き換えられます。
この挙動は、元のファイルが削除されてしまうため、ファイル監視がファイル見失うという事態を招きます。 この問題を避けるためには、エディタの"safe write"機能を無効にする必要があります。
- vimの設定 -
:set backupcopy=yes
(参考: ドキュメント) - IntelliJ - Settings -> System Settings -> Synchronization -> disable "safe write" (各IntelliJのIDEで異なる可能性があります。その場合はsearch featureを使用してください。)
Proxy
webpackの開発用サーバー(dev server)は、node-http-proxyを使用することで、 バックエンドサーバー(外部へのリクエストも可能)へのproxyリクエストを好きなように振り分けることを可能にしてくれます。 設定例は下記のようになります。
proxy: {
'/some/path*': {
target: 'https://other-server.example.com',
secure: false
}
}
設定の詳細については、node-http-proxyのドキュメント(オプション)を参照してください。
一部のURLをプロキシすることは、様々な(開発)環境の構築において便利なことがあります。 一例として、JavaScriptファイルやその他の静的なファイル(資産)をローカルの開発サーバーから提供し、 APIのリクエストは外部のバックエンドの開発サーバーに送信するという設定が考えられます。
別の例として、バックエンドのサーバーへのリクエストを、 認証とアプリケーションのバックエンドの2つに分ける、ということも考えられます。
Proxyのバイパス(迂回)
(v1.13.0で追加)
proxyは関数から返される情報を基にして、任意にバイパスすることが可能です。
この関数は与えられたproxyオプションによって、HTTPリクエスト・レスポンスに割り込みます。
戻り値としてfalse
、またはプロキシのリクエストに代わるURLのパスを返さなければいけません。
例えば下記の設定は、ブラウザからの本来のHTTPリクエストに対して、プロキシを行いません。
これはhistoryApiFallback
のオプションと同じように、ブラウザのリクエストは通常のHTMLファイルとして受け取りますが、
APIリクエストはバックエンドサーバーにproxyされます。
proxy: {
'/some/path*': {
target: 'https://other-server.example.com',
secure: false,
bypass: function(req, res, proxyOptions) {
if (req.headers.accept.indexOf('html') !== -1) {
console.log('Skipping proxy for browser request.');
return '/index.html';
}
}
}
proxyリクエストのURLを書き換え
(v???で追加) proxyへのリクエストは、提供された関数で任意に書き換えることが可能です。 この関数はHTTPリクエストへの割り込みと変更を行います。
例えば、下記の設定はURLの先頭の/api
部分を削除して、HTTPリクエストを書き換えます。
proxy: {
'/api/*': {
target: 'https://other-server.example.com',
rewrite: function(req) {
req.url = req.url.replace(/^\/api/, '');
}
}
}
webpack-dev-server CLI
$ webpack-dev-server <entry>
全てのwebpackのCLIオプションは、webpack-dev-serverのCLIにも有効ですが、
デフォルトの引数の<output>
は存在しません。
webpack.config.js
(または、--config
によるファイルの受け渡し)によるwebpack-dev-serverのCLIのための設定が、
同様に受け入れられます。
webpack-dev-server用に追加されるオプションは下記のとおりです。
オプション | 説明 |
---|---|
--content-base <file/directory/url/port> |
コンテンツのベースとなるパスです。 |
--quiet |
コンソールに何も出力しません。 |
--no-info |
冗長な情報の出力を抑制します。 |
--colors |
出力情報の色付けを行います。 |
--no-colors |
出力情報に色付けを行いません。 |
--compress |
gzip圧縮を使用します。 |
--host <hostname/ip> |
ホスト名、またはIPアドレスを指定します。0.0.0.0 のIPアドレスは、全てのホストにバインドします。
|
--port <number> |
ポート番号を指定します。 |
--inline |
バンドルへwebpack-dev-serverのランタイムを埋め込みます。 |
--hot |
HotModuleReplacementPlugin を追加し、サーバーをhotモードに切り替えます。注意: HotModuleReplacementPluginが重複して追加されないようにしてください。 |
--hot --inline |
webpack/hot/dev-server エントリーも追加します。
|
--lazy |
no watching, compiles on request (cannot be combined with --hot).
(--hot との連携は出来ません)
|
--https |
webpack-dev-serverがHTTPSプロトコルでサーバーを提供します。 リクエストを処理する際の、自己署名の証明書を含みます。 |
--cert 、--cacert 、--key |
証明書ファイルのパスを指定します。 |
--open |
ブラウザが開くデフォルトURLです。 (webpack-dev-server versions > 2.0) |
--history-api-fallback |
history APIのフォールバックのサポートを有効にします。 |
設定オプションの拡張
CLIを使用する場合、設定ファイルのdevServer
キー配下に、webpack-dev-serverのオプションを持たせることが可能です。
CLIの引数で渡されたオプションは、設定ファイルのオプションを上書きします。
devServer
キー配下のオプションについては、次のセクションを参照してください。
module.exports = {
// ...
devServer: {
hot: true
}
}
API
var WebpackDevServer = require("webpack-dev-server");
var webpack = require("webpack");
var compiler = webpack({
// configuration
});
var server = new WebpackDevServer(compiler, {
// webpack-dev-server options
contentBase: "/path/to/directory",
// or: contentBase: "http://localhost/",
hot: true,
// Enable special support for Hot Module Replacement
// Page is no longer updated, but a "webpackHotUpdate" message is send to the content
// Use "webpack/hot/dev-server" as additional module in your entry point
// Note: this does _not_ add the `HotModuleReplacementPlugin` like the CLI option does.
// Set this as true if you want to access dev server from arbitrary url.
// This is handy if you are using a html5 router.
historyApiFallback: false,
// Set this if you want to enable gzip compression for assets
compress: true,
// Set this if you want webpack-dev-server to delegate a single path to an arbitrary server.
// Use "*" to proxy all paths to the specified server.
// This is useful if you want to get rid of 'http://localhost:8080/' in script[src],
// and has many other use cases (see https://github.com/webpack/webpack-dev-server/pull/127 ).
proxy: {
"*": "http://localhost:9090"
},
// pass [static options](http://expressjs.com/en/4x/api.html#express.static) to inner express server
staticOptions: {
},
// webpack-dev-middleware options
quiet: false,
noInfo: false,
lazy: true,
filename: "bundle.js",
watchOptions: {
aggregateTimeout: 300,
poll: 1000
},
publicPath: "/assets/",
headers: { "X-Custom-Header": "yes" },
stats: { colors: true }
});
server.listen(8080, "localhost", function() {});
// server.close();
ミドルウェア(middleware)のオプションについては、webpack-dev-middleware を参照してください。
webpackの設定はWebpackDevServer
のAPIに渡されないことに注意してください。
そのため、webpack設定内のdevServer
オプションは、このケースでは使用されません。
また、WebpackDevServerのAPIにInlineモードは存在しません。
<script src="http://localhost:8080/webpack-dev-server.js"></script>
が、手動でHTMLページに挿入される必要があります。
historyApiFallback
オプション
もしHTML5のヒストリーAPIを使用している場合、404レスポンスの際にindex.html
を返す必要があるかもしれません。
これは、historyApiFallback: true
に設定することで行うことが出来ます。
ただし、もしwebpackの設定でoutput.publicPath
を変更している場合、
リダイレクト先のURLを指定する必要があります。
これは、historyApiFallback.index
オプションを使用して行うことが出来ます。
// output.publicPath: '/foo-app/'
historyApiFallback: {
index: '/foo-app/'
}
既存サーバーとの連携
あなたは開発用に、バックエンドサーバーまたはそのモックを動かしたいと考えているかもしれません。 ただし、バックエンドとしてwebpack-dev-serverを使用しないべきです。 webpack-dev-serverは静的な(webpackで出力された)ファイルのみを扱う目的で作られています。
webpack-dev-serverとあなたのバックエンドサーバーの2つを、連携して動かすことが可能です。
このケースでは、バックエンドサーバーによってHTMLページの送信が行われている場合でも、
webpackで出力されたファイルはwebpack-dev-serverにリクエストさせるように指定する必要があります。
一方でバックエンドサーバーに、生成されるHTMLページに含まれるscript
タグが、
webpack-dev-serverのファイルを対象とするように指定する必要があります。
加えて、webpack-dev-serverとwebpack-dev-serverのランタイム間を、 再コンパイルで再読み込みがトリガされるように繋げる必要があります。
webpack-dev-serverへリクエスト(チャンク読み込み、またはHMRのために)するようにwebpackに伝えるには、
output.publicPath
で完全なURLを提供する必要があります。
webpack-dev-serverとそのランタイムを繋げる最良の方法は、--inline
を付けてInlineモードを使用することです。
webpack-dev-serverのCLIは自動的にWebSocket接続を設置するエントリーポイントを含めます。
(また、webpack-dev-serverの--content-base
をバックエンドサーバーに指定している場合は、Iframeモードを使用することも可能です。)
もし、あなたのバックエンドサーバーにWebsocket接続をする必要がある場合、iFrameモードを使用する必要があります。
インラインモードを使用する場合は、ブラウザでバックエンドのサーバーのURLを開くだけです。
(もし、IFrameモードを使用している場合は、webpack-dev-serverのURLの先頭に/webpack-dev-server/
を付けて開きます。)
下記に具体例を示します。
-
webpack-dev-serverのポートは
8080
とします。 -
バックエンドサーバーのポートは
9090
とします。 -
<script src="http://localhost:8080/assets/bundle.js"></script>
を含んだ生成されたHTMLがあるとします。 -
webpackの設定で、
output.publicPath = "http://localhost:8080/assets/"
を指定します。 -
production用のファイルのコンパイルを行う際に、
--output-public-path /assets/
を使用します。 -
Inlineモードの場合:
--inline
http://localhost:9090
を開きます。
-
Iframeモードの場合:
-
webpack-dev-serverで、
contentBase = "http://localhost:9090/"
(--content-base
)を設定。 -
http://localhost:8080/webpack-dev-server/
を開きます。
-
webpack-dev-serverで、
もしくは、Proxyのオプションを使用します。
© 2010 - 2017 STUDIO KINGDOM