九保すこひ@フリーランスエンジニア|累計300万PVのブログ運営中
さてさて、私は以前から何度も開発が必要になる機能やコンポーネントをパッケージ化して次回から開発効率を上げるように心掛けています。
そのため、現在私のGitHubアカウントには150を超えるパッケージが存在していて、いわば「過去の私」が現在の開発を手伝ってくれている状況です😊✨
しかし、そうはいっても全てのパッケージが永遠に利用できるかといったらそうではなく、開発環境の変遷によってパッケージの一部に変更を加える必要がでてきたりしています。そしてその中で特に重要なのが、webpackへの移行です。
以前私はbower
というtwitte
社が開発していたパッケージマネージャを使っていましたが、現在ではすでに非推奨となってしまったためLaravel
が標準で利用しているnpm
へ変更したという経緯があります。
しかし、npm
を利用するとバンドル(全コードをひとつのファイルにする)する必要があり、通常の以下のようにコードを書いてしまうとundefined
となってしまうのです。
// my-package.js var myPackage = { testFunction() { return 'xxx'; }, testString: 'yyy' };
// そして、バンドルされたファイルを読み込んでも console.log(myPackage); // undefinedになる😅
そこで!
今回はJavaScriptの独自パッケージを webpack 向けに開発する方法をお届けします。
まずは手順から
まず独自パッケージをつくる手順を紹介します。
(すでにご存知の方は読み飛ばしてください)
- 元になるソースコードをつくる
- webpackでソースコードをブラウザに向けに統合、改変
- 新しいJavaScriptファイルを出力する
となります。
やはり(設定すればですが)ES6を使ってコードを書けたりするのでIE 11用に古い記述をする必要がなくなるのは大きいですね。
また、ひとつのファイルにまとめてくれたり、余分な改行や空白を除去してくれるので表示が早くなり、訪問ユーザー側へのメリットも大きいといっていいでしょう!
環境を整える
前提としてwebpack
は、npm
が必要ですので以下の手順でnpm
が使えるようにしておいてください。
- node.jsをインストール(公式サイト)
- npmをインストール(
npm install npm@latest -g
)
さぁ、これで開発のための環境が整いました!
独自パッケージを作る
やりたいこと
独自パッケージを作るといってもいろんなゴールがあると思うので、はじめに何がしたいかをまとめておきます。
- ES6でコードを書くけど、IE 11には対応させる
- バンドルされたコードはファイルサイズを圧縮(余分な改行や空白を除去)する
- 作成したパッケージをグローバルで呼び出せる(冒頭で書いた内容の解決)
実際に作ってみよう
では、ここから実際に独自パッケージをつくっていきましょう!
今回テストで作るパッケージ名はhello
です。
まずはどこでもいいので好きな場所に専用のフォルダをつくります。(Laravelの場合はテストしやすいのでpublic
以下がいいかもしれません)
そして、コマンドラインでhello
フォルダへ移動して以下のコマンドを実行します。
npm init -y
するとhello
フォルダ内にpackage.json
というファイルが作成されるので、以下のように必要な記述を追加してください。(太字が追加した部分です)
{ "name": "hello", "version": "1.0.0", "description": "", "main": "hello.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "webpack --mode development", "production": "webpack --mode production" }, "keywords": [], "author": "", "license": "ISC" }
※ ちなみに「dev」「production」はLaravelに合わせたものですが自由に決めることができます。そして、この場合npm run dev
とnpm run production
が実行コマンドになります。
次に必要なnpmパッケージをインストールします。(今回必要になるのは、4つですが、お好みで他のパッケージを入れたい場合もここでインストールしてください)
npm i @babel/preset-env babel-loader webpack webpack-cli --save-dev
インストールが完了すると、以下のようにnode_modules
というフォルダが作成され、この中に必要なパッケージが格納されることになります。
続いてwebpack
の設定ファイルwebpack.config.js
を作ってどういう風にファイルをバンドル(統合)&トランスパイル(改変)するかを決めます。
中身は以下のようになります。
const path = require('path'); module.exports = { entry: './src/hello.js', // このファイルが元ソースコード output: { filename: 'hello.js', // 実行後のファイル名 path: path.resolve(__dirname, 'dist'), // 絶対パスでないとエラーが出るのでこの記述にしてます library: 'hello', // helloという変数でパッケージにアクセスできるようになる libraryTarget: 'umd' // Laravel Mixで利用するなら必要 }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: [ "@babel/preset-env" // IEに対応させる(つまり古いコードに変換する) ] } } } ] } };
つまり内容としては、
src/hello.js
をIE11に対応できるコードにし、さらに余分な改行や空白を除去してdist/hello.js
というファイルを作成する
となります。
では、src
フォルダとdist
フォルダを作って元のソースコードとなるsrc/hello.js
を作っていきましょう。
今回はテストですので、次のようなシンプルなコードにします。(※ このコード自体はIE11ではエラーが発生する「ES6」形式であることに注意してください)
const hello = { japanese() { return 'おはようございます!'; } }; module.exports = hello;
では、この状態で以下のコマンドを実行してバンドルを実行してみましょう!
npm run dev
うまくいけば、以下のようにdist
フォルダにhello.js
が作成されているはずです。
では、実行が完了しましたのでtests/index.html
を作ってテストしてみましょう。
ファイルの中身に以下のようにします。
<!doctype html> <html> <body> <script src="../dist/hello.js" charset="utf8"></script> <script> console.log(hello.japanese()); </script> </body> </html>
そして、ブラウザで実行してみるとうまく実行されていることがわかります(上がGoogle Chrome、下がIE 11です。)
なお、現在の状態ではまだdist/hello.js
はサイズ圧縮(余分な改行や空白を除去)されていません。サイズ圧縮を実行する場合はproduction
の方を使ってください。
npm run production
※ つまり、開発途中は内容を確認しやすいように「devモード」を使い、完成したら「productionモード」を使うというのが通常の流れになるでしょう。
以上になります。
お疲れ様でした!
※ なお、この間公開した記事【JavaScript】日付や都道府県、通貨など日本関連のデータを扱うwafujsを公開しました!で紹介したwafujsも今回のテクニックを使ってwebpack対応したので良かったらぜひ使ってみてくださいね。
おわりに
ということで今回は webpack
で独自パッケージを作る方法を紹介しました。
ちなみに私はたくさんのパッケージを管理する必要があるので、babel
などのnpm
のパッケージを-g
でグローバルにインストールして実行するようにしてみましたが、パスが合っていないためうまくいきませんでした。
その後、解決策を2つほど見つけはしたものの「うーん、それだったらローカルにインストールしますわー😅」という状況になりました。なので、この部分に関しては今後ももっといい開発環境を探っていきたいと思います。(知ってたらぜひ教えてください!)
そして、最後に途中で作成したpackage.json
の変更例をおまけとしてつけておきたいと思います。(太字が変更箇所)
{ "name": "hello", "version": "1.0.0", "description": "A JavaScript package that allows you to try webpack.", "main": "hello.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "webpack --mode development", "production": "webpack --mode production" }, "keywords": ["test"], "author": "Sukohi Kuhoh", "license": "MIT", "devDependencies": { "@babel/preset-env": "^7.4.4", "babel-loader": "^8.0.5", "webpack": "^4.31.0", "webpack-cli": "^3.3.2" } }
皆さんのお役にたてると嬉しいです!
ではでは〜。