CEP向けのwebpack構築-Sass babel-
webpackについては何度か触れましたが今回もっと深く触れたいと思います。webpackの役割はいくつかのファイルに分割されたjsファイルを一つにまとめるツールです。コードが複雑化するにつれファイル、一つあたりのコードが長くなって読みづらくなったり変数の管理が大変になります。なので各モジュールに役割事にコードを分割してメインのjsファイルで読み込ませる事で読みやすく、管理のしやすいコードが実現できます。まとめるついでにjsのコードを古いECMAに変換したりsassをcssに変換してモダンなコード書きつつ古いブラウザに対応させることが可能です。ReactやVueを使用する場合もこういった変換作業が必要ですね。ただ今回はとりあえずCEP向けにwebpackを使用する記事です。目的として。
-
sassの使用。
-
cssにベンダープレフィックスをつける。
-
最新のjsのコードを書きつつ古いCEP環境でも動くようにする。
-
完成時のコードのサイズを軽くする。
です。ある程度初歩の話は飛ばすので一番初歩の段階から始めたい場合はこちらのサイトが参考になると思います。
とにかくnpm init -y でpackage.jsonを用意したらパッケージをインストールします。
webpackの基本のパッケージになります。次にbabel。このbabelがjsのトランスパイルの役割を果たしてjsを古いバージョンに落としてくれます。
次にsass関連。sassで書いてcssに変換してくれるようにします。
ちなみに今回はcssも画像ファイルもjsに一括でまとめます。勿論画像まで全てjsにまとめるやり方は違和感もありますが全てローカルで動くExtensionの場合はいちいちcssとか画像ファイルとか別個に書き出したりするよりも一括してまとめた方が管理しやすいだろうという安易な考えです。ちなみに私は普段はcssも画像も別個にする派です。web siteを作成する場合jsの読み込みが遅れるとCSSで作成したローディング画像まで表示が遅れたり全体的に若干重たくなった気がしたのでその流れでExtension開発も別個にするようにしました。その他websiteを作る場合httpリクエストを減らすした方が負担が減るらしいです。私もよくわかっていませんがこの辺はExtension上では関係なさそうですね。
話がそれましたが今回全てのパッケージをdevDependenciesでインストールしました。これはwebpack関係はあくまで開発時に必要なだけで本番の時には不要になるためです。本番時も必要なパッケージは-Dを省いてdependenciesでインストールしてください。それではwebpack.config.jsに設定を書いてゆきます。
modeは開発中か、本番中かで変わります変数の値を変えます。開発中ならdevelopmentに、本番時はproductionを設定します。developmentに設定するとソースコードをデバッグ時に見れたりproductionだとサイズが軽くなったりします。devtoolはsource-mapを設定するとデバッグ時にソースコードを確認できます。targetは一応Nodeが動く環境なのでnodeにしていますがnode-webkitの方が適格な気もします。CEP自体がnode-webkiベースらしいので。デフォルトだとwebになっているのでNodeも動かす環境で開発する場合は必ず設定できます。詳しくはここから確認してください。electronはjsとhtmlとcssでネイティブアプリが開発できるツールです。これもいつか触れてみたいです。それで次にcontextに触れる前に各種ファイルのディレクトリー関係がどうなっているか確認します。
srcフォルダーの中にjsフォルダーとstylesフォルダーとimagesフォルダーがあります。このsrcフォルダーが開発ファイルを格納するフォルダーとなり、この中のファイルをwebpackで一つにまとめます。なのでこのsrcフォルダーをコンパイルのメインのパスに設定します。そのためのcontextです。context:path.resolve(__dirname,”src”)でこのwebpack.config.jsと同じ階層にあるsrcフォルダーがベースのディレクトリーになるように設定します。次にどのファイルがコンパイルの対象になるか設定します。それが entry:”./js/main.js”です。srcフォルダーから見て相対パスでmain.js
を指定しています。今回はscssファイルもこのmain.js経由で取り入れます。複数ファイルの設定もできますが今回は一ファイルだけ対象にします。outputにまとめたjsファイルの出力先を設定します。pathにベースとなるディレクトリーを選択してnameで書き出し後のファイル名を設定します。[name]で元のファイル名を設定できます。その他[ext][path]等詳しくはドキュメントを。
これで基本の設定は終わりましたがまだloaderの設定があります。
一気にコードが増えました。このloaderの設定でsass、jsのコンパイルの設定をするのでここも重要です。rulesの中にcss-loaderやtestのプロパティがありますがtestにコンパイルの対象ファイルを正規表現で指定、loaderがコンパイルの内容になります。(css-loaderの場合はcss関係のコンパイル)ちなみに各種loaderもnpmで既にインストールしています。さらにcss-loaderの場合はsassのコンパイルとベンダープレフィックスの処理も含まれるためより詳細なオプションを付けていきます。各種optionsのsourceMapはソースコードが見れるようにするか否かのオプションです。develop時はtrueにします。postcss-loaderにはさらにgrid-layoutも古い環境に対応させるためにプラグインのautoprefixerでgridのオプションを加えています。url-loaderはcss内の画像をjsに取り込むためのloader、なのでtestには画像ファイルの拡張子を指定。babel-loaderは最新のECMAで書かれたjsをECMA5に落とすためのloaderです。jsの拡張子が対象になっています。style-loaderは実際にcssを展開するloaderなのでこれがないとcssが適用されません。ここまでやったらさらにメインとなるjsファイルにpollyfillとsassファイルをimportします。
polyfillは@babel/polyfillモジュールをインストールしていればモジュール名をimportするだけです。sassはhtmlではなくメインのjsファイルにimportしてください。これで書き出してみます。
これで実際にjsを出力するとこのようになります。
distフォルダーにハンドルされたjsが出力されました。後はこれをhtmlに読み込むだけでsassのcssもimages内の画像ファイルもjsファイル内にハンドルされているので適用されます。全て一つのファイルにまとまっていると出力後のファイルの管理も楽なのでExtension向けはこれで良いでしょう。正直個人的にちょっと気持ち悪いですが。それで基本はこれで終わりなのですがここからさらにnpmパッケージを本番環境でも使用したりjsファイルをさらに圧縮する場合はまだ十分ではありません。という事でまずNode.jsのモジュールライブラリも使用することを前提にwebpack-node-externalsプラグインをインストール。
#2020年10月24日追記 webpack-node-externalsプラグインを使用するとパッケージ時に正常に読み込まれなかったので一度この項目を削除します。再度よく調べます。申し訳ありません。
そしてもひとつ重要なのがterser-webpack-plugin。オプションを設定する事で本番のパッケージを出力時にファイルのサイズを小さく纏めてさらに不要なコメントやconsole.logも外してくれます。
以上のプラグインも反映させた結果が以下
これで本番ファイルの出力も綺麗にファイルサイズを小さくしてくれます。とりあえずsass、babel使用の全てjsに同梱させるやり方なのでまだシンプルな方かもしれません。同じ設定でもwebpackのバージョンが上がると求められるパッケージの種類が増えたりするので注意。typescriptの場合なんかもまた変わってきますが次回。