最近使った
フロントエンド小技集

2018-02-16 pixivエンジニア勉強会 LT

@hakatashi

PreCSS

PreCSS

  • SCSS, LESS, stylusなどの代替
    • ピュアPostCSS実装
  • PostCSSのパイプラインに乗せやすくて便利
  • 仕事がミニマルなのが好き

babel-plugin-react-css-modules

CSS Modules

  • CSSをモジュール化し、
    闇のCSSファイルに別れを告げるための技術
  • Reactなどのコンポーネント化可能な
    ライブラリと組み合わせる

styled-components

import styled from 'styled-components';

const Title = styled.h1`
  color: palevioletred;
`;

const Wrapper = styled.section`
  background: papayawhip;
  &:hover {
    background: palevioletred;
  }
`;

<Wrapper>
  <Title>Hello World!</Title>
</Wrapper>

styled-components

  • 面白い発想ではある
    • クラスという概念が消えるのは良い
  • けど正直あまり好きじゃない

babel-plugin-react-css-modules

import './style.pcss';

<section styleName="wrapper">
  <h1 styleName="title">Hello World!</h1>
</section>
.wrapper {
  color: palevioletred;
}

.title {
  background: papayawhip;
  &:hover {
    background: palevioletred;
  }
}

babel-plugin-react-css-modules

<section className="Hoge__wrapper--38Se1">
  <h1 className="Hoge__title--4S9e7">Hello World!</h1>
</section>
.Hoge__wrapper--38Se1 {
  color: palevioletred;
}
.Hoge__title--4S9e7 {
  background: papayawhip;
}
.Hoge__title--4S9e7:hover {
  background: palevioletred;
}

よいとこ

  • CSSがCSS
  • PostCSSなどと容易に統合可能
  • CSSだけ集めて別ファイルにできる

Webpackで
フォント読み込み

App.pcss

@font-face {
    font-family: misaki;
    src: url('./misaki_gothic.ttf') format('woff');
}

webpack.config.js

module.exports = { module: { rules: [ {
    test: /\.ttf$/,
    use: [
        {
            loader: 'url-loader',
            options: {
                limit: Infinity,
                mimetype: 'application/font-woff',
            },
        },
        {
            loader: './lib/fontmin-loader.js',
            options: {
                text: 'あいうえお',
            },
        },
    ],
},
...

lib/fontmin-loader.js

const Fontmin = require('fontmin');
const loaderUtils = require('loader-utils');

module.exports = async function(font) {
    const callback = this.async();
    const fontmin = new Fontmin().src(font);
    const options = loaderUtils.getOptions(this) || {};

    fontmin.use(
        Fontmin.glyph({
            text: options.text,
            hinting: false,
        })
    );

    fontmin.use(Fontmin.ttf2woff());

    const fonts = await new Promise((resolve, reject) => {
        fontmin.run((error, files) => {
            if (error) {
                reject(error);
            } else {
                resolve(files);
            }
        });
    });

    const retFont = fonts.find((f) => f.extname === '.woff');

    callback(null, retFont ? retFont.contents : fonts[0].contents);
};

module.exports.raw = true;

生成されるCSS

@font-face{
    font-family: misaki;
    src: url(data:application/font-woff;base64,d09GRgABAA…) format('woff');
}

😂

package.json

{
  "dependencies": {
    "napa": "^3.0.0",
    ...
  },
  "napa": {
    "misaki-font": "http://www.geocities.jp/littlimi/arc/misaki/misaki_ttf_2015-04-10.zip",
    "hatena-icon": "http://hatenacorp.jp/file/hatenaportal/company/Hatena-Bookmark-Logo.zip"
  },
  "scripts": {
    "install": "napa"
  },
  ...
}

react-icons

アイコンを使う技術の変遷

  • 画像
    • <img>
  • Webフォント
    • <i class="i-hoge"/>
  • SVGスプライト
    • <svg><use href="#hoge"/></svg>
  • Reactコンポーネント ←NEW!!!

react-icons

const Videocam = require('react-icons/lib/md/videocam');
const VideocamOff = require('react-icons/lib/md/videocam-off');

class Hoge extends React.Component {
    render() {
        return (
            <Tooltip>
                {this.state.isNoVideo ? <VideocamOff/> : <Videocam/>}
            </Tooltip>
        );
    }
}

おしまい

Made with Slides.com