Wener Notes

NextJS Cookbook

约 2 分钟阅读
标签:实践手册
TypeScript
// 判断服务端
const isServer = typeof window === 'undefined';

配置问题排查

JavaScript
// 输出 Webpack 的匹配规则
config.module.rules.forEach((rule) => console.log(`Rule Test ${rule.test} Use`, rule.use));

页面基础代码

TypeScript
import React from 'react';
import { NextPage } from 'next';

const Page: NextPage = () => {
  return <div></div>;
};

export default Page;

API 基础代码

TypeScript
import { NextApiRequest, NextApiResponse } from 'next';

const handler = async (req: NextApiRequest, res: NextApiResponse) => {
  res.status(200).json({ version: process.env.APP_VERSION || '1.0.0' });
};

export default handler;

页面跳转

TypeScript
// 初始阶段跳转
Page.getInitialProps = async ({ res }) => {
  // 目标地址
  let targetUrl = '...';
  if (!res) {
    window.location.href = targetUrl;
  } else {
    res.writeHead(302, { Location: targetUrl });
    res.end();
  }
  return {};
};

// 页面内跳转
function MyPage() {
  const router = useRouter();
  useEffect(() => {
    if (!auth) {
      router.push('...');
    }
  }, []);
}

// API 跳转
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
  res.clearCookie('authenticated');
  res.writeHead(302, { Location: '/login' });
  res.end();
};

SSE - Servr-Send Event

TypeScript
import { NextApiRequest, NextApiResponse } from 'next';

export const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

// curl -Nv localhost:3000/test/see
// https://zeit.co/pricing#limits Zeit free only allowed 10s/req
// NOTE Zeit deploy not works - because the request will be buffered
// https://github.com/zeit/next.js/issues/9965
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Content-Type', 'text/event-stream;charset=utf-8');
  res.setHeader('Cache-Control', 'no-cache, no-transform');
  res.setHeader('X-Accel-Buffering', 'no');

  for (let i = 0; i < 5; i++) {
    res.write(`data: Hello seq ${i}\n\n`);
    await sleep(1000);
  }
  res.end('done\n');
};

export default handler;
html
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <title>EventSource test</title>
  </head>
  <body>
    <h1>EventSource test</h1>
    <ul></ul>

    <script type="text/javascript">
      var logger = document.getElementsByTagName('ul')[0],
        socket = new EventSource('/');

      var log = function (text) {
        logger.innerHTML += '<li>' + text + '</li>';
      };

      socket.onopen = function () {
        log('OPEN');
      };

      socket.onmessage = function (event) {
        log('MESSAGE: ' + event.data);
      };

      socket.addEventListener('update', function (event) {
        log('UPDATE(' + event.lastEventId + '): ' + event.data);
      });

      socket.onerror = function (event) {
        log('ERROR: ' + event.message);
      };
    </script>
  </body>
</html>

CSS 导入字体

JavaScript
config.module.rules.push({
  test: /\.(eot|woff|woff2|ttf)$/,
  use: {
    loader: 'url-loader',
    options: {
      limit: 100000,
      name: '[name].[ext]',
    },
  },
});

导入 SVG

TypeScript
// Typescript 确保不会出现类型错误
declare module '*.svg';

declare module '*.png';
declare module '*.jpg';
declare module '*.jpeg';
declare module '*.gif';

使用 @svgr/webpack

bash
yarn add --dev @svgr/webpack babel-loader
Packages@svgr/webpacknpm Package@svgr/webpackNPMbabel-loadernpm Packagebabel-loaderNPM
JavaScript
config.module.rules.push({
  test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
  use: [
    {
      loader: 'babel-loader',
    },
    {
      loader: '@svgr/webpack',
      options: {
        babel: false,
        icon: true,
      },
    },
  ],
});
JavaScript
// 区分 js 或 css 导入
config.module.rules.push({
  test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
  issuer: {
    test: /\.[tj]sx?$/,
  },
  use: ['babel-loader', '@svgr/webpack', 'file-loader'],
});

config.module.rules.push({
  test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
  loader: 'url-loader',
});

使用 inline-react-svg

  • 不可以 使用 tsconfig 中的 path
  • 会用 SVGO 优化
bash
yarn add --dev babel-plugin-inline-react-svg
json
{
  "presets": ["next/babel"],
  "plugins": ["inline-react-svg"]
}

关联信息

反向链接、本文链接的其他页面和外部资料。

References

GitHub6 条
其他外链2 条
最近更新commit 456b1b1Edit

On this page