目的
- Web Frameworkで使うことを前提として
ES6
,Sass
をトランスパイルする。 - フロント開発に必要な人権を満たす開発環境を作る。
指針
- フロントエンドを
create-react-app
,vue-cli
などのツールに頼らずに0ベースで作る。
-> 拡張性の問題(変な依存、余計な設定を盛り込みたくない。cli使っても結局Document読むから面倒臭い) - 多人数の開発チームを想定して構築する。
- シンプルが正義。
経緯
Spring boot
で個人開発していたが、やっぱりプレーンJSは書きたくなかった。
それと今までcreate-react-app
でごちゃごちゃやっていたので、1からフロント環境を設定したかった。
著者は執筆時点で実務1年ちょいのフロント知識浅めなペーペーなのでマサカリお願いします。
要件・設計
-
yarn build
コマンドでjsのバンドルファイルとScssのトランスパイル結果をデプロイ先のフォルダに配置する。 -
yarn dev
コマンドでJS, cssのホットリローディングに対応する。 - メディアクエリーをcssに書きたくないので、SPとPCのcssファイルを分離しておく(そうでないケースもあると思います)。
実装
自分はspring boot
のstaticフォルダを資源の配置先にしているので、そうでない方は読み替えてください。
なお、node_modules
について開発環境でしか使わないものはyarn
なら-D
オプション。npm
なら--save-dev
オプションをつけるようにしてください。
###webpack
yarn add -D webpack webpack-cli
module.exports = {
mode: process.env.NODE_ENV || 'development',
// バンドル対象のファイルのエントリーポイント
entry: ['./src/index.js'],
output: {
// ビルド後のファイル名
filename: 'bundle.js',
// ビルド後の配置先ディレクトリ
// webアプリにビルド結果を配置
path: __dirname + '../../src/main/resources/static/js'
},
module: {
// どのファイルに対してどんなことをするか
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['@babel/preset-env']
}
}
]
}
};
次に、設定したようにトランスパイルするため、以下のようにyarn add
、npm install
してください。
yarn add -D @babel/core @babel/polyfill @babel/preset-env babel-loader
これでsrc/index
ファイルがwebpack --config webpack.config.js
を実行すると指定先にコンパイルされたバンドルファイルが生成される。便利!
※src/index
でimportしているファイルがバンドル対象になるので、他の設定は不要です。
ESLint
cliツールに頼らないと言いつつもいつも初期化するときはcliでやっていたので、
yarn add -D eslint
して
npx eslint --init
npxコマンドはnpm init
された階層のnode_modules
のcliモジュールをPATHを通さなくても呼び出せる、そんなノリのコマンドっぽい。
で対話形式で設定ファイルを作成する。自分はJSONで作成して以下の通りになった。
{
"env": {
"browser": true,
"es6": true
},
"extends": [
"eslint:recommended",
"plugin:vue/essential"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"plugins": ["vue"],
"rules": {
"semi": "error",
"quotes": ["error", "single"]
}
}
ESLintのエディタ設定はVScodeのみ次回更新。
node-sass
ついでにsassを使いたかったのでnode-sass
のcliツールで.scss
を.css
にトランスパイルする。
yarn add -D node-sass
webpack
でもできそうだが、このコマンドで必要なことはできるので採用。
npx node-sass [トランスパイル対象ファイル] [出力先]
とりあえずここまでで必要なことは全て揃っている。
そしたらあとはnpm scripts
の設定をする。
なお、npm scripts
でスクリプトを書くことになるわけだが、このスクリプトに環境依存を持たせないために、今回追加でnpm-run-all
モジュールを追加する。
以下がここまで依存関係を追加した結果と、npm scripts
の設定になる。
{
"name": "client",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"dev": "run-p run:js run:sass",
"build": "run-s build:js; yarn build:sass",
"build:js": "webpack --config webpack.config.js",
"run:js": "webpack --progress --colors --watch --config webpack.config.js",
"build:sass": "run-s build:sass:pc build:sass:sp",
"build:sass:pc":"node-sass src/style/pc/index.scss ../src/main/resources/static/css/pc.css",
"build:sass:sp": "node-sass src/style/sp/index.scss ../src/main/resources/static/css/sp.css",
"run:sass": "run-p run:sass:pc run:sass:sp",
"run:sass:pc": "node-sass -w src/style/pc/index.scss ../src/main/resources/static/css/pc.css",
"run:sass:sp": "node-sass -w src/style/sp/index.scss ../src/main/resources/static/css/sp.css"
},
"dependencies": {},
"devDependencies": {
"@babel/core": "^7.8.6",
"@babel/polyfill": "^7.8.3",
"@babel/preset-env": "^7.8.6",
"babel-core": "^6.26.3",
"babel-loader": "^8.0.6",
"babel-preset-es2015": "^6.24.1",
"eslint": "^6.8.0",
"node-sass": "^4.13.1",
"npm-run-all": "^4.1.5",
"webpack": "^4.41.6",
"webpack-cli": "^3.3.11"
}
}
重要なのはここ。
"scripts": {
"dev": "run-p run:js run:sass",
"build": "run-s build:js; yarn build:sass",
"build:js": "webpack --config webpack.config.js",
"run:js": "webpack --progress --colors --watch --config webpack.config.js",
"build:sass": "run-s build:sass:pc build:sass:sp",
"build:sass:pc":"node-sass src/style/pc/index.scss ../src/main/resources/static/css/pc.css",
"build:sass:sp": "node-sass src/style/sp/index.scss ../src/main/resources/static/css/sp.css",
"run:sass": "run-p run:sass:pc run:sass:sp",
"run:sass:pc": "node-sass -w src/style/pc/index.scss ../src/main/resources/static/css/pc.css",
"run:sass:sp": "node-sass -w src/style/sp/index.scss ../src/main/resources/static/css/sp.css"
}
コマンドの内容は雰囲気でわかると思うので、軽く説明。
- JSのホットリローディング
# ファイル更新のたびにビルドが走り、コンパイルの進捗も表示 + 色付け
webpack --progress --colors --watch
- Scssのホットリローディング
# src/style/pc/index.scssをファイル更新のたびに
# ../src/main/resources/static/css/pc.cssにトランスコンパイル
#
node-sass -w src/style/pc/index.scss ../src/main/resources/static/css/pc.css
- npm-run-allのコマンド
# 1と2を並列で実行
run-p [npm scripts1] [npm scripts2]
なお、ビルド時には失敗したならすぐに処理落ちして欲しいのでシーケンシャルに実行する。
ここはケースバイケースでいいと思う。
# 1と2を直列で実行
run-s [npm scripts1] [npm scripts2]
Example
自分の場合は最終的にこうなった。
|--.eslintrc.json
|--package-lock.json
|--package.json
|--src
| |--index.js
| |--style
| | |--_define.scss
| | |--pc
| | | |--index.scss
| | |--sp
| | | |--index.scss
|--webpack.config.js
|--yarn.lock
--resources
| | | |--application.properties
| | | |--static
| | | | |--css
| | | | | |--normalize.css
| | | | | |--pc.css
| | | | | |--sp.css
| | | | |--js
| | | | | |--bundle.js
| | | | |--test.html
ビルドを実行すると狙った通りの箇所に配置できていることがわかる。
<!-- for check js and css files without application server -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="css/normalize.css" rel="stylesheet"></link>
<link rel="stylesheet" type="text/css" media="only screen and (min-width: 0px) and (max-width: 480px)" href="css/sp.css">
<link rel="stylesheet" type="text/css" media="only screen and (min-width: 481px)" href="css/pc.css">
<title>Document</title>
</head>
<body>
<h2>title</h2>
<div id="header">header</div>
<div class="body">body</div>
<script src="js/bundle.js"></script>
</body>
</html>
まとめ
やりたいことが他にあったので端折りまくってしまいましたが、所詮備忘録程度に見ていただければ幸いです。