全部のせRequireJSっぽいWebpackを使ってみた。

  • 82
    いいね
  • 2
    コメント
この記事は最終更新日から1年以上が経過しています。

自分のお守りしているプロジェクトがいい加減だるだるになってきてモジュール管理しないとしないと死んじゃう!! みたいな状況になってきた。

RequireJSを導入しようとしていたはずが、何故か気がついたらWebPackを試していた… その間の記憶は全くない。

Webpackって何?

RequireJSと同じく、モジュール管理/バンドル化をしてくれるツール

  • AMD(RequireJSのやつ), CommonJS形式両対応
  • Jade、CoffeeScriptのローダーもある
  • コード分割(Code Spliting) ... 非同期でモジュールを読み込む機能
  • WatchしたりUglifyもしてくれる(Gruntとかぶってる)

Browserifyとの比較記事を見かけたがBrowserify使ったこと無いので良し悪しは分からず...

導入

npmからインストールする。gruntで使いたいので、grunt-webpackも。
coffee-loaderはWebpackでcoffeeから読み込むためのプラグイン 
(ちゃんとメモってなかったので間違ってたらごめんなさい)

$ npm install --save-dev webpack grunt-webpack coffee-loader

Gruntfile

Plugin使いたいのと、ファイルパス周りが特殊なので上の方でrequire

Gruntfile.coffee
path = require('path')
webpack = require('webpack')

タスク設定はこんな感じ
結構無理やりGruntから使えるようにしているようで、設定をoptionsに書き、Grunt的なfilesセクションは無視される。

(追記: 現在は、multitask化されているので、このままでは動きません。コメント参照)

Gruntfile.coffee
webpack:
  options:

    # 進捗どうですか
    progress: true

    # entryは複数書けるらしい。
    entry:
      bundle: 'entry.coffee'

    # .coffee拡張子のスクリプトは`coffee-loader`で読むように指定
    module:
      loaders: [
        { test: /\.coffee$/, loader: 'coffee-loader' }
      ],

    # output先を指定。 [name]などは適宜置換される [参照](http://webpack.github.io/docs/configuration.html#output-filename)
    output:
      path: path.join(__dirname, "www/static/js/")
      publicPath: 'www/static/js/'
      filename: '[name].js'
      chunkFilename: '[chunkhash].js'

    # ファイル名解決のための設定
    resolve:
      # 'src/coffee'にコードを入れているので、指定
      root: path.join(__dirname, 'src/coffee')

      # 探索するモジュール用ディレクトリを指定。デフォルトではbower_componentsは入っていない。 `moduleDirectories`とtypoしてて小一時間ハマった
      modulesDirectories: ['node_modules', 'bower_components']

      # .coffeeを省略できるようにする
      extensions: ['', '.coffee', '.webpack.js', '.web.js', '.js']


    # お便利プラグイン
    plugins: [
      # bowerのモジュールを読めるようにするために
      new webpack.ResolverPlugin([
        new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin('bower.json', ['main'])
      ]),

      # 指定のモジュールを予めグローバル変数としておく(後述)
      new webpack.ProvidePlugin
        $: 'jquery'
        _: 'underscore'
        Backbone: 'backbone'
    ]
src/coffee/entry.coffee
AppRouter = Backbone.Router.extend
  routes:
    'home': 'home'

  home: ->
    require('pages/home').initialize()

new AppRouter();
Backbone.history.start {pushState: true}
src/coffee/pages/home.coffee
module.exports =
  initialize: ->
    console.log('homeだよー')

extensionsで.coffeeをしているので、require('pages/home')でpages/home.coffeeを読むようになる。

外部モジュール

bowerで管理しているコンポーネントを読めるように、resolveと、webpack.ResolverPlugin.DirectoryDescriptionFilePluginを設定する。
それだけだと

test.coffee
$ = require('jquery')

みたいな形で読み込むことになり面倒なので、上記を勝手に行うProviderPluginを導入している。

感想

最初はまったか?と思ったが、resolveまわりが頭に入ってきたらなんとかなった気がしてきた。Gruntとかぶってる点が多いのが気になる(小並感)

TODO

非同期読み込みを試す

参考

http://webpack.github.io/docs/configuration.html#resolve
https://github.com/webpack/webpack-with-common-libs
http://ameblo.jp/ca-1pixel/entry-11884453208.html