3
2

More than 3 years have passed since last update.

webpack & node-sass & eslintでシンプルなフロント開発環境構築

Posted at

目的

  • 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
webpack.config.js

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 addnpm 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で作成して以下の通りになった。

.eslintrc.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-run-allとは

以下がここまで依存関係を追加した結果と、npm scriptsの設定になる。

package.json
{
  "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"
  }
}

重要なのはここ。

package.json
"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

自分の場合は最終的にこうなった。

directory
|--.eslintrc.json
|--package-lock.json
|--package.json
|--src
|  |--index.js
|  |--style
|  |  |--_define.scss
|  |  |--pc
|  |  |  |--index.scss
|  |  |--sp
|  |  |  |--index.scss
|--webpack.config.js
|--yarn.lock
directory
--resources
|  |  |  |--application.properties
|  |  |  |--static
|  |  |  |  |--css
|  |  |  |  |  |--normalize.css
|  |  |  |  |  |--pc.css
|  |  |  |  |  |--sp.css
|  |  |  |  |--js
|  |  |  |  |  |--bundle.js
|  |  |  |  |--test.html

ビルドを実行すると狙った通りの箇所に配置できていることがわかる。

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>

まとめ

やりたいことが他にあったので端折りまくってしまいましたが、所詮備忘録程度に見ていただければ幸いです。

3
2
0

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
  3. You can use dark theme
What you can do with signing up
3
2