search
LoginSignup
3

More than 3 years have passed since last update.

posted at

updated at

すごくカンタンなSSR with Vue.js - 実践1. ビルド環境

「御託はいいからやり方だけ教えてくれ」というあなたは → 実践 - 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. ビルド環境

webpackbabelを使用して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

iinstall-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.jsmain.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は自動でmodeproductionに設定し、その旨の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を参照しています。

次にwebpackbabelを使うように、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');

/***/ })

constvarに、(message) => { ... }function greet(message) { ... }に変換されています。
これでESNextが書ける環境が整いました。

babelの機能やbabel-loaderの設定について、より詳しく知りたい場合は以下を参照してください。

最後に、ビルドコマンドをnpm scriptsに登録しておきましょう。
package.jsonscriptsに以下を追記します。

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

実践2. SPA

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
3