かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Gulp Stylusでautoprefixerを使うメモ

nibだけだと今は不要になってるベンダープレフィックスも出力してしまうのでautoprefixerを使って対象ブラウザをコントロールするメモ

node: v9.6.1
npm: v6.1.0

gulp@3.9.1
gulp-stylus@2.7.0
gulp-autoprefixer@2.3.1
nib@1.1.2

install

$ npm install --save-dev gulp-autoprefixer

stylusで使用するならautoprefixer-stylusというパッケージもあるみたいで、中身はautoprefixerを使っているので問題ないと思うのだけれど、最終アップデートが1年前だったのでgulp-autoprefixerを使うことにしました。

gulpfile.js

"use strict";
const gulp    = require('gulp'),
      plumber = require('gulp-plumber'),
      stylus  = require('gulp-stylus'),
      nib     = require('nib'),
      prefix  = require('gulp-autoprefixer');

const devDir = './dev',
      destDir = './webroot';

// task
gulp.task('stylus', function() {
  let files = devDir + '/stylus/main.styl',
      destPath = destDir + '/assets/css';

  return gulp.src( files )
    .pipe( plumber() )
    .pipe( stylus({
      import: ['nib'],
      use:    [nib()],
      compress: false,
      linenos:  false
    }) )
    .pipe( prefix({
      browsers: ['last 2 versions', '> 1% in JP', 'ie >= 10']
      cascade: false
    }) )
    .pipe( gulp.dest( destPath ) );
});

gulp-autoprefixer browsers オプションで対応ブラウザを指定する

autoprefixerbrowsers オプションで対応させるブラウザを配列で複数指定ができます。
上記の

browsers: ['last 2 versions', '> 1% in JP', 'ie >= 10']

は「最新の2バージョン、日本で1%以上のシェア、IE10以上に対応」という感じです。

対象ブラウザはbrowserl.istでチェックすることが出来ます。(, 区切りで複数条件もチェックできるっぽいです)
オプションの詳細はbrowserslist - Githubで確認ができるのですが、gulp-autoprefixerのバージョンのせいなのかちゃんと調べてはないのですが、last 2 major versionsnot ie <= 8といったオプションだとエラーになってコンパイルできませんでした。

コンパイル結果

Stylus

::selection
  background: #A5EFD2

main
  a
    transition: all .25s
    opacity: 1
    user-select: none
    &:hover
      opacity: .6
      transform: scale(.9, .9)

.flex
  display: flex

1. nibだけ (autoprefixer) 無しの時

::selection {
  background: #a5efd2;
}
main a {
  -webkit-transition: all 0.25s;
  -moz-transition: all 0.25s;
  -o-transition: all 0.25s;
  -ms-transition: all 0.25s;
  transition: all 0.25s;
  opacity: 1;
  -ms-filter: none;
  filter: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
main a:hover {
  opacity: 0.6;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";
  filter: alpha(opacity=60);
  -webkit-transform: scale(0.9, 0.9);
  -moz-transform: scale(0.9, 0.9);
  -o-transform: scale(0.9, 0.9);
  -ms-transform: scale(0.9, 0.9);
  transform: scale(0.9, 0.9);
}
.flex {
  display: -webkit-box;
  display: -moz-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: box;
  display: flex;
}

2. autoprefixer使用時

::-moz-selection {
  background: #a5efd2;
}
::selection {
  background: #a5efd2;
}
main a {
  transition: all 0.25s;
  opacity: 1;
  -ms-filter: none;
  filter: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
main a:hover {
  opacity: 0.6;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";
  filter: alpha(opacity=60);
  transform: scale(0.9, 0.9);
}
.flex {
  display: -ms-flexbox;
  display: box;
  display: flex;
}

新しく足りてないベンダープレフィックスが追加され、不要なベンダープレフィックスが削除されてスッキリしました!
状況としてはnibで色々ベンダープレフィックスが出力されて、その後でautoprefixerがゴニョゴニョしてるという感じです。display: flexに関してはnibdisplay: box;が出力されてしまい、 次のような

You should write display: flex by final spec instead of display: box

display: boxではなく、display: flexを使ってねというメッセージが出てdisplay: box;は削除されず残ったままになりました。

最近のブラウザだと結構ベンダープレフィックス不要になっていたのですね... 自動コンパイルで放置してたから気づいていませんでした...

gulp-autoprefixerにベンダープレフィックス付きのプロパティのインデントを整形するcascadeオプションがあるのですが、nibでベンダープレフィックスが出力されてしまっていると整形(cascade: true)は効かないようです。
実際に使用する場合はmin化とかしてしまうと思うので、まぁ気にするほどではないと思いますが。(オプション効かない気持ち悪さはあります)
 

autoprefixer-stylus の場合

折角なのでgulp-autoprefixerではなくautoprefixer-stylusも試してみました。

gulpfile.js

"use strict"
const prefix = require('autoprefixer-stylus');

// task
gulp.task('stylus', function() {
  let files = devDir + '/stylus/main.styl',
      destPath = destDir + '/assets/css';

  return gulp.src( files )
    .pipe( plumber() )
    .pipe( stylus({
      import: ['nib'],
      use: [nib(), prefix({
        browsers: ['last 2 versions', '> 1% in JP', 'ie >= 10'],
        cascade: true
      })],
      compress: false,
      linenos:  false
    }) )
    .pipe( gulp.dest( destPath ) );
});

autoprefixer-stylus の場合stylusのuse内に処理を書けばOK。
同様のstylusをコンパイルしてみます。

コンパイル結果

Stylus

::selection
  background: #A5EFD2

main
  a
    transition: all .25s
    opacity: 1
    user-select: none
    &:hover
      opacity: .6
      transform: scale(.9, .9)

.flex
  display: flex

::-moz-selection {
  background: #a5efd2;
}
::selection {
  background: #a5efd2;
}
main a {
  -webkit-transition: all 0.25s;
  transition: all 0.25s;
  opacity: 1;
  -ms-filter: none;
  -webkit-filter: none;
          filter: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
main a:hover {
  opacity: 0.6;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";
  filter: alpha(opacity=60);
  -webkit-transform: scale(0.9, 0.9);
  transform: scale(0.9, 0.9);
}
.flex {
  display: -webkit-box;
  display: -ms-flexbox;
  display: box;
  display: flex;
}

cascadeオプションは効いています。
display: flexに関してはnibで出力されるdisplay: boxのせいで長めのメッセージが表示されて少しびっくりしますが問題なくコンパイルは動作します。
ただ、gulp-autoprefixerと同じブラウザの指定なのですが出力されるベンダープレフィックスに違いが... ξ(Ծ‸Ծ)ξ
(どっちが正しいんだ...
 
個人的にstylus以外にしたときにも使えそうなのでgulpで使用するならgulp-autoprefixerで良いかな〜という気がしました。
nibでdisplay: boxを出力しないオプションが有るのか知りたい...


[参考]

HTML5 & CSS3 デザインレシピ集

HTML5 & CSS3 デザインレシピ集

Gulp4 gulpコマンドでgulpInst.start.apply(gulpInst, toRun); Cannot read property 'apply' of undefinedで動かなくなった

久々にnpm installしてgulpを動かそうとしたところ

$ gulp
[08:46:54] Using gulpfile ~/Documents/local/gulpfile.js
/.nodebrew/node/v6.9.2/lib/node_modules/gulp/bin/gulp.js:129
    gulpInst.start.apply(gulpInst, toRun);
                   ^
TypeError: Cannot read property 'apply' of undefined

というエラーが表示されてgulpが動かなくなってしまいました。
gulpのヴァージョンが4.0になってglobalにインストールされていたgulp-cliのヴァージョンが合わなくてエラーになっているようでした。

npm install gulp@nextとしないとv4は入らないという記事を見たのですが、もうnpm install gulpでv4系が入ってしまうかも知れません...

解決方法 gulp-cli をインストールしなおす

npm i -g gulp-cli

ただ、

グローバルにgulp-cliを入れなくて済みます。
メモ: gulp-cliは、gulpの依存性として、ローカルのnode_modulesにインストールされています。
[出典]: 帰ってきたGulp 4

ということらしいので、globalのgulp-cliは削除してしまってもよいのかも知れません。
(個人的にはnode_modules がすぐ巨大になっていく問題をどうにかして欲しいのん...


[参考]

Webデザイナーの仕事を楽にする! gulpではじめるWeb制作ワークフロー入門

Webデザイナーの仕事を楽にする! gulpではじめるWeb制作ワークフロー入門

👆 2018/5/29 出版のgulpの本。なか見!見た感じだとv4対応っぽい

Pug 出力するコメントに変数を使いたい

pugでHTMLを生成する時、変数をコメントに含めて出力するのに少しハマったのでメモ

変数をコメントに含める方法

- var hello = "world";
<!-- hello #{hello} -->
| <!-- hello #{hello} -->

<!-- hello world -->
<!-- hello world -->

又はpugの文字列展開の方法を使って

- var hello = "world";
!= `<!-- hello ${hello} -->`

<!-- hello world -->

NG集

- var hello = "world";
<!-- hello ${hello} -->      // <!-- hello ${hello} -->
`<!-- hello #{hello} -->`    // ERROR
| <!-- hello ${hello} -->    // <!-- hello ${hello} -->
|= <!-- hello ${hello} -->   // = <!-- hello ${hello} -->
! <!-- hello ${hello} -->    // ERROR
!= "<!-- hello #{hello} -->" // <!-- hello #{hello} -->
!= `<!-- hello #{hello} -->` // <!-- hello #{hello} -->
// hello #{hello}            // <!-- hello #{hello}-->
// `hello ${hello}`          // <!-- `hello ${hello}`-->
//= hello #{hello}           // <!--= hello #{hello}-->
//= `hello ${hello}`         // <!--= `hello ${hello}`-->
//!= `hello ${hello}`        // <!--!= `hello ${hello}`-->
//= hello                    // <!--= hello-->

jadeからpugになって文字列展開は#{var}から`${var}`に変わったはずなのですが、コメントの出力に関しては${var}を使うには != `<!-- ${var} -->` としなければならないので、<!-- #{var} -->とした方が楽そうです。(コメント部分とそうでない部分とで書き方が異なるので少し混乱しそうですが...

GitHub内でも議論があるようですが、//= var とかで出力できるようになって欲しいかなーと思いました。


コメント力―「できる人」はここがちがう (ちくま文庫)

コメント力―「できる人」はここがちがう (ちくま文庫)