カスタムコンテンツ04.next [次へ]

カスタムヘッド

これがデフォルトのヘッドであります

このようなヘッドは、内蔵コンポーネントに追加された要素のために記載されている.next我々のニーズを満たしていない<head>ラベル。私たちは、このカスタムヘッドを使用することができます

新しいコンポーネント/ Head.js

import { Fragment } from "react";
import Head from "next/head";

function MyHead() {
  return (
    <Fragment>
      <Head>
        <meta charset="utf-8"></meta>
        <meta name="referrer" content="origin"></meta>
        <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1"></meta>
        <meta name="keywords" content="next.js,react.js"></meta>
        <meta content="next 简介 next.js作为一款轻量级的应用框架,主要用于构建静态网站和后端渲染网站。 next 特点 默认情况下由服务器呈现 自动代码拆分可加快页面加载速度 简单的客户端路由(基于页面) 基于"></meta>
        <title>蓝猫</title>
      </Head>
    </Fragment>
  );
}

export default MyHead;

重複ラベルを避けるために、あなたは<head>必ずラベルが一度だけ表示させるためにキープロパティを使用することができます

MyLayout.jsで導入

import Head from "./Head";

......
      <Fragment>
        <Head />
        <Header />
        <div className={"content"}>{children}</div>
        <Footer />
      </Fragment>
......

使用中、頭のタグを追加することが完了した後、しかし<meta charset="utf-8"></meta>、それは2を追加して表示された場合、ヘッドアセンブリの文字セットを削除します。

カスタムサーバー

次のスタートは、実際には、サーバーを開くために使用することであった前に、次の既存のルートおよびパターンを含む、カスタムサーバーをサポートしています。

新server.js

const express = require("express");
const next = require("next");

const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();

app
  .prepare()
  .then(() => {
    const server = express();

    server.get("/m/:id", (req, res) => {
      const actualPage = "/marked/[id]";
      const queryParams = { id: req.params.id };
      app.render(req, res, actualPage, queryParams);
    });

    server.get("*", (req, res) => {
      return handle(req, res);
    });

    server.listen(6776, err => {
      if (err) throw err;
      console.log("> Ready on http://localhost:6776");
    });
  })
  .catch(ex => {
    console.error(ex.stack);
    process.exit(1);
  });

package.jsonを変更し、コンテンツを追加

    "server:dev": "node server.js",
    "server:start": "NODE_ENV=production node server.js",

// localhostを::HTTP入力し6776、ページのロードが正常に我々はいくつかの余分な仕事をしたレンダリングされ、通常の訪問は、ページのレンダリングのハイライトを入力する/ 1をマークしたが、エイリアスからカスタムフォームで、我々はそれにM / 1を入力してください。同じページへの直接ポイント。

次の(OPTS:オブジェクトを)持っているアプリはから作成されます

  • 開発モードではデフォルトでNext.js-偽を開始するかどうかDEV(ブール値)
  • 場所DIR(文字列)は、次のプロジェクトに位置して - 「」デフォルト
  • 静かな(ブール値)サーバ情報隠しのエラーメッセージ - デフォルトはfalse
  • CONF(オブジェクト){}再構成デフォルトnext.config.js-

ファイルシステムのルーティングを無効にします

JSファイルがサーバーに保存されている静的ファイルを一致する次/ページになります。これは、/インデックスにつながる可能と/index.htmは、このページにアクセスすることができます。特にカスタムルートの使用は、動作はから同じコンテンツにつながる可能性があり= SEOとUXの問題につながる可能性があり、複数のパスによって提供。

// next.config.js
module.exports = {
  useFileSystemPublicRoutes: false,
}

useFileSystemPublicRoutesはSSRからのルーティングファイル名のみを無効にし、クライアントはこれらのルーティングパスにアクセスすることができます。

クライアントは、クライアント・ファイル・システムと一致するようにルーティングを禁止したい、popstate傍受を使用しています。

ダイナミックassetPrefix

時には私たちは、この時間は、我々はapp.setAssetPrefixを使用するために必要な変更をassetPrefixに基づいて要求に応じて、例えば、ダイナミックルーティングを必要とします

server.get("*", (req, res) => {
    if (req.headers.host === "my-app.com") {
    app.setAssetPrefix("http://cdn.com/myapp");
    } else {
    app.setAssetPrefix("");
    }

    return handle(req, res);
});

無効にX-Poweredのバイ

Next.jsは、x駆動-によってリクエストヘッダに付加しました。これは、言語パーサーやアプリケーションフレームワークからの出力です。この意味でサイトを知らせるために使用されるものの値は、言語やフレームワークで書かれています。

これを無効にダイレクト

// next.config.js
module.exports = {
  poweredByHeader: false,
}

カスタムアプリ

上記の次のレンダリングプロセスで、アプリページを使用して初期化される次のコンポーネントは次のアプリが初期化するために来てカバーすることができます

  • ページレイアウトで持続的な維持することです
  • ページを切り替えたときの状態を保持します
  • カスタムエラー処理を使用します componentDidCatch
  • インジェクション・データ・ページ

新しいページ/ _app.js

import React from "react";
import App from "next/app";

class MyApp extends App {
  render() {
    const { Component, pageProps } = this.props;
    return (
      <div className="my-app">
        <Component {...pageProps} />
      </div>
    );
  }
}

export default MyApp;

getInitialPropsは、カスタム設定がアプリケーションに自動的に静的な最適化に影響を与えます追加します

カスタムドキュメント

  • カスタム<Document>一般的に拡張するために使用<html>し、<body>ラベル
  • サービス側のレンダリングには
  • サーバーを初期化するとき、文書のマークアップ要素を追加します。
  • 通常、実装され、サーバー側のレンダリングは、このようなスタイルのコンポーネント、華やかや感情など、いくつかのCSS-で-JSライブラリを使用します。スタイル-JSXはNext.jsがデフォルトCSS-で-jsのライブラリが付属しています

新しいページ/ _document.js

import Document, { Html, Head, Main, NextScript } from "next/document";

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx);
    return { ...initialProps };
  }

  render() {
    return (
      <Html>
        <Head />
        <body>
          <div className="document">
            <Main />
            <div className="inner-document"></div>
            <NextScript />
          </div>
        </body>
      </Html>
    );
  }
}

export default MyDocument;

フックgetInitialPropsはパラメータが同じオブジェクトCTXある受信しました

  • RenderPageコールバック関数は、(同期)関数を実行しますロジックをレンダリング、このアプローチは、この機能にアフロディーテのrenderStaticや他のコンテナをレンダリングするいくつかのサーバー側に似た何かをサポートするのに役立ちます反応します。

注意:<Main />外的 React 组件将不会渲染到浏览器中,所以那添加应用逻辑代码。如果你页面需要公共组件(菜单或工具栏),可以参照上面说的 App 组件代替。

自定义 renderPage

使用 renderPage 的唯一原因是 css-in-js 库需要包裹当前应用并且在服务端渲染下也能正常工作

static async getInitialProps(ctx) {
  const originalRenderPage = ctx.renderPage

  ctx.renderPage = () =>
    originalRenderPage({
      // useful for wrapping the whole react tree
      enhanceApp: App => App,
      // useful for wrapping in a per-page basis
      enhanceComponent: Component => Component,
    })

  // Run the parent `getInitialProps` using `ctx` that now includes our custom `renderPage`
  const initialProps = await Document.getInitialProps(ctx)

  return initialProps
}

自定义错误页面

客户端和服务器端的 404 或 500 错误默认由 error.js 组件处理。

新建 pages/_error.js 覆盖

import React from 'react'

function Error({ statusCode }) {
  return (
    <p>
      {statusCode
        ? `An error ${statusCode} occurred on server`
        : 'An error occurred on client'}
    </p>
  )
}

Error.getInitialProps = ({ res, err }) => {
  const statusCode = res ? res.statusCode : err ? err.statusCode : 404
  return { statusCode }
}

自定义配置 / 自定义 Webpack 配置 / 自定义 babel 配置

当前的配置./next.config.js

const fetch = require("isomorphic-unfetch");
const withBundleAnalyzer = require("@zeit/next-bundle-analyzer");
const withLess = require("@zeit/next-less");
const FilterWarningsPlugin = require("webpack-filter-warnings-plugin");

if (typeof require !== "undefined") {
  require.extensions[".less"] = file => {};
}

function HACK_removeMinimizeOptionFromCssLoaders(config) {
  config.module.rules.forEach(rule => {
    if (Array.isArray(rule.use)) {
      rule.use.forEach(u => {
        if (u.loader === "css-loader" && u.options) {
          delete u.options.minimize;
        }
      });
    }
  });
}

module.exports = withBundleAnalyzer(
  withLess({
    poweredByHeader: false,
    analyzeServer: ["server", "both"].includes(process.env.BUNDLE_ANALYZE),
    analyzeBrowser: ["browser", "both"].includes(process.env.BUNDLE_ANALYZE),
    bundleAnalyzerConfig: {
      server: {
        analyzerMode: "static",
        reportFilename: "../bundles/server.html"
      },
      browser: {
        analyzerMode: "static",
        reportFilename: "../bundles/client.html"
      }
    },
    exportPathMap: async function() {
      const paths = {
        "/": { page: "/" },
        "/books": { page: "/books" },
        "/article": { page: "/article" },
        "/write": { page: "/write" }
      };

      const res = await fetch("https://api.tvmaze.com/search/shows?q=batman");
      const data = await res.json();
      const shows = data.map(entry => entry.show);

      shows.forEach(show => {
        paths[`/book/${show.id}`] = {
          page: "/book/[id]",
          query: { id: show.id }
        };
      });

      return paths;
    },
    lessLoaderOptions: {
      javascriptEnabled: true
    },
    webpack(config) {
      config.plugins.push(
        new FilterWarningsPlugin({
          exclude: /mini-css-extract-plugin[^]*Conflicting order between:/
        })
      );
      HACK_removeMinimizeOptionFromCssLoaders(config);
      return config;
    }
  })
);

当前的.babelrc

{
  "presets": ["next/babel"],
  "plugins": [
    [
      "import",
      {
        "libraryName": "antd",
        "style": "less"
      }
    ]
  ]
}

Doc

おすすめ

転載: www.cnblogs.com/mybilibili/p/11725443.html