リンク
前回は
サンプルソースを落として開発環境を構築、起動までを確認しました。
今回は開発環境で使う開発ツールのパッケージマネージャ(npm) タスクランナー(gulp) モジュール管理(webpack)の説明をします。
ソースはこちら
github
パッケージマネージャ
npm
ちょっと前まではbowerなどありましたが、今はこれが主流かなと。
npmで必要なファイルはpackage.jsonとなります。
package.jsonには開発、実行時に使用するライブラリが明記されていて、npm installを実行するときに使います。
実行するとnode_modulesにjsやscssなどのファイルをどこかしらからダウンロードします。package-lock.jsonも同時に生成されます。package-lock.jsonについてはとりあえず、なにかあるなぁくらい認識で。
{
"name": "project-base3",
"version": "1.0.0",
"description": "",
"main": "main.js",
"author": "",
"license": "",
"devDependencies": {
"babel-core": "6.21.0",
"babel-loader": "6.2.10",
"babel-preset-es2015": "6.18.0",
"css-loader": "^0.28.10",
"del": "^2.2.2",
"gulp": "3.9.1",
"gulp-cssimport": "^5.0.0",
"gulp-uglify": "2.0.0",
"gulp-rename": "^1.2.2",
"gulp-sass": "3.1.0",
"gulp-minify-css": "^1.2.4",
"require-dir": "0.3.0",
"run-sequence": "1.2.2",
"sass-loader": "^6.0.6",
"style-loader": "^0.20.2",
"ts-loader": "1.3.1",
"typescript": "2.2.1",
"vue-class-component": "5.0.1",
"vue-loader": "12.0.4",
"vue-template-compiler": "2.3.3",
"vue-template-loader": "0.3.1",
"webpack": "2.2.0",
"webpack-dev-middleware": "1.9.0",
"webpack-dev-server": "2.3.0",
"webpack-hot-middleware": "2.15.0",
"webpack-stream": "^3.2.0"
},
"dependencies": {
"babel-polyfill": "6.23.0",
"bulma": "0.6.1",
"isomorphic-fetch": "2.2.1",
"url-search-params-polyfill": "2.0.0",
"vue": "2.3.3",
"vue-router": "2.5.3",
"vuex": "2.3.1",
"vuex-router-sync": "4.2.0"
}
}
devDependenciesは開発及びビルド時にdependenciesは実行時に必要となるファイルを明記します。
ライブラリを追加したい場合は以下のコマンドを実行します。
$ npm install bulma --save
$ npm install webpack --save-dev
--save,--save-dev(オプション)を追加するとpackage.jsonに追加されます。
--saveはdependenciesに、--save-devはdevDependenciesにそれぞれ追加されます。
タスクランナー
gulp
grunt、webpackでも代用ではありますが、今回はgulpで。
gulpfile.jsファイル
タスクを記述していきます。
タスクにはwebpack dev serverの起動、ビルドなどがあります。
var requireDir = require('require-dir');
var runSequence = require('run-sequence');
requireDir('./gulp/tasks', { recurse: true });
var gulp = require('gulp');
gulp.task('default', ['webpack-dev-server']);
gulpのタスク
defaultしかないのでわかりにくいですが、
この例の場合、タスク(gulp)は以下のように指定できます。
$ gulp
$ gulp default
webpack dev serverが立ち上がります。
└── gulp
└── tasks
└── webpack-dev-server.js
webpack dev serverの設定
設定はwebpack-dev-server.jsに記述していきます。
var gulp = require('gulp');
var webpack = require("webpack");
var WebpackDevServer = require("webpack-dev-server");
var webpackConfig = require('../../webpack.config.js');
var compiler = webpack(webpackConfig);
gulp.task('webpack-dev-server', function(callback) {
new WebpackDevServer(compiler, {
contentBase:"webRoot",
publicPath: webpackConfig.output.publicPath,
hot: true,
historyApiFallback: true
}).listen(3000, "localhost", function(err) {
if(err) throw new gutil.PluginError("webpack-dev-server", err);
callback();
});
});
軽く説明すると、contentBaseでルートディレクトリ(今回はwebRoot)を指定します。
実装するソースはTypeScript、SASSとなりますが、そのままではブラウザでは判読できないので、
javascript、cssにコンパイルしてからブラウザで読ませます。
開発時はコンパイルされたファイル(javascript、css)をwebpack dev server内のメモリ上に作成されて、物理的には作成されません。
その際のwebpack dev serverからの出力先をpublicPathで指定します。
今回の場合は以下のように出力されます。
http://localhost:3000/public/main.min.js
http://localhost:3000/public/style.min.js
historyApiFallbackがポイントです。
この設定がSPA環境、vue-routerでHTML5 historyモードで動作させるために必要な設定です。
この設定をすることで
http://localhost:3000/
http://localhost:3000/sample-button/
でアクセスしても同じwebRoot/index.html
を参照します。
本番環境ではwebpack dev serverを使わず、nginxやspring mvc等でfallbackの設定するかと思います。
nginxの場合は。
location / {
root /usr/share/nginx;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
spring mvcの場合は。
@Controller
@RequestMapping(value="/**")
public class StartController extends BaseController {
}
詳しくはVue Router HTML5 History モードを参照してください。
webpack dev serverの設定
webpack dev serverの設定はwebpack.config.jsに記述しています。
const webpack = require('webpack');
var path = require('path');
var config = {
devtool: "source-map",
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].min.js',
publicPath: "/public/"
},
resolve: {
extensions: [".ts", ".vue", ".js"],
modules: ['node_modules', 'src/main/html', 'src/main/js', 'src/lib/js', 'src/main/ts', 'src/lib/ts'],
alias: {
vue: 'vue/dist/vue.common.js'
}
},
module: {
rules: [
{
test: /\.vhtml$/,
loader: 'vue-template-loader'
},
{
test: /\.scss$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
}
]
},
{
test: /\.ts$/,
use: [
{
loader: 'babel-loader'
},
{
loader: 'ts-loader'
}
]
}
]
},
plugins:[
new webpack.LoaderOptionsPlugin({
debug: true
}),
new webpack.HotModuleReplacementPlugin()
]
};
config.entry = {
//mainファイルを作成する。複数作れば複数作られる。
main: [
'babel-polyfill',
'isomorphic-fetch',
'url-search-params-polyfill',
"webpack-dev-server/client?http://localhost:3000",
"webpack/hot/dev-server",
"./src/main/ts/main.ts"
],
style: "./src/main/ts/style.ts"
};
module.exports = config;
source-map
source-mapは出力されたjavascriptからTypeScriptのファイルをデバッグするために使われます。
これでChromeやintellij(web storm)でTypeScriptファイルをデバッグできるようになります。
entry
TypeScriptのルートファイルを指定したらそのファイルを元にJavaScriptを作成します。
今回はmainのみになります。
test
testは一致したファイル(この場合は拡張子が.tsのもの)に各種loaderを当てていきます。
test: /\.ts$/,
use: [
{
loader: 'babel-loader'
},
{
loader: 'ts-loader'
}
]
ts-loader、次にbabel-loaderを使ってコンパイルします。
これでTypeScript->ES2015->ES5となります。
HotModuleReplacementPlugin
HotModuleReplacementPlugin はファイルを保存するたびにリロードするかと思いますが、画面全体をリロードするのではなく、修正したファイルのみリロードするようになります。
ささっとタスクランナーの説明をしました。
ビルドについてはまた後で説明します。
とりあえず、開発用までです。
jQueryから脱出したい人のためのなんとなくなフロント開発入門5(ビルド編)
モジュール管理
JavaScriptのモジュール管理とはブラウザのJavaScript(ES5)ではJavaScriptから別のJavaScriptを呼ぶ仕組みがないので、その仕組みを補うのがモジュール管理かなと。
今回はモジュール管理はwebpackを使います。
トランスパイル
.babelrc
.babelrcはBabelの設定ファイルです。
es2015でjavascript(今回はTypeScript)を書きますよ。的なやつです。
{
"presets": ["es2015"]
}
tsconfig.json
tsconfig.jsonはTypeScriptの設定ファイルです。
{
"compilerOptions": {
"target": "es2015",
"experimentalDecorators": true,
"sourceMap": true,
"allowSyntheticDefaultImports": true,
"lib": [
"dom",
"es5",
"es2015.promise"
],
"module": "es2015",
"moduleResolution": "node"
}
}
TypeScriptをes2015で出力しますよかな。
TypeScriptでvueを使う場合の設定方法がTypeScript のサポートに書いてあります。
終わりに
開発ツール編はとりあえずここまでで。
まだ本題の実装に入っていません。
環境構築だけで相当な労力を使います。
初めての人はここまででも大変かと思います。