20190310のReactに関する記事は5件です。

旧DMM.R18で女優をフォローするChrome拡張をReact+Webpackで作った

モチベーション

自分はジャンルやシチュエーションより出演者や監督でAVを選ぶことが多い。しかし、DMM.R18(元FANZA)では作品のお気に入りは出来るけど出演者をフォローする機能がない。「検索条件を保存」 という機能があるがこれは10件のキューで上限を超えて追加されると古いものから削除されるため使い勝手が悪かった。
そこで制限なく出演者をフォロー出来るアプリが欲しかった。

スクリーンショット 2019-03-11 1.29.30.png

試しにTwitterで調べてみると同じこと考えてる人はそれなりにいるみたい。

作ったもの

og24715/DMM.pornstars https://github.com/og24715/DMM.pornstars

構成

DMM.pornstars
├── README.md
├── node_modules
├── chrome
│   ├── dist
│   └── src
│       ├── background.js
│       ├── detail.js
│       ├── favorites
│       │   ├── App.jsx
│       │   ├── component
│       │   │   ├── card
│       │   │   │   ├── index.js
│       │   │   └── navbar
│       │   │       └── index.jsx
│       │   ├── index.css
│       │   ├── index.html
│       │   └── index.js
│       └── manifest.json
├── package-lock.json
├── package.json
├── webpack.config.js
└── yarn.lock
パス 説明
chrome/ 実質 Chrome 拡張用のプロジェクトディレクトリ。
chrome/dist/ webpack によってバンドルされた諸々が吐かれるディレクトリ。Chromeにはここを読ませる。静的ファイルも src/ に置いて copy-webpack-plugin を使って dist/ 配置されるようにしたので当たり前だけどここは触らない。
chrome/src/background.js アイコンがクリックされたら一覧を表示するだけ。
chrome/src/detail.js DMM.R18 で作品の画面を表示しているときに、出演者の名前の横にフォローボタンを表示するだけ。
chrome/src/favorites/ 一覧画面。React使ってる。

ハマりどころ

CRA (create-react-app) を使いたい

やめたほうがよさそうです。
だいぶ前に試した記憶だと、CRAはSPAを作るときには非常に頼りになるスタートアップツールですが、react-scripts ejectをしない限り webpack の entry を複数設定することが出来ません。画面ごとに create-react-app {project_name} しなくてはらず地獄です。

local.storage.get の第一引数に文字列で与えたのに第2引数のコールバック関数への引数がキーバリューになる

これはドキュメントちゃんと読んでください。
local.storage.get は第一引数に与えられた文字列もしくは文字列配列のキーをもとにキーバリューのオブジェクトを第二引数に与えられたコールバック関数へ引数として与えます。
第一引数に文字列を与える意図としては、キーを決定したので対応するバリューを返して欲しいってことなんですが、第一引数が文字列だろうと配列だろうとキーバリューをオブジェクトを返します。

コードにすると

// こうじゃなくて
chrome.storage.local.get('following', following = [] => { /* noop */ }));
// こう
chrome.storage.local.get('following', ({ following = [] }) => { /* noop */ }));

こんな感じ。
今の所 following ってキーでしか値を保存していないんですが、キー一つ与えたところでその値は返って返ってこないってことです。
ブラウザ実装の Window.localStorage.getItem と挙動が違うのでドキュメント見ないで実装するとハマります。

localStorage.getItem() - Web APIs | MDN https://developer.mozilla.org/en-US/docs/Web/API/Storage/getItem
chrome.storage - Google Chrome https://developer.chrome.com/apps/storage

静的ファイルを src/ に置きたい

dist/ は極力触りたくありませんでした。
今回のアプリで静的ファイルは拡張のマニフェストファイルである manifest.json と Reactのエントリーポイントとなる index.html があります。
これらは素の webapck を通しても dist/ へ配置されないので webpack-copy-plugin を使うしかなさそうです。

plugins: [
  new CopyWebpackPlugin([
    { from: './chrome/src/favorites/index.html', to: 'favorites.html' },
    { from: './chrome/src/manifest.json' },
  ]),

たかがコピーするだけなのにプラグインを追加し無くてはならない歯がゆさに gulp 時代の混沌をに似たものを感じます。
なにかいい方法があれば教えてください。

性欲駆動開発

https://twitter.com/search?q=%E6%80%A7%E6%AC%B2%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React環境構築

はじめに

Reactの環境を1から構築していく。

アプリディレクトリの作成

まずはmkdirコマンドでアプリのディレクトリを作成する。
作成したらアプリディレクトリに移動する。

whitecat:~/environment $ mkdir whitecat-app
whitecat:~/environment $ ls
README.md  whitecat-app
whitecat:~/environment $ cd whitecat-app/
whitecat:~/environment/whitecat-app $ 

必要npmパッケージのインストール

package.jsonの作成

npmモジュールをインストールするために、最初に空のpackage.jsonを作成する。

whitecat:~/environment/whitecat-app $ echo "{}" > package.json
whitecat:~/environment/whitecat-app $ ls
package.json

babel

babelとは

reactのJSXで記述されたコードは、ブラウザでは解釈できない。そこでブラウザ解釈できるように変換する必要がある。この変換を行ってくれるのがbabelである。

babelのインストール

インストールはnpm install --save-dev babel-core babel-preset-reactコマンドで実施する。babel-coreはbabelの本体である一方、babel-preset-reactはreactアプリケーションに必要なbabelのプラグインをまとめたものだ。

babel-preset-hogehogeは、特定の目的のためにbabelで必要なプラグインをまとめてくれているもの。自分でひとつひとつインストールしてもよいが、特に理由なければpresetを使うべき。

webpack

webpackはモジュールバンドラーであり、モジュール(機能ごとにファイルを分割したソースコードやnpmパッケージ)をバンドルして(依存関係を解決したうえで1ファイルにまとめて)くれる。

webpackのインストール

インストールはnpm install --save-dev webpack babel-loader@7 webpack-cliコマンドで実施する。
モジュールをバンドルするだけならwebpakだけでよいが、reactではモジュールをバンドルする前にbabelでソースコードのJSX記述を変換する必要があるため、babel-loaderを併せてインストールする。なお、babel-coreのバージョン関係から@7のバージョンをインストールしないといけない。

webpackでバンドルする際にはcliでコマンド実行させる必要があるので、webpack-cliもインストールする。

react

reactのインストール

最低限必要な2つのreactパッケージをnpm install --save react react-domでインストールする。

package.json

インストール後のpackage.jsonは以下のようになる。

package.json
{
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "babel-preset-react": "^6.24.1",
    "webpack": "^4.29.6",
    "webpack-cli": "^3.2.3"
  },
  "dependencies": {
    "react": "^16.8.4",
    "react-dom": "^16.8.4"
  }
}

アプリケーションソースコードの作成

srcディレクトリを作成し、サンプルとして以下ファイルを作成する。

index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Hello from './Hello';

ReactDOM.render(
    <Hello />,
    document.getElementById('root')
    );
Hello.js
import React from 'react';

export default function Hello(){
    return <h1> Hello world!! </h1>;
}

webpack設定ファイルの作成

webpack.config.jsを作成し、バンドルの設定を記述する。

webpack.config.js
module.exports = {
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader",
                    options: {
                        presets: ['react']
                    }
                }
            }
        ]
    }
};

バンドル実施

./node_modules/.bin/webpack --config webpack.config.js --mode developmentを実行し、バンドルファイルを作成する。モードについては、とりあえずdevとしておく。

実行するとwebpackは自動的に/src/index.jsを起点として、バンドルする。実行後は、/dist/main.jsがアウトプットとして出力される。

index.htmlの作成

publicフォルダを作成し、index.htmlを作成する。index.htmlでは、バンドルされたmain.jsを読み込むようにする。

index.html
<body>
    <div id="root"></div>
    <script src=".././dist/main.js"></script>
</body>

index.htmlを読み込む

htmlをブラウザで開くと、reactが実行されhello world!!が表示される。

最終的なディレクトリの構成

.
├── dist
│   └── main.js
├── node_modules
├── package.json
├── package-lock.json
├── public
│   └── index.html
├── src
│   ├── Hello.js
│   └── index.js
└── webpack.config.js

おわりに

とりあえず、最低限のreact環境は作成できた。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React初期構築

はじめに

Reactの環境を1から構築していく。

アプリディレクトリの作成

まずはmkdirコマンドでアプリのディレクトリを作成する。
作成したらアプリディレクトリに移動する。

whitecat:~/environment $ mkdir whitecat-app
whitecat:~/environment $ ls
README.md  whitecat-app
whitecat:~/environment $ cd whitecat-app/
whitecat:~/environment/whitecat-app $ 

必要npmパッケージのインストール

package.jsonの作成

npmモジュールをインストールするために、最初に空のpackage.jsonを作成する。

whitecat:~/environment/whitecat-app $ echo "{}" > package.json
whitecat:~/environment/whitecat-app $ ls
package.json

babel

babelとは

reactのJSXで記述されたコードは、ブラウザでは解釈できない。そこでブラウザ解釈できるように変換する必要がある。この変換を行ってくれるのがbabelである。

babelのインストール

インストールはnpm install --save-dev babel-core babel-preset-reactコマンドで実施する。babel-coreはbabelの本体である一方、babel-preset-reactはreactアプリケーションに必要なbabelのプラグインをまとめたものだ。

babel-preset-hogehogeは、特定の目的のためにbabelで必要なプラグインをまとめてくれているもの。自分でひとつひとつインストールしてもよいが、特に理由なければpresetを使うべき。

webpack

webpackはモジュールバンドラーであり、モジュール(機能ごとにファイルを分割したソースコードやnpmパッケージ)をバンドルして(依存関係を解決したうえで1ファイルにまとめて)くれる。

webpackのインストール

インストールはnpm install --save-dev webpack babel-loader@7 webpack-cliコマンドで実施する。
モジュールをバンドルするだけならwebpakだけでよいが、reactではモジュールをバンドルする前にbabelでソースコードのJSX記述を変換する必要があるため、babel-loaderを併せてインストールする。なお、babel-coreのバージョン関係から@7のバージョンをインストールしないといけない。

webpackでバンドルする際にはcliでコマンド実行させる必要があるので、webpack-cliもインストールする。

react

reactのインストール

最低限必要な2つのreactパッケージをnpm install --save react react-domでインストールする。

package.json

インストール後のpackage.jsonは以下のようになる。

package.json
{
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "babel-preset-react": "^6.24.1",
    "webpack": "^4.29.6",
    "webpack-cli": "^3.2.3"
  },
  "dependencies": {
    "react": "^16.8.4",
    "react-dom": "^16.8.4"
  }
}

アプリケーションソースコードの作成

srcディレクトリを作成し、サンプルとして以下ファイルを作成する。

index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Hello from './Hello';

ReactDOM.render(
    <Hello />,
    document.getElementById('root')
    );
Hello.js
import React from 'react';

export default function Hello(){
    return <h1> Hello world!! </h1>;
}

webpack設定ファイルの作成

webpack.config.jsを作成し、バンドルの設定を記述する。

webpack.config.js
module.exports = {
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader",
                    options: {
                        presets: ['react']
                    }
                }
            }
        ]
    }
};

バンドル実施

./node_modules/.bin/webpack --config webpack.config.js --mode developmentを実行し、バンドルファイルを作成する。モードについては、とりあえずdevとしておく。

実行するとwebpackは自動的に/src/index.jsを起点として、バンドルする。実行後は、/dist/main.jsがアウトプットとして出力される。

index.htmlの作成

publicフォルダを作成し、index.htmlを作成する。index.htmlでは、バンドルされたmain.jsを読み込むようにする。

index.html
<body>
    <div id="root"></div>
    <script src=".././dist/main.js"></script>
</body>

index.htmlを読み込む

htmlをブラウザで開くと、reactが実行されhello world!!が表示される。

最終的なディレクトリの構成

.
├── dist
│   └── main.js
├── node_modules
├── package.json
├── package-lock.json
├── public
│   └── index.html
├── src
│   ├── Hello.js
│   └── index.js
└── webpack.config.js

webサーバーの作成と自動ビルド

このままだと、ソースを書き換えるたびにwebpackコマンドを実行し、htmlファイルを再読み込みしないといけない。webpack-dev-serverをインストールすると、ソースコードの書き換えにより勝手に再ビルドしてくれるようになる。

インストール

npm install webpack-dev-server --save-devコマンドを実行する。

設定

webpack-dev-serverもwebpack.config.jsを設定ファイルとして利用する。なお、まずは設定として[disableHostCheck: true]とする。
※今回は開発環境にcloud9を利用しているためlocal環境ではない。よって、どこからでもアクセスできるようにしないといけない。

webpack.config.js
module.exports = {
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader",
                    options: {
                        presets: ['react']
                    }
                }
            }
        ]
    },
    devServer: {
        disableHostCheck: true
    }
};

アクセス

./node_modules/.bin/webpacdev-serverコマンドでwebサーバーを起動する。起動後、https://hogehoge.hoge.cloud9.us-east-1.amazonaws.com/public/index.htmlにアクセスすると、hello world!!が表示される。

distフォルダ削除

webpack-dev-serverではバンドルしたファイルはインメモリ上に保存される。よって、distフォルダは必要ないため削除する。

おわりに

とりあえず、最低限のreact環境は作成できた。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【React】Hooksの出現で変わったいまどきのコンポーネント設計

これまでのコンポーネント設計

これまでReactである程度開発できる人がアニメーションなどローカルで閉じて制御させたいコンポーネント実現しようとするとき、問題になってくるのがStateLifecycleです。

React入門者は各コンポーネントをクラスで作成していると思うのでローカルでStateを使い、componentDidMountなどのLifecycle methodを使えば良いので問題はありません。

しかし、慣れてくるとコンポーネントをクラスでは作成せず、SFC(Stateless Function Component)化していく流れがありました(過去形)。そしてそのような人たちは好んでStateReduxMobxでグローバルに一元管理しているはずです。

SFC化したコンポーネントはローカルにStateを保持できないし、Lifecycle methodも使えません。そのため、HoC(Higher-Order Components)を活用し、コンポーネントをラップすることで擬似的にローカルStateを保持させたり、Lifecycle method使えるようにすることで解決してきました。

これまでコンポーネントはSFC化し、必要があればHoCを用いてラップするのがベストプラクティス的な流れがありましたが、React version16.8で正式にリリースしたHooksという機能の出現で流れが変わりました

HoCの代表的ライブラリーrecomposeの開発の停止の発表、recomposeの開発者がReactチームに参画したみたいなのでHoCの流行りは終わると思っています。

これからのコンポーネント設計

これまでのコンポーネント

まずクラスで作ったコンポーネント、SFC化したコンポーネント、HoCでラップしたコンポーネントの違いについてみてみます。

Component local state lifecycle method performance
Class ×
SFC × ×
HoC(wrap SFC)

つまりパフォーマンスを考えたとき、SFCを使い、必要に応じてHoC(wrap SFC)がベストプラクティスでした

HooksがもたらすFC(Function Component)とは

Hooksはクラスを使わずとも、ローカルでstateを管理できたり、様々な機能を使えるようにできるフックAPIです。

useStateuseEffectuseCallbackuseReducerなどたくさんあります。ここら辺の使い方はたくさん記事が世に出回っているので説明しません。

Hooksを利用することで、これまでHoC(wrap SFC)で実現していたローカルのstatelifecycle methodの利用を上手く吸収したFC(Function Component)を作ることができます

HoC(wrap SFC)とあまり変わらないが、一々ラップする必要がなくなっているところと、可読性がかなり上がります。

パフォーマンスの面では、まだHoC(wrap SFC)よりは遅いらしいです。

FCの例をあげておきます。
カラーの部分はわざわざuseStateuseEffectを使わなくてもいいのですが、使い方の紹介として使っています。

SampleButton.js
import React, { useState } from 'react'
import styled, { keyframes } from 'styled-components'

const white = '#F5F5F5'
const innerDefaultColor = '#3C3C3C'
const outerDefaultColor = '#FF5A5F'

const SampleButton = ({ onClick, inner, outer, text, children }) => {
  const [ hover, setHover ] = useState(false)

  const [ textColor, setTextColor ] = useState(white)
  useEffect(() => {
    if(text) {
      setTextColor(text)
    }
    else {
      setTextColor(white)
    }
  }, [text])

  const [ innerColor, setInnerColor ] = useState(innerDefaultColor)
  useEffect(() => {
    if(inner) {
      setInnerColor(inner)
    }
    else {
      setOuterColor(innerDefaultColor)
    }
  }, [inner])

  const [ outerColor, setOuterColor ] = useState(outerDefaultColor)
  useEffect(() => {
    if(outer) {
      setOuterColor(outer)
    }
    else {
      setOuterColor(outerDefaultColor)
    }
  }, [outer])

  const scaleUp = keyframes`
    from {
      transform: scale(1)
    }
    to {
      transform: scale(${hover? 1.05 : 1})
    }
  `

  const Container = styled.div`
    position: relative
    display: flex
    justify-content: center
    align-items: center
    width: 210px
    height: 210px
  `

  const Outer = styled.div`
    position: absolute
    top: 0
    left: 0
    width: 210px
    height: 210px
    background: ${outerColor}
    border-radius: 105px
    animation-name: ${scaleUp}
    animation-duration: 0.5s
    animation-timing-function: ease-in
    animation-iteration-count: infinite
    animation-direction: alternate
    z-index: -1
  `

  const Inner = styled.div`
    display: flex
    justify-content: center
    align-items: center
    text-align: center
    width: 200px
    height: 200px
    border-radius: 100px
    background: ${innerColor}
    color: ${textColor}
    cursor: pointer

  `

  return (
    <Container>
      <Outer />
      <Inner
        onClick={onClick}
        onMouseOver={() => setHover(true)}
        onMouseOut={() => setHover(false)}
      >
        {children}
      </Inner>
    </Container>
  )
}

export default SampleButton

結論

これからのReactのコンポーネント設計は、SFCとHoC(wrap SFC)主体の設計からSFCとFC主体へとシフトしていきます。Hooksの出現は割と大きな変化だと思うので、一度Reactの知識をアップデートしておいた方がいいと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

設定不要で簡単にNode.jsアプリケーション構築できるZero Serverを試してみた

Zero Serverについて公式ページを読んで試したみたという内容です。
詳しく知りたい方は公式を参照するようお願いします。
間違いなどありましたらご指摘お願いいたします。 :bow:

Zero Server とは

※githubのreadmeの説明の部分をgoogle翻訳↓

Zeroは現代のWeb開発を単純化するためのWebフレームワークです。 パッケージ管理やルーティングを気にせずにアプリケーションを構築できます。 Node.js、React、HTML、MDX、および静的ファイルを組み合わせてコードを記述し、それらをすべてフォルダーに入れるのと同じくらい簡単です。 ゼロはそれらすべてに役立つでしょう。 作業を簡単にするために、ルーティング、バンドル、およびトランスパイルのための通常のプロジェクト構成がゼロで抽象化されています。

自分でいろいろ設定しなくても、require('moment') と書けば、Zero Serverが自動でmomentをインストールして、解決してくれます。

Installation

bash
npm i zero

Hello World

時刻を教えてくれるアプリケーションを作成する

time.js
const moment = require("moment")

module.exports = (req, res) => {
  var time = moment().format('LT');   // 11:51 AM
  res.send({time: time })
}
bash
npx zero

http://localhost:3000/time にアクセスすると、

image.png

time.jsで作成しましたので、localhost:3000/time にアクセスすると内容を表示してくれます。

moment を自動でインストールして使えているのが確認できました。


サーバーを稼働し続けた状態で、index.jsx を作成する。

index.jsx
import React,{ Component } from 'react'

export default class extends Component {
  static async getInitialProps(){
    const { time } = await fetch("/time").then((resp) => resp.json())
    return { time }
  }

  render() {
    return <p>Current time is: {this.props.time}</p>
  }
}

http://localhost:3000/

image.png

先ほどの/time からjsonを受け取り、jsxも正しく動作しているのが確認できました。

webpackなどの設定をいじる必要がなく、簡単にアプリケーション構築できました!

Static Files

https://github.com/remoteinterview/zero/tree/master/docs/static

画像やテキストファイルなどの扱いについて

.js, .ts, .jsx, .tsx, .htm, .html, .md, .mdx以外の場合は、プロジェクトディレクトリにファイルを置けばそのまま表示してくれるようでした。

※プロジェクト直下のディレクトリにnihon-amagaeru.jpg を置いた場合

image.png

Node.js (.js, .ts)

https://github.com/remoteinterview/zero/tree/master/docs/nodejs

hello.js
module.exports = function(req, res) {
  res.send("Hello");
}

Zero はExpress.jsを使用しているようなので、req, resのリクエスト・レスポンスのオブジェクトはExpressのものと同じ。


./api/login.js とファイルを設置した場合は http://localhost:3000/api/login でアクセスできる

/api/logion.js
module.exports = function(req, res) {
    res.send("Login Api");
}

image.png

パラメータの取得

param-test.js
module.exports = function(req, res) {
    console.log(req.body)
    res.send({body: req.body})
}

POST, PUT, PATCH, DELETE でパラメータを問題なく受け取れるようでした。

bash
$ curl http://localhost:3000/param-test -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "category=1&sort=asc"
{"body":{"category":"1","sort":"asc"}}
$ curl http://localhost:3000/param-test -X POST -H "Content-Type: application/json" -d '{"category":1, "sort":"asc"}'
{"body":{"category":1,"sort":"asc"}}
$ curl http://localhost:3000/param-test -X DELETE -H "Content-Type: application/json" -d '{"category":1, "sort":"asc"}'
{"body":{"category":1,"sort":"asc"}}

Route Rewrites

user.js
module.exports = function(req, res) {
    console.log(req.params)
    res.send({params: req.params})
}

/user/lukeにアクセスした時に、./user/luke.jsがなかった場合、req.params['luku']と設定してくれます。

image.png

image.png

TypeScript

.tsファイルにすると、TypeScriptとして動作させることができる

hello-ts.ts
import * as express from "express";

function handler(req: express.Request, res: express.Response) {
  res.send("Hello TypeScript")
}
export default handler

image.png

React

https://github.com/remoteinterview/zero/tree/master/docs/react

hello-react.jsx
export default () => <h1>Hello React</h1>

image.png

Populating <head>

react-helmet.jsx
import {Helmet} from "react-helmet";

module.exports = () => (
  <div>
    <Helmet>
        <meta charset="UTF-8" />
        <title>Page Title</title>
        <link rel="canonical" href="http://mysite.com/example" />
    </Helmet>
    <h1>Hello World</h1>
  </div>
)

react-helmetが使えるので、metaタグなどの扱いも簡単です

image.png

Importing CSS/Sass

cssとscssがサポートされているようです。

react-style
import "./style.scss"
module.exports = ({name}) => (
  <h1>Hello {name}</h1>
)
style.scss
body {
    h1 {
        color: blue;
    }
}

image.png

TypeScript

.tsxとするとことで使用することができました。

react-ts.tsx
import * as React from "react";

export default class HelloWorld extends React.Component<{}, {}> {
    render() {
       return (<b>Hello TypeScript</b>);
    }
}

HTML (.htm, .html)

バンドラーはparcelが使われているとのことです。なので<script>タグのsrcから自動で解析してくれました。

html-test.html
<!DOCTYPE html>
<html lang="en">
<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">
    <script src="./style.js"></script>
    <title>Document</title>
</head>
<body>
    <h1>Hello</h1>
</body>
</html>
style.js
import "./style.scss";
style.scss
body {
    h1 {
        color: blue;
    }
}

image.png

Markdown / MDX (.md, .mdx)

自動で.mdファイルをhtmlに変換してくれる

markdown.md
# Markdown in Zero
Zero renders `.md` files too.

image.png

mdx-test.mdx
import Btn from "./component/btn"

# Hello, world!

<Btn />

image.png


自分で試したコード

最後まで読んでいただいてありがとうございましたm(_ _)m

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む