普段の業務では主にサーバーサイドを担当することが多いのですが、Vue.jsとTypeScriptを使ったフロントエンドの作業を担当する機会がありましたので、10日ほどの間でざっと勉強した内容をまとめてみました。
(フロントエンドに関しては初学者のため理解の浅い部分が多々あると思います。誤り等ありましたらご指摘頂けますと大変ありがたいです)
ES5
ECMAScript5。要するに古いJavaScript。モダンなブラウザであればほとんど動作する。モジュールという概念が存在しないので、ファイルの依存関係の管理がとても大変。
CommonJS/AMD
ES5の欠点を補うため、つまりJavaScriptのコードをモジュールとして扱えるようにするために、CommonJSやAMDという仕様
が作成された。CommonJSは主にサーバーサイドでの用途を想定(node.jsもCommonJS方式)。AMDはブラウザでの使用を前提としているらしい。
// hello.js
module.exports.greet = function () {
console.log('Hello!');
};
// index.js
var hello = require('hello');
hello.greet(); // Hello!
// hello.js
define(function () {
return function greet() {
console.log('Hello!');
};
});
// index.js
define(["hello"], function (hello) {
hello.greet(); // Hello!
});
AMDに関しては、依存するモジュールの数が多くなると記述が大変になる。AMDに対応しているライブラリであるRequireJSはこの問題に対応しており、下記のような記法を使用可能。
define(function(require, exports, module) {
var hello = require('hello');
var foo = require('foo');
var bar = require('bar');
...
hello.greet(); // Hello!
});
- JavaScriptのモジュール管理(CommonJSとかAMDとかBrowserifyとかwebpack) | tsuchikazu blog
-
AMD & RequireJS - Qiita
RequireJS使い方メモ - Qiita
CommonJSは(Webpack等を使用した)ビルド時に依存関係を解決する方式だが、AMD(RequireJS)は実行時に依存関係を解決する方式である。
CommonJSはツールやライブラリではなく仕様
のため、ビルド時に依存関係を解決する何らかのツールが必要となる。それが後述するBrowserify
やWebpack
である。
AMDも仕様
のため、それに対応するライブラリが必要である。それがRequireJSであり、さらにRequireJSはAMDには存在しない便利記法を導入している。
コードの中でmodule.exports
とrequire
が使われていたらCommonJS形式、define
が使われていたらRequireJS(AMD)
と考えて良いのだが、両方にrequire
という用語が登場するので初学者にはここがちょっと分かりにくい。(学習を始めた当初は、requireというキーワードが使われていたらRequireJSが使われているのだと勘違いしていました)
最近は後述のWebpackを使ってビルド&バンドルする方式が主流になっており、AMDやRequireJSに関してはあまり使われなくなっているようなので、Webpackだけ勉強しておけば良いようである。
ES6(ES2015)
新しいバージョンのJavaScript。一部の機能はモダンなブラウザでも動作しないため、後述するbabel
等のトランスパイラ
を使用して、ES2015で記述したコードをES5に変換する方式が主流になっている。
ES6で導入された機能は色々あるが、モジュール管理用に導入されたimport/export
機能の理解と、CommonJSのmodule.exports/require
との区別が初学者にとっては重要。(Vue.jsのコードの中でも両方のキーワードが登場するので混乱するが、設定ファイル系はCommonJS方式のmodule.exports/require
、コンポーネント等のコードはES2015のimport/export
を使うと考えておけば良いと思われる)
babel
ES2015のコードをES5にトランスパイルする際に使用される。設定ファイルとして.babelrc
が使用される。
preset
という概念がある。要するに新しいJavaScriptの機能をコード内でどこまで使用可能にするか
をこれで決定するようである。(指定したpresetで対応出来ている機能であれば問題なくES5形式にトランスパイルしてくれるが、そうでなければエラーになるようである)
Vue.jsの場合はstage-2
とenv
というpresetが.babelrc
内でデフォルトで指定されている。babel-preset-stage-2
に関しては、下記の記事で記載されているような機能がES2015のコード内で使用可能になるようである。(babel-preset-env
等とは異なり、一部の最新機能だけをチェックするpresetだと思われる)
babel-preset-env
に関しては少々分かりにくいが、targets
を指定しない場合はbabel-preset-latest
と同様な挙動になるらしい。(babel-preset-latest
は、最新のES6の構文を認識してES5に変換してくれるが、ターゲットブラウザやnode.jsのバージョン等は指定出来ないので、既にほとんどのブラウザが対応済みな機能であっても全て古いES5に変換すると考えてよいらしい)
targets
で例えばターゲットブラウザとバージョンを指定した場合は、そのブラウザのバージョンが対応している機能に関しては、(機能の対応テーブルを見て)その機能に関してはコードを古くし過ぎないように変換してくれるようである。多分。
ちなみに、Vue.jsのデフォルトの.babelrc
では、babel-preset-env
に関して、下記のように"modules": false
という指定が行われている
"presets": [
["env", {
"modules": false
}],
...
],
これは何かというと、下記の記事で説明されているように、WebpackのTree Shaking
を有効にするためである。babelはデフォルトの設定だと、ES2015のimport/export
をCommonJSのmodule.exports/require
に変換してしまうので、"modules": false
を指定することでこの挙動を防止しているようである。
Browserify/Webpack
基本的には、JavaScriptモジュールやCSS等のアセットのバンドル(ファイルを一つにまとめる)を行うためのツールである。
babelはES2015からES5への変換は行うが、JavaScriptのモジュール管理システムには対応していないため、モジュール間の依存関係の解決等は別のツールが行う必要がある。それを行うのがBrwoserifyやWebpack。
Browserifyと異なり、WebpackはAMD(RequireJS)形式の記述にも対応していたり、JavaScriptに加えてCSS等のアセットのバンドル、および単一でなく複数ファイルへの出力にも対応している等の違いがあるようである。ローカルWebサーバー使用時のLive Reload的な機能も備わっている。
Vue.jsではデフォルトでWebpackが使用されるので、特別な理由が無ければWebpackだけ勉強しておけば良いと思われる。
Gulp等のタスクランナーとの違いはなにかという点に関してはいまいち理解出来ていない。タスクランナーと一緒に使うことも可能なようであるが、Vue.jsではタスクランナーは使用せずにnpm-scripts
を使用している。下記の記事にも記載されているが、タスクランナーは使わずにnpm-scripts
とWebpack
だけでタスクを管理するのが主流(?)になってきているのかもしれない。
Vue.js
ReactやAngular等と同じく、JavaScriptのフロントエンドのフレームワーク。MVVMパターンを採用している。
初学者の学習リソースとしては下記がお薦めと思われる。(ステップバイステップ形式の公式チュートリアル等があると助かるのですが、そういうものはまだ存在していないようです)
(追記:ドットインストールさんでVue.jsのバージョン2.5対応の動画が公開されましたので、初学者の方はそちらから学習するのが良いかもしれません)
(私の場合は、とりあえずVue.js入門でざっと勉強した後は、実際に手を動かしてアプリケーションを作りつつ、分からないことは逐次ネットで調べていくというスタイルで覚えていきました)
エディタとしては、TypeScriptを使うことが前提であれば、公式ドキュメントもお薦めしているVSCode
とVetur
プラグインの組み合わせが無難と思われる。
現時点ではまだTypeScript
用のscaffoldは用意されていないので、vue-cli
によるプロジェクト作成後に、独自にTypeScript化を行う必要がある。
Vue.js用のボタンやDatetimePicker等のUIライブラリに関しては、ElemeFE/elementというパッケージが広く使われているようである。
ステート管理にはVuex
というライブラリを使用する。Flux
パターンの実装であるとのこと。Redux
に似ているらしい。とりあえず下記等でざっと勉強しておけばよいと思われる。
VuexとLocalStorage
を連携させたい場合は、robinvdvleuten/vuex-persistedstateというライブラリが使える。(LocalStorage
は、こちらの記事でも記載されているように、モダンブラウザであれば基本的に問題なく使用可能なようである)
Vue.jsでSPAなBingoカードアプリを作ってみてわかったこと - Qiita
TypeScript
TypeScriptの学習リソースに関しては色々あると思いますが、私はとりあえずドットインストールさんの動画でざっと学習しました。
TypeScriptには型定義ファイル
というものが存在する。当初からTypeScriptで記述されているモジュールであれば不要だが、JavaScriptで記述されたモジュールをTypeScriptから使用するためには型定義ファイルが必要。
型定義ファイルに関しては初学者向けの学習リソースが見当たらなかったが、下記の記事をじっくりと読んで内容を理解出来れば大体オッケーではないかと思われる。
下記の記事等で説明されているようにTypeScript2からはtsd
やtypings
等の型定義ファイル管理ツールは不要になり、npmだけで型定義ファイルが使用出来るようなったようである。
Vue.jsのTypeScript化に関しては、下記のチュートリアルや記事でざっと学習すればおおよその手順は理解出来ると思われる。
Tips
Vue.jsをTypeScript化する際のwebpack.base.conf.jsの設定
module: {
rules: [
{
test: /\.ts$/,
use: [
'babel-loader',
{
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/]
}
},
{
loader: 'tslint-loader',
options: {
configFile: 'tslint.json'
}
}
],
include: [resolve('src'), resolve('test')]
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
module.exports = {
loaders: Object.assign(
{ ts: 'ts-loader!tslint-loader' },
utils.cssLoaders({
sourceMap: sourceMapEnabled,
extract: isProduction
})
),
色々な方式があると思われるが、とりあえず上記のような設定を採用した。
この設定の場合、*.ts
ファイルに関するローダーはtslint-loader -> ts-loader -> babel
の順に適用される。
ts-loader
のappendTsSuffixTo
の部分は、*.ts
ファイルと*.vue
ファイルの依存関係を解決する際に必要なようである。ts-loader
以外にbabel-loader
も使っている理由は、ts-loader
ではES5
までの変換は行わずにES6
までの変換だけを行って、ES6
からES5
への変換はbabel
を使用したいため。
vueLoaderConfig
変数にはvue-loader-conf.js
の中身が適用されますが、ここで{ ts: 'ts-loader!tslint-loader' }
を指定することで、*.vue
ファイル内のTypeScriptの部分にもtslint-loader
とts-loader
が適用される(はず)。
本文中に記載されていない参考資料
- ES2015(ES6)な時代だからこそ、ES5を改めて調べたJavaScript初級者のメモ - Qiita
- ES5とES6の違いをまとめてみた(メモ) - Qiita
- ES6の概要と、最新ブラウザに対応させる「Babel」の使い方 | ES6のある星に生まれて
- JavaScriptのモジュールシステムに関するまとめ - Qiita
- JavaScriptのモジュールシステムの歴史と現状 - Qiita
- いまどきなフロントエンド開発者になる!JSのモジュール管理ってこういうこと - WPJ
- フロントエンド開発の基本知識(2017年夏) - Qiita
おまけ
Youtubeの方で、ITエンジニアやIT業界に興味のある方たち向けの雑食系エンジニアTVというチャンネルを始めました。もしご興味ございましたらチャンネル登録してみて頂けると大変嬉しいです(^.^)