webpack + Vue
自分用メモ
はじめに
webpackはモジュールバンドラーである。エントリーポイントに設定したjsファイルを中心に、各モジュールのjsファイルを纏めてバンドル
- モジュール管理できるため機能ごとに開発ができ保守性が上がる
- 複数のjsファイル(cssや画像も)を一つのファイルにbundleできるためリクエスト数減少とパフォーマンス向上
※ ファイルサイズの増大によるパフォーマンス低下もありうる - 依存関係の解消
1. webpack使用の下準備
1.1. webpackでの基本的なパッケージのインストール
$ npm init -y
$ npm i -S vue
# .vueファイルを読み込むために必須
$ npm i -D vue-loader vue-template-compiler
$ npm i -D webpack webpack-cli
$ npm i -D terser-webpack-plugin optimize-css-assets-webpack-plugin
# .vueファイルではCSSも扱うので必須
$ npm i -D node-sass css-loader
$ npm i -D babel-loader @babel/core @babel/preset-env
# 分割したcssの読み込みをリロードしない(brouser-sinc代用)
$ npm i -D webpack-dev-server
# gulp使うとき
$ npm i -D gulp gulp-eslint gulp-notify gulp-plumber
1.2. package.jsonの編集
package.json
{
"name": "webpack_test",
"version": "1.0.0",
"description": "",
- "main": "index.js",
"scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
// sassも監視対象
+ "build:dev": "webpack --mode development --watch",
+ "build": "webpack --mode production",
// dev-serverだけだとjsの監視はされるが、バンドルはされない
// 保存すると自動リロードがかかるため更新はされるが、監視よりも遅いため二回目リロード時にバンドルが反映される
+ "start": "webpack --mode development --watch & webpack-dev-server",
},
"scripts": {
},
+ "private": true,
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"jquery": "^3.4.1"
},
"devDependencies": {
"@babel/core": "^7.4.5",
"@babel/polyfill": "^7.4.4",
"@babel/preset-env": "^7.4.5",
"autoprefixer": "^9.6.0",
"babel-loader": "^8.0.6",
"css-loader": "^3.0.0",
"mini-css-extract-plugin": "^0.7.0",
"node-sass": "^4.12.0",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"terser-webpack-plugin": "^1.3.0",
"webpack": "^4.35.2",
"webpack-cli": "^3.3.5",
"webpack-dev-server": "^3.7.2"
}
}
1.2. webpack.config.jsの作成
webpackをインストールしたらwebpack.config.js
を手動で作成
webpack.config.js
// 開発or本番モードの選択(development、production、noneのいずれか設定必須)
// development: 開発時のファイル出力のモード(最適化より時間短縮,エラー表示などを優先)
// production: 本番時のファイル出力のモード(最適化されて出力される)
const MODE = "development";
// ソースマップの利用有無(productionのときはソースマップを利用しない)
const enabledSourceMap = MODE === "development";
// ファイル出力時の絶対パス指定に使用
const path = require('path');
// プラグイン
// js最適化
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
// エントリーポイント(メインのjsファイル)
entry: './src/js/app.js',
// ファイルの出力設定
output: {
// 出力先(絶対パスでの指定必須)
path: path.resolve(__dirname, 'dist/js'),
// 出力ファイル名
filename: "bundle.js"
},
mode: MODE,
// ソースマップ有効
devtool: 'source-map',
// ローダーの設定
module: {
rules: [
{
test: /\.css$/,
use: ["vue-style-loader", "css-loader"]
},
{
test: /\.vue$/,
loader: "vue-loader"
},
{
// ローダーの対象 // 拡張子 .js の場合
test: /\.js$/,
// ローダーの処理対象から外すディレクトリ
exclude: /node_modules/,
// Babel を利用する
loader: "babel-loader",
// Babel のオプションを指定する
options: {
presets: [
// プリセットを指定することで、ES2019 を ES5 に変換
"@babel/preset-env"
]
}
}
]
},
// import 文で .ts ファイルを解決するため
resolve: {
// Webpackで利用するときの設定
alias: {
vue$: "vue/dist/vue.esm.js"
},
extensions: ["*", ".js", ".vue", ".json"]
},
plugins: [
// Vueを読み込めるようにするため
new VueLoaderPlugin()
],
// mode:puroductionでビルドした場合のファイル圧縮
optimization: {
minimizer: production
? []
: [
// jsファイルの最適化
new TerserPlugin({
// すべてのコメント削除
extractComments: 'all',
// console.logの出力除去
terserOptions: {
compress: { drop_console: true }
},
}),
]
},
// js, css, html更新時自動的にブラウザをリロード
devServer: {
// サーバーの起点ディレクトリ
// contentBase: "dist",
// バンドルされるファイルの監視 // パスがサーバー起点と異なる場合に設定
publicPath: '/dist/js/',
//コンテンツの変更監視をする
watchContentBase: true,
// 実行時(サーバー起動時)ブラウザ自動起動
open: true,
// 自動で指定したページを開く
openPage: "index.html",
// 同一network内からのアクセス可能に
host: "0.0.0.0"
}
};
2. webpackの処理対象となるjsファイルの書き方
エントリーポイントとなるjsファイルをapp.js
モジュールファイルをmodule1.js
とすると次のように書く
jsファイル内でVue.component()
などのメソッドで作る場合と、.vue
拡張子の単一ファイルコンポーネントで作る場合がある
以下はコンポーネントごとに.vue
拡張子で作るときである
app.js
import Vue from 'vue';
// コンポーネントファイルがある場合
import App from './components/App.vue';
./components/App.vue
// 関数を定義。
index.html
<!DOCTYPE html>
<html lang="ja" dir="ltr">
<head>
<meta charset="utf-8">
<title>webpack_sample</title>
<link rel="stylesheet" href="./dist//css/main.css">
</head>
<body>
//
<script src="./dist/js/bundle.js"></script>
</body>
</html>
3. webpack実行
実行コマンド
package.json
のscripts
で設定した名称で実行
$ npm run build:dev # バンドル(開発用)実行
$ npm run build # バンドル(本番用)実行
$ npm run start # バンドルと監視スタート