「御託はいいからやり方だけ教えてくれ」というあなたは → 実践 - Vue.jsでSSR
この記事は
別途私が書いている実践 - Vue.jsでSSRに、割とどうでもいい私の感情を交えながら、いくつかのパートに分けて書いていく実践形式のSSR with Vue.js説明記事です。
実際の開発フローに沿って、なるべく予備知識がなくても読み進められるように心がけています。
実践1. ビルド環境 ← 当記事
実践2. SPA
実践3. SSR
誰に役立つ?
私のような
- フロントエンジニアなりにSSRの実際のやり方を知りたくてググったのに概念的なものしか見つけられない
検索能力の低い人 - 意を決してサーバサイドレンダリング — Vue.jsを通してやったのに、途中から「あれ、なんか違う」ってなって結局出来なかった
理解力の低い人 - 概要をザクッと知ってあとは自分流にやっていきたい人
ゴール
SSR環境を構築でき、拡張することができる
- 極シンプルなSSR環境を構築します
- ジェネレータ的なものは使わず、全体の概要を理解しながら進めていきます
はじめに
Node.jsがインストール済みであるか確認してください。
ここでは現時点での安定板v8.12.0
を使用していきます。
続いて、任意のディレクトリでnpm init -y
を実行してpackage.json
を生成しておきます。
それではいきましょう。
実践1. ビルド環境
webpack
・babel
を使用してESNextが書ける環境を構築します。
ビルド対象となるファイルをsrc/index.js
として生成しておきましょう。
確認用にESNextのconst
とアロー関数
を使用します。
src/index.js
const greet = (message) => {
console.log(message);
};
greet('Hello');
webpack
webpack
をインストールします。
npm i -D webpack webpack-cli
i
はinstall
、-D
は--save-dev
のエイリアスです。
続いて設定ファイルを作成します。
webpack.config.js
という名前のファイルを作成します。
これはwebpack
が自動で読み込んでくれる特別な名前です。
webpack.config.js
const path = require('path');
const config = {
entry: path.join(__dirname, 'src/index.js'),
output: {
filename: 'main.js',
path: path.join(__dirname, 'dist')
}
};
module.exports = (env, argv) => {
switch (argv.mode) {
case 'production':
// expand config for production
break;
case 'development':
default:
// expand config for development
config.devtool = 'inline-source-map';
break;
}
return config;
};
src/index.js
をmain.js
という名前でdist
ディレクトリにビルドするだけの設定です。
entry: path.join(__dirname, 'src/index.js'),
output: {
filename: 'main.js',
path: path.join(__dirname, 'dist')
}
module.exports
では単にオブジェクトを返すこともできますが、関数を返すことによって実行時の環境(env
)や引数(argv
)を受け取ることができ、環境ごとの設定をすることが可能になります。
module.exports = (env, argv) => {
// ここで環境ごとの設定をする
// 最後に設定内容を返すことを忘れずに
return config;
}
今回は開発環境でのみソースマップを追加するように設定しています。
case 'development':
default:
// expand config for development
config.devtool = 'inline-source-map';
break;
require('path')
や__dirname
はNode.jsで使える特別なモジュール・変数です。
ここでは述べませんが、興味のある方はNode.jsドキュメントを参照してください。
それでは、一度ビルドを実行してみましょう。
npx webpack --mode=development
npx
はローカルにインストールされているnode_modulesを実行できる、npm
に付随する便利なコマンドです。
以下のようなメッセージが表示され、dist/main.js
というファイルが生成されれば成功です。
Hash: c1504f90d90b13c36b96
Version: webpack 4.20.2
Time: 78ms
Built at: 2018-10-09 11:22:46
Asset Size Chunks Chunk Names
main.js 3.84 KiB main [emitted] main
Entrypoint main = main.js
[./src/index.js] 72 bytes {main} [built]
dist/main.js
を確認してみましょう。
ファイル下部に以下のような記述が確認できます。
/***/ "./src/index.js":
/*!**********************!*\
!*** ./src/index.js ***!
\**********************/
/*! no static exports found */
/***/ (function(module, exports) {
const greet = (message) => {
console.log(message);
};
greet('Hello');
/***/ })
const
やアロー関数
がそのままビルドされているのがわかります。
まだESNextをコンパイルする設定をしていないため、これで問題ありません。
今現在のディレクトリ構成を確認しておきます。
root
|- /dist
|- main.js
|- /node_modules
|- /some_modules
|- /src
|- index.js
|- package.json
|- package-lock.json
|- webpack.config.js
ところで、ちらほら出現しているmode
とは何でしょうか。
これはwebpack
にビルドの方法を指定するもので、mode=production
とすれば本番環境に適した形でビルドをしてくれます。
オプションmode
を省略した場合、webpack
は自動でmode
をproduction
に設定し、その旨のWARNINGをコマンドライン上に表示します。
試しに以下のコマンドの実行して、コマンドライン上の表示やビルド結果を確認してみてください。
npx webpack
ここまでの実践内容で不明な点があった、またwebpack
についてより詳しく知りたい場合は公式ガイドを参照してください。
babel
babel
を使用してESNextをコンパイルする設定をしていきましょう。
必要パッケージをインストールします。
npm i -D babel-loader @babel/core @babel/preset-env
続いて設定ファイル.babelrc
を作成します。
.babelrc
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}
]
]
}
この設定によって、browsers
で指定した環境でもJavaScriptが動作するようにコンパイルされます。
なお、設定値はvuejs-templatesを参照しています。
次にwebpack
でbabel
を使うように、webpack.config.js
に追記します。
webpack.config.js
const path = require('path');
const config = {
entry: path.join(__dirname, 'src/index.js'),
output: {
filename: 'main.js',
path: path.join(__dirname, 'dist')
},
// ここを追加
module: {
rules: [
{
test: /\.m?js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}
]
}
};
これで拡張子.mjs
またはjs
のビルドにはbabel
の設定が適応されます。
それでは、ビルドを実行してみましょう。
npx webpack --mode=development
dist/main.js
のファイル下部を見てみます。
/***/ "./src/index.js":
/*!**********************!*\
!*** ./src/index.js ***!
\**********************/
/*! no static exports found */
/***/ (function(module, exports) {
var greet = function greet(message) {
console.log(message);
};
greet('Hello');
/***/ })
const
がvar
に、(message) => { ... }
がfunction greet(message) { ... }
に変換されています。
これでESNextが書ける環境が整いました。
babel
の機能やbabel-loader
の設定について、より詳しく知りたい場合は以下を参照してください。
最後に、ビルドコマンドをnpm scriptsに登録しておきましょう。
package.json
のscripts
に以下を追記します。
package.json
{
...,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build:prod": "webpack -p",
"build:dev": "webpack --mode=development"
},
...
}
npm scriptsではnpx
なしでもローカルにインストールされたnode_modulesの実行が可能です。
webpack
にオプション-p
を指定すると、自動的にproduction
モードに設定され、コード圧縮も実行されます。
以下のコマンドを実行して、それぞれのビルド結果を確認してみてください。
# 本番用
npm run build:prod
# 開発用
npm run build:dev
現在のディレクトリ構成は以下のようになっています。
root
|- /dist
|- main.js
|- /node_modules
|- /some_modules
|- /src
|- index.js
|- .babelrc
|- package.json
|- package-lock.json
|- webpack.config.js