Help us understand the problem. What is going on with this article?

preact にも hooks が生えそうなのでやっていく

More than 1 year has passed since last update.

軽量で react ライクなライブラリである preact に hooks が入りそうなのをたまたま見つけたので久しぶりにやっていく

やっていくライン

  1. webpack-dev-server で hot-reload 開発
  2. webpack を介した bundle
    1. preact gzip で 3kb 説検証
  3. webpack 外で静的ホスト

setup

もろもろ準備する

package.json

package.json
  "scripts": {
    "dev": "webpack-dev-server --config ./webpack.config.js --mode development",
    "build": "npm run clean && npm run build:webpack && cp ./dist/bundle.js ./public/",
    "build:webpack": "webpack --config ./webpack.config.js",
    "clean": "rm -rf ./dist/ ./public/bundle.*",
    "start": "serve ./public",
    "init": "npm i && mkdir src public && touch src/index.js public/index.html babel.config.js webpack.config.js",
    "gzip": "gzip -k9rn ./dist"
  },
  "dependencies": {
    "preact": "10.0.0-beta.2"
  },
  "devDependencies": {
    "@babel/cli": "7.4.4",
    "@babel/core": "7.4.5",
    "@babel/plugin-transform-react-jsx": "7.3.0",
    "@babel/preset-env": "7.4.5",
    "babel-loader": "8.0.6",
    "serve": "11.0.1",
    "webpack": "4.33.0",
    "webpack-cli": "3.3.3",
    "webpack-dev-server": "3.7.1"
  },
  • webpack, babel
    • 近代では必須
  • preact
    • やっていく module
  • serve
    • 静的ホスト簡易サーバ

初期化コマンドで諸々用意する

npm run init

babel

babel.config.js
const presets = [
  [
    '@babel/env',
    {
      targets: {
        chrome: '75',
      },
    },
  ],
];
const plugins = [['@babel/plugin-transform-react-jsx', { pragma: 'h' }]];
module.exports = { presets, plugins };

とりあえず chrome で動けばいいので targets は適当に指定しとく
公式に載ってる通りに JSX をコンパイルできるようにする plugin だけ入れとく

webpack

webpack.config.js
module.exports = {
  entry: ['./src/index.js'],
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: ['babel-loader'],
      },
    ],
  },
  resolve: {
    extensions: ['*', '.js', '.jsx'],
  },
  output: {
    path: __dirname + '/dist',
    publicPath: '/',
    filename: 'bundle.js',
  },
  devServer: {
    contentBase: './public',
  },
};

まあ packer の皆さんなら特に難しいところもないと思うので割愛

development

まずはハロワを目指す

public/index.html
<!DOCTYPE html>
<html>
  <head>
    <title>preact starter</title>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <script src="/bundle.js" async></script>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>
src/index.js
import { h, render } from 'preact';

const App = ({}, {}) => <div>Hello Preaaaaaaaaact</div>;

render(<App />, document.getElementById('app'));
dev-server
npm run dev

多分これでいけてると思う
あとは好きに修正すればokということでやっていきライン1はクリア

ここで build も試す

npm run build && npm run gzip && ls -lah dist/
# ... 3.5K ... bundle.js.gz

import cost と同じ数値なので成功ということでやっていきライン2もクリア
続けて3のクリアも目指す

npm start

全クリできたと思う
静的ホスティングはnowでもねっとりファイでもなんでもいいと思う

hooks

ついでに preact の hooks をいくつか書いて終わりたいと思う

src/index.js
import { h, render } from 'preact';
import { useState, useMemo, useLayoutEffect, useCallback } from 'preact/hooks';

const Clock = () => {
  const [time, setTime] = useState(0);

  const double = useMemo(() => {
    return time * 2;
  }, [time]);

  const increment = useCallback(() => {
    setTime(time + 1);
  }, [time]);
  const decrement = useCallback(() => {
    setTime(time - 1);
  }, [time]);

  useLayoutEffect(() => {
    time !== 0 && time % 3 === 0 && setTime(time + 1);
  }, [time]);

  return (
    <div>
      {time}
      {double}
      <button onclick={increment}>++</button>
      <button onclick={decrement}>--</button>
    </div>
  );
};

const App = () => (
  <div>
    Hello Preaaaaaaaaact
    <Clock />
  </div>
);

render(<App />, document.getElementById('app'));

流石に書き味は同じだった
ちなみに preact/hooks の bundle size は gzip で 3.5kb くらい

lidqqq
フロントエンドッグ
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away