はじめに
webpackが流行ってきているようなので、がんばって使ってみます。
流れが早すぎておじさんには辛いです。
せっかくwebpackを使うのでreact.jsを使ってみます。
こちらもはじめて。
webpackとは
jsの依存関係を解決して、複数のjsファイルを1つに結合してくれるビルドツールです。
大規模なアプリケーションを開発する際に、力を発揮しそうです。
◎gulpなどで結合するのとの違い
gulpなどでjsファイルを結合する際は、読み込み順を気にする必要がありますが、
webpackの場合、requireした箇所でモジュールを読み込んでくれるので順番を気にする必要が無いようです。
webpackを使ってみる
◎webpackをインストール
sudo npm install webpack -g
◎ファイル構成
.
└── www
├── index.html
└── js
├── main.js
└── sub.js
var sub = require('./sub');
sub('test');
module.exports = function(s) {
alert(s);
};
<body>
<script src="./dist/bundle.js"></script>
</body>
下記コマンドを実行
//webpack <input> <output>
$ webpack www/js/main.js www/dist/bundle.js
www配下にdist/bundle.jsが作成されます。
index.htmlをブラウザで開くとアラートが表示されます。
webpack.config.jsを使う
毎回コマンドを打つのは初心者の私には辛いので
設定ファイル(webpack.config.js)を使います。
webpackコマンド実行時のディレクトリ内に、webpack.config.jsがあった場合自動的に読み込んでくれます。
module.exports = {
entry: './www/js/main.js',
output: {
path:__dirname + '/www/dist/',
filename: 'bundle.js'
}
}
$ webpack
bundle.jsがwww/dist/配下に作成されます。
bowerと連携する
react.jsなど必要なライブラリをbowerに管理します。
webpackと連携するには少しだけ手間が必要です。
公式サイトの情報はこちら
var path = require("path");
var webpack = require("webpack");
module.exports = {
resolve: {
root: [path.join(__dirname, "bower_components")]
},
plugins: [
new webpack.ResolverPlugin(
new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
)
]
}
ただし上記の方法だが、少し問題があり、
ResolverPlugin.DirectoryDescriptionFilePlugin
を使用すると読み込むライブラリのbower.jsonのmainが配列の場合読み込めなくなる。
◎解決方法
bower-webpack-pluginを使用する。
これでmainが配列の場合も問題なく読み込むことができる。
var BowerWebpackPlugin = require("bower-webpack-plugin");
module.exports = {
plugins: [new BowerWebpackPlugin()]
}
gulpを使ってビルドする。
gulpタスクの中でwebpackを使うにはgulp-webpack
が必要です。
gulp-webpackをまずはインストールします。
追記
naru0504さんよりコメント頂ましたので修正点追記します。
- gulp-webpackは最新版はwebpack-streamと名前を変えている。 gulp-webpackだとビルドした際にwarningがでるのでwebpack-streamに移行したほうがよい。
webpackを実行する。設定はwebpack.config.jsを利用。
$ npm install gulp-webpack --save-dev
var gulp = require('gulp');
var webpack = require('gulp-webpack');
var webpackConfig = require('./webpack.config.js');
gulp.task('build', function() {
return gulp.src('')
.pipe(webpack(webpackConfig))
.pipe(gulp.dest('.www/dist/'));
});
これでgulp build
でwebpackを実行できるようになりました。
react.jsを使う
◎ファイル構成
.
├── bower.json
├── bower_components
├── gulpfile.js
├── node_modules
├── package.json
├── webpack.config.js
└── www
├── index.html
└── js
└── main.jsx
◎jsx-loaderをインストール
webpackで、JSXをコンパイルするには。jsx-loaderが必要となる為、インストールします。
$ npm install jsx-loader --save-dev
webpack.confing.jsのmodule.loadersで、jsx-loaderを読み込む。
module.exports = {
entry: {
bundle:'./www/js/main.jsx'
},
output: {
path: __dirname + '/www/dist/',
filename: '[name].js'
},
module: {
loaders: [{
test: /\.jsx$/,
loader: 'jsx-loader?harmony'
}]
},
//externals: {
// 'react': 'React'//html側でreact.jsを読み込んでいる場合は必要
//},
resolve: {
extensions: ['', '.js', '.jsx'],
}
};
補足
①harmonyオプション
loader: 'jsx-loader?harmony'のharmonyオプションを追加することで、ES6の仕様の一部を使うことができるようになります。
②externals
詳しくは下記を参照
webpackのconfiguration#externals
webpackによって解決されるべきではない依存関係を指定しますが、生成されたバンドルの依存関係になります。
よく意味がわからなかったが、webpackのコンパイルに含めないものを定義するようです。
例えば、react.jsをhtml側ですでに読み込んでいる場合、ビルドに含める必要がないのでexternalsに追加します。
◎react.jsをインストール
bower install react --save-dev
<body>
<div id="content"></div>
<script src="./dist/main.js"></script>
</body>
var React = require('react');
var CommentBox = React.createClass({
render: function() {
return (
<div className="commentBox">
わけワカメ
</div>
);
}
});
React.render(
<CommentBox />,
document.getElementById('content')
);
こちらの状態でビルドしてみたところ、下記のエラーが発生した。
React.createClass is not a function
v0.14でビルドする場合に発生しているが、原因がわからなかった。。。
v0.13インストールし直しでビルドしてみる。
$ bower install react#0.13 -save-dev
$ gulp build
今回はエラーが発生せず、下記の画面が表示された。
追記
naru0504さんよりコメント頂ました
- React v0.14.xでビルドした際のバグはbower-webpack-pluginのバグの可能性有り
- webpackはnpmでのパッケージ管理を推奨している為、bowerではなく、なるべくnpmを使用したほうがいいかもしれない
終わり
画面を表示するだけで大変でした。
もっとそれぞれの使い方について理解する必要があります。