環境構築:macOS Mojaveにwebpackをインストール

2020-03-05 19:39

まだまだ環境構築は続く・・・か。

webpackとは、JavaScriptなどの複数のモジュールをひとつにまとめるツールです。

インストールの流れ

環境は、

Node.js バージョン 12.16.1
npm バージョン 6.13.4

package.jsonを作成

npm initコマンドでpackage.jsonを作成します。npm initコマンドを実行すると、packagpe.jsonファイルを生成するためにいくつかの入力が必要になるので、下記のコマンドのように-yをつけて実行することで問い合わせをスキップできます。

$ npm init -y

下記のようなpackage.jsonファイルが生成されます。

package.json
{ "name": "nananomae.xyz", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }

webpackをインストール

webpackはプロジェクト毎に構築したい環境が異なるだろう・・・なので、下記のコマンドでローカルにインストールします。

$ npm install webpack --save-dev

> fsevents@1.2.11 install 【プロジェクトディレクトリ】/node_modules/fsevents
> node-gyp rebuild

  SOLINK_MODULE(target) Release/.node
  CXX(target) Release/obj.target/fse/fsevents.o
  SOLINK_MODULE(target) Release/fse.node
npm notice created a lockfile as package-lock.json. You should commit this file.

+ webpack@4.42.0
added 393 packages from 216 contributors and audited 4227 packages in 17.696s

無事にインストールが完了するとプロジェクトディレクトリ配下にnode_modulesディレクトリが生成され、その中にい様々なモジュールがインストールされます。

webpack-cliをインストール

続いて、webpackコマンドでwebpackを実行するために、下記のコマンドでwebpack-cliを同じくローカルにインストールします。

$ npm install webpack-cli --save-dev

+ webpack-cli@3.3.11
added 66 packages from 31 contributors and audited 5288 packages in 4.757s

無事にインストールが完了しても、現状のままだとwebpackコマンドは実行できないため、下記のコマンドでPATHを通す必要があります。

$ export PATH=$PATH:./node_modules/.bin

webpackを実行

簡単なJavaScriptファイルを作成し、webpackを実行してみます。

エントリポイントを作成

エントリポイントとなるJavaScriptファイルを作成します。

index.js
var name = require('name.js'); console.log(name);

このスクリプトは、同階層のname.jsを読み込み、その内容をログ出力するだけの単純なスクリプトです。

読み込まれるスクリプトを作成

エントリポイントから読み込まれるJavaScriptファイルを作成します。

var name = 'nananomae'.split('');
module.exports = name;

このスクリプトは、文字列nananomaeを配列に変換して返すだけの単純なスクリプトです。

実行してみる

下記のコマンドでwebpackを実行してみます。

$ node node_modules/.bin/webpack index.js --mode=development

Hash: 3aa11f465477fdb0752f
Version: webpack 4.42.0
Time: 58ms
Built at: 2020-03-05 18:31:55
  Asset      Size  Chunks             Chunk Names
main.js  4.82 KiB    main  [emitted]  main
Entrypoint main = main.js
[./index.js] 52 bytes {main} [built]
[./name.js] 57 bytes {main} [built]

と、処理結果が表示され、プロジェクトディレクトリ配下にdist/main.jsというJavaScriptファイルが生成されています。

その生成されたファイルを下記のコマンドで実行すると

$ node dist/main.js

[
  'n', 'a', 'n',
  'a', 'n', 'o',
  'm', 'a', 'e'
]

と、予想通りの結果が表示されました。

package.jsonを編集

ただ、毎回毎回長たらしいパスを打つのも面倒臭いです。
package.jsonに記述することでnode_modules/.bin/にパスが通るのでコマンドをシンプルにできます。

package.json
"scripts": { "test": "echo "Error: no test specified" && exit 1", + "build:dev": "webpack index.js --mode=development" },

package.jsonを編集したら、下記のコマンドでwebpackを実行できます。

$ npm run build:dev

設定ファイルを導入

設定ファイルwebpack.config.jsを導入し、$ webpackコマンドの実行時の設定を読み込むようにします。

webpack.config.jsを作成

同階層にwebpack.config.jsというファイル名で、下記のような単純な設定ファイルを作成します。

webpack.config.js
module.exports = { entry: './index.js', output: { filename: 'bundle.js' } }

package.jsonを編集

package.jsonのコマンドをよりシンプルにします。

package.json
"scripts": { "test": "echo "Error: no test specified" && exit 1", - "build:dev": "webpack index.js --mode=development", + "build:dev": "webpack --mode=development" },

ここまでの設定で、下記のコマンドを実行すると、

$ npm run build:dev

index.jsの内容を開発モードでdistディレクトリにbundle.jsファイルを生成します。

実際に生成されたファイルの中身はこんな感じ

dist/main.js
/******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = "./index.js"); /******/ }) /************************************************************************/ /******/ ({ /***/ "./index.js": /*!******************!* !*** ./index.js ***! ******************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { eval("var name = __webpack_require__(/*! ./name.js */ "./name.js");nnconsole.log(name);//# sourceURL=[module]n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9pbmRleC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2luZGV4LmpzPzQxZjUiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIG5hbWUgPSByZXF1aXJlKCcuL25hbWUuanMnKTtcblxuY29uc29sZS5sb2cobmFtZSk7Il0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=n//# sourceURL=webpack-internal:///./index.jsn"); /***/ }), /***/ "./name.js": /*!*****************!* !*** ./name.js ***! *****************/ /*! no static exports found */ /***/ (function(module, exports) { eval("var name = 'nananomae'.split('');nnmodule.exports = name;//# sourceURL=[module]n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9uYW1lLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbmFtZS5qcz8zM2YyIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBuYW1lID0gJ25hbmFub21hZScuc3BsaXQoJycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5hbWU7Il0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=n//# sourceURL=webpack-internal:///./name.jsn"); /***/ }) /******/ });

これで、最も単純なwebpack環境の構築が完了しました。