webpackさわる

環境は webpack 2.2.1。

コード分割

アプリケーション用のjs (app.js)と、ライブラリをまとめたjs (vendor.js)を分割させたい場合。

webpack.config.js

var path = require('path');
var webpack = require('webpack');
module.exports = {
  entry: {
    app: './src/app',

    // ここで設定したライブラリは、利用していなくても読み込まれるので注意
    vendor: [
      'lodash',
      'moment-timezone',
    ]
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: "[name].js",
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: Infinity
    })
  ]
};

動的読み込み

  • require.ensureを使えばおk
  • 古めのブラウザに対応させる場合、PromiseのPolyfillが必要なので注意
    • e.g. import 'es6-promise/auto';
  • オフィシャルドキュメント

webpack.config.js

var path = require('path');
var webpack = require('webpack');
module.exports = {
  entry: {
    app: './src/app',
  },
  output: {
    path: path.resolve(__dirname, 'dist'),

    // webpack.js.org/guides/code-splitting-require/#example
    // > output.publicPath is an important option when using code-splitting, it is used to tell webpack where to load your bundles on-demand, see the configuration documentation.
    publicPath: '/app/',

    filename: '[name].js',
    chunkFilename: '[name].js'
  }
};

app.js

// a.jsとb.jsを読み込む
// require.ensureはPromiseを返す
require.ensure(['./a', './b'], require => {
  // a.jsを実行
  // (requireしていないので、b.jsは実行されないまま)
  require('./a');
  console.log('loaded');
}, 'chunk');

TypeScriptを使う場合はrequireを定義する必要がある

// https://github.com/TypeStrong/ts-loader#loading-other-resources-and-code-splitting
declare var require: {
  <T>(path: string): T;
  (paths: string[], callback: (...modules: any[]) => void): void;
  ensure: (paths: string[], callback: (require: <T>(path: string) => T) => void) => void;
};

その他

moment読み込み時に全てのlocaleファイルを読み込んでしまう

  • ContextReplacementPluginを利用して回避
var webpack = require('webpack');
module.exports = {
  // ...
  plugins: [
    // moment/locale/ja.jsのみ読み込み
    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /ja/)
  ]
};