<!DOCTYPE LNLY>

ノールック寿司グリップ🍣

今から僕は、ビルド環境を作る

使っているライブラリとか、ビルド環境に使っているnpmモジュールが知らぬ間にバージョンアップしたりすることはよくあって、ボイラープレートはすぐに陳腐化するので、たまにはゼロからビルド環境を構築する。読んでいるのが、2018年8月10日よりも後の日付なら、あまり真にうけないでちゃんと調べた方が(新しくなってることあると思うので)いい。

どんな環境にするか

  • ビューはVue.js
  • CSSはSass(SCSS)
  • CSSSFC上にscoped
  • watchはもちろんのこと
  • 開発中はlocalhostでアクセスしたい
  • ホットリロードする
  • eslintをかけたい

そんな感じ。

できたもの

https://github.com/linlymatsumura/boilerplate/tree/master/20180711/myApp

できていくまで

プロジェクト作る

npm init -y

yをつけると対話インターフェースをすっ飛ばす。

webpack導入

webpack-cliも一緒に。

npm i --save-dev webpack webpack-cli

babelとbabel-loader導入

早くbabelかまさなくていいようになるといいな。

npm i --save-dev babel-core bable-loader

webpack.config.jsを書く。配置はプロジェクトルートに。

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/
      }
    ]
  }
};

entryはどこにソースファイルがあるか。outputはどこに出力するか。rulesで、末尾が.jsのファイルはbabelかけるよ。って書いてある。

eslint導入

npm i --save-dev eslint

.eslintrc.jsが設定ファイル。これもプロジェクトルートに置く。

module.exports = {
    "extends": "standard",
    "parserOptions": {
      "ecmaVersion": 2017,
      "sourceType": "module"
    }
};

extendsはどんなルールでlintするか。https://standardjs.com/を使う。 Standardだけど、標準ってわけじゃないのであんまり気にしない。 コードの様式は、どう揃っているかよりも、揃っていることそれ自体が重要。

これでlintをかけるための、これら。

npm i --save-dev eslint-config-standard eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-standard

webpackに組み込むために、eslint-loaderを。

npm i --save-dev eslint-loader

さっきのwebpack configに追加する。

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        enforce: 'pre',
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'eslint-loader'
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/
      }
    ]
  }
};

基本的なeslintの設定とjsのbuildまでできた。

webpack-dev-server導入

localhostアクセスできるように

npm i --save-dev webpack-dev-server

webpack configに設定を追加。 ./distをルートにしたり、ポートを3000にしたり。

関係ないけどmain.jsbundle.jsに変更したりして、

<!doctype html>
<html>
<head>
  <title>my App</title>
</head>
<body>
  <script src="bundle.js"></script>
</body>
</html>

./dist/index.js作って

window.onload = () => {
  console.log(123)
}

./src/index.js書いたら

  "scripts": {
    "build": "webpack --config webpack.config.js",
    "dev": "webpack-dev-server --config webpack.config.js"
  }

npm scriptをちょっと書いたり。 これで、

npm run build

したり

npm run dev

できるようになった。

vueとvue-loader導入

次はvueを書けるように。

npm i --save-dev vue vue-loader vue-template-compiler

webpack.config編集。

const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  plugins: [
    new VueLoaderPlugin()
  ],
  module: {
    rules: [
      {
        enforce: 'pre',
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'eslint-loader'
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/
      }
    ]
  },
  mode: 'development',
  devServer: {
    contentBase: path.join(__dirname, './dist'),
    port: 3000
  }
}

rulesとか、pluginとかその辺りを足す。 vue-loaderはv15からpluginとしてwebpackに組み込まないと動かないようになった。

import Vue from 'vue'
import MyApp from 'MyApp.vue'

window.onload = () => {
  new Vue({
    render: h => h(MyApp)
  }).$mount('#myApp')
}

./src/index.js書いて

<template>
  <h1>this is myApp</h1>
</template>

<script>
export default {
  mounted () {
    console.log(123)
  }
}
</script>

./src/MyApp.vue書いて。 ビルドできるようになった。

CSS

Vueコンポーネント上でStyleを書けるようにするvue-style-loadercss自体のcss-loadersass-loaderpostcss-loadernode-sassなどを一気に入れる。

npm i --save-dev vue-style-loader css-loader sass-loader postcss-loader node-sass

postcss-loaderは当初予定していなかったが、autoprefixerをかけるために導入

module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}

postcss.config.jsを書いて。

これで冒頭に書いた環境が整った。

終わり。イェーイ。

CSSで作るグラデーションを美しくする一手間

素晴らしい記事*1を見つけて真似してみたら地味なポイントだけどグッと見栄えがよくなりましたので、ぜひ試して欲しいな。

いつ使うのか

このテクニックが最も有効に効果を発揮するのは、写真の上に文字を重ねるとき。 そういうデザインでよく使う、グラデーションを薄く重ねておくアレです。

See the Pen smooth gradient effect by LNLY (@linlymatsumura) on CodePen.

上がこれまでやっていた方法(というか、ただグラデーションを重ねた方法)で、下が今回のテクニックを使ったサンプルです。

何が良くなったのか

これまでの方法ではグラデーションの終わりの部分が(一応グラデーションではあるのだけど)パキっと光彩のように境界線が出てしまっています。 一方改善した方ではほとんど境界線が分からないように滑らかに終わっています。

改善前のグラデーション

    background-image: linear-gradient(
      rgba(#151515, 1),
      rgba(#151515, 0)
    );

元はこのように、シンプルに開始と終了の透明度を変えてグラデーションをかけてます。

改善後のグラデーション

    background-image: linear-gradient(
      rgba(#151515, 1) 0%,
      rgba(#151515, 0.738) 19%,
      rgba(#151515, 0.541) 34%,
      rgba(#151515, 0.382) 47%,
      rgba(#151515, 0.278) 56.5%,
      rgba(#151515, 0.194) 65%,
      rgba(#151515, 0.126) 73%,
      rgba(#151515, 0.075) 80.2%,
      rgba(#151515, 0.042) 86.1%,
      rgba(#151515, 0.021) 91%,
      rgba(#151515, 0.008) 95.2%,
      rgba(#151515, 0.002) 98.2%,
      rgba(#151515, 0) 100%
    ); 

改善後はこのように、細かくステップを分けて透明度がだんだんと緩やかに変わる( easing )ようになっています。 このおかげで、サンプルのように綺麗にグラデーションするようになります。

mixinや、グラデーションの細かい学び

sass mixin

元記事では作者によるPostCssのプラグインが紹介されているので、PostCSS案件ではそちらを。 Sassはないそうなので、こんなミックスインにしておくと使いやすいかなと。

グラデーションは透明度を変えて重ねる

全部の場合でとはいかないけど、

background-image: linear-gradient($color-A, $color-B)

このようにlinear-gradientだけで色を変えるより、

background-color: $color-A;
background-image: linear-gradient(rgba($color-B, 0), $color-B);

のように重ねて透明度で色を変化させたほうが、今回のようなのを適用するのに楽 *2

See the Pen 2 way to gradient. by LNLY (@linlymatsumura) on CodePen.

transparentは何色か

transparentrgba(0,0,0,0)に等しく、つまり「黒」だ。だから、background-image: linear-gradient(blue, transparent)としたときは、だんだんと青のまま不透明度が下がっていくのではなくて、中間色ではグレーが混ざることになる。望んだ結果を得るにはbackground-image: linear-gradient(blue, rgba(blue, 0))とする *3 必要がある

そんな感じ。ハピネス。

*1:https://css-tricks.com/easing-linear-gradients/

*2:rgba()に色名を引数として渡すにはsassの使用を前提

*3:rgba()に色名を引数として渡すにはsassの使用を前提