🙆‍♀️

Next.js × Tailwind.cssでAMP対応させてみる

2021/07/23に公開

こちらを参考にさせていただきながら(なぞりながら)やってみました。詳しい解説はこちらの方が良いです。
https://sunday-morning.app/posts/2020-12-25-next-js-10-tailwind-2-hybrid-amp

まずはNext.js × Tailwind.cssの環境構築

以前自分が作ったコマンドを調整して(storybookを外して)環境構築を行いました。
https://zenn.dev/dl10yr/articles/0e31819e983a28

 git clone -b not-including-storybook git@github.com:dl10yr/nextjs-setup.git next-amp 

https://github.com/dl10yr/nextjs-setup/tree/not-including-storybook

sh nextjs-setup.sh -n test
yarn dev

とりあえずbuildできることを確認する

AMP対応の作業

ここからが実際のAMP対応の作業になります。

ちなみにこのcommitがAMP対応の作業に該当します。
https://github.com/dl10yr/nextjs-tailwind-amp/commit/6d4a7964533507df512aa91ee85b28f2ab411395

postcssを使ってcssの容量削減

yarn add -D cssnano @fullhuman/postcss-purgecss postcss-cli
postcss.config.js
/* eslint-disable @typescript-eslint/no-var-requires, no-undef */
const purgecssOption = {
  content: ['./pages/**/*.{js,jsx,ts,tsx}', './components/**/*.{js,jsx,ts,tsx}'],

  defaultExtractor: (content) => content.match(/[\w-/:]+(?<!:)/g) || [],
}

module.exports = {
  plugins: [
    require('tailwindcss'),
    require('autoprefixer'),
    require('@fullhuman/postcss-purgecss')(purgecssOption),
    require('cssnano')({
      preset: 'default',
    }),
  ],
}
tailwind.config.js
-  purge: ['./pages/**/*.tsx', './components/**/*.tsx'],

こっちのpurgeは消しとく

scriptsの追加

package.json
  "scripts": {
    "dev": "yarn build-css && next dev",
    "build": "yarn build-css && next build && next export",
    ...
    "build-css": "postcss styles/globals.css --config postcss.config.js -o styles/output.css"
  },

raw-loaderを使ってcssを文字列としてインポートできるようにする

yarn add -D raw-loader
next.config.js
/* eslint-disable @typescript-eslint/no-var-requires, no-undef */
module.exports = {
  webpack: (config) => {
    config.module.rules.push({
      test: /\.css$/,
      use: "raw-loader",
    });

    return config;
  },
}
_document.tsx
/* eslint-disable @typescript-eslint/ban-ts-comment */
import Document, { Head, Html, Main, NextScript } from 'next/document'
import React from 'react'
// @ts-ignore
import outputcss from '!raw-loader!../styles/output.css'

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    return {
      ...initialProps,
      styles: (
        <>
          {initialProps.styles}
          <style
            dangerouslySetInnerHTML={{
              __html: outputcss,
            }}
          />
        </>
      ),
    }
  }

  render() {
    return (
      <Html>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default MyDocument

AMP用のページを用意して確認する

exampleのページを適当に用意

example.tsx
import React from 'react'
import Head from 'next/head'

export const config = {
  amp: true,
}

const example: React.FC = () => {
  return (
    <div className="min-h-screen p-2.5 bg-red-100">
      <Head>
        <title>dl10yr</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className="flex flex-wrap">
        <div className="w-full lg:w-2/3">
          <div className="p-3">
            <h2 className="text-xl font-bold text-cdorange">ああああ</h2>
          </div>
        </div>
        <div className="w-full lg:w-1/3 pt-12 px-5">
          <p>ああああ</p>
        </div>
      </main>
    </div>
  )
}

export default example

App.tsx
- import '../styles/globals.css'

cssのimport文は不要なので消去する

yarn dev

App.vueからimport文を消しても、CSSが適用されていることが確認できます。

このエラーはどうしても出てしまうみたいです。

deployしたページ

https://dl10yr.com/blog/hello-world
いい感じです。

Discussion