このブログははてなブログからの移行記事です。

やりたいこと

お仕事でページごとに必要なモジュールのみimportしたJSを実装し、それぞれコンパイルしたいという場面があった。

イメージ的にはsrc/(pc|sp)/**/*.jsをフォルダ構成やファイル名をそのままpublic/js配下に吐きだすといった感じ。

Webpackは基本的に複数ファイルをよしなに1ファイルにバンドルするものなので結構情報が少なくて詰まったのでメモっておく。

実装方針

Webpackでは複数ファイルをコンパイル対象として、それぞれ特定フォルダに吐き出すといったことをサポートしている。

multiple entry points

公式からコードを引用するとこんな感じ。

{
    entry: {
        a: "./a",
        b: "./b",
        c: ["./c", "./d"]
    },
    output: {
        path: path.join(__dirname, "dist"),
        filename: "[name].entry.js"
    }
}

こんな感じで頑張ってentryに書いていってもいいんだがこれだと2つ問題がある。

  • ファイルが増えれば増えるほど自分で書き足していかなきゃいけない
  • entryのkey名でファイルが吐きだされるのですべてoutputで定義されたフォルダに吐き出される

2つ目の問題この記事がわかりやすく説明してくれてる。

webdesign-dackel.com

この記事ではファイルがそこまで多くない想定なので手でentryの項目を書いているが、私のケースだとファイルが大量にあったので以下の方針で設定を試みた。

  • globを使ってコンパイル対象のファイルを全て取得する
  • globで取った配列からoutputを基準として出力してほしいフォルダ + ファイル名をkey, コンパイル対象のファイルパスをvalueとした連想配列を作る
  • それをentryに渡す

コード

要するにこんな感じです。

この例はsrc/pc/*.jssrc/sp/*.jspublic/js/配下にフォルダ構成そのままに出力する例です。

import webpack from 'webpack';
import path    from 'path';
import glob    from 'glob';

const jsBasePath = path.resolve(__dirname, 'src/');
const jsCompileFolders = ['pc', 'sp'];

const targets = glob.sync(`${jsBasePath}/+(${jsCompileFolders.join('|')})/*.js`);
const entries = {};
targets.forEach(value => {
  const re = new RegExp(`${jsBasePath}/`);
  const key = value.replace(re, '');
  entries[key] = value;
});

export default {
  entry: entries,
  output: {
    path: path.join(__dirname, 'public/js'),
    filename: '[name]',
  },
}

色々省略してますが、まずはコンパイル対象のフォルダを取る部分。

const targets = glob.sync(`${jsBasePath}/+(${jsCompileFolders.join('|')})/*.js`);

ここで同期処理でコンパイルしたいJSファイルの一覧を取ってきてます。 これを{[outputを基準として吐き出したいフォルダ+ファイル名]: [コンパイルするファイル]}となるkey-valueをここで作ります。

const entries = {};
targets.forEach(value => {
  const re = new RegExp(`${jsBasePath}/`);
  const key = value.replace(re, '');
  entries[key] = value;
});

もっといい方法ありそうなんですが、愚直にkey-valueをオブジェクトに突っ込んでるだけです。 あとはこれをwebpackのconfigに渡して終わり。

サンプルコード

超必要最低限書いたサンプルコード置いておきます。

github.com

まとめ

webpack楽しいぞい