某所でLTした内容の抜粋。 Reactを使って静的ウェブサイトを生成してみました。 技術的にはサーバーサイドレンダリングを利用するだけです。 ウェブサイトとしてReactを利用しないため、軽量なウェブサイトを構築でき、Reactのコンポーネントを再利用することがメリットです。
ところがCSS ModuleやGTMのタグを入れようとするとちょっと面倒でした。
ReactͰ੩తαΠτδΣωϨʔτ2018-09-15
View Slide
ReactͷͨΊͷ੩తαΠτδΣωϨʔτͰͳ͍
react-staticGatsbyNext.js
クライアントで処理しない
メリットReactコンポーネントが再利用できる軽量・高速
デメリットReactが活きてないやってる人が別にいない
仕組み
サーバーサイドレンダリングするだけ
const writeFilePage = async ({filename,Page}: {filename: string,Page: Component}): Promise<{ path: string, html: string }> => {const content = ReactDOMServer.renderToStaticMarkup();const html = `${content}`;const path = `public/${filename}`;await fs.mkdirp(dirname(path));await fs.writeFile(path, html);return { path, html };};
ReactDOMServer.renderToStaticMarkup
簡単
つらいこと
CSS Module採用したらつらかった
CSS Module雑に言うと• CSSセレクタ用のクラス名が被らない• JS上でimportできる
CSS Moduleの仕組みを雑に
.article {font-size: 16px;}goro.css
CSS Moduleとして処理すると
._article_xkpkl_10 {font-size: 16px;}goro.css
{"article": "_article_xkpkl_10",}一緒にこんなjsonができる感じ
使うとき
import { article } from ‘./goro.css'# 実質生成された.jsonを読み込む感じ() => GoroJavascript
Goro出力
Import するのは css であって jsonではないCSSとJSを事前処理しないといけない困る点
解決策Webpackのloaderが対応している
• nodejs向けのコードを生成するようにする• target: 'node' (webpack.config.js)• 生成されたコードを実行する• node main.jsWebpackの導入
{"scripts": {"build": "webpack && node dist/main.js"}}package.json
他につらいこと
解析用のJavaScriptの挿入
// @flowimport React from 'react';export const GTMInit = ({ id }: { id: string }) => (dangerouslySetInnerHTML={{__html: `(function(w,d,s,l,i){ w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});varf=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer', "${id}");`}}/>);export default GTMInit;
·ͱΊ
Reactで静的サイトそんなに難しくない
やりこむとつらい