[Next.js]私たちのサイトに翼を差し込む(1)
ロゴから好きな次はjsについて知りましょう!
*サーバ側のレンダリング?(SSR)
サーバ側レンダリングとは、サーバ側でレスポンスコードを実行してレンダリングすることです.
では、なぜサーバ側レンダリングが必要なのでしょうか.
もしそうなら、各社が生き残るためには、ユーザーの前に十分に露出しなければならない.
Google以外の検索エンジンではJavaScriptは実行されないため、クライアントレンダリングのみを行うサイトはコンテンツのないサイトと同じ扱いになります
=>GoogleもSSRサイトのスコアを高くしています.
では次はjsを使用する前に、直接的なサーバ側レンダリング環境を構築します.
#サーバ・エンド・レンダー・プリミティブ
mkdir test-ssr
cd test-ssr
npm init -y
npm install react react-dom
npm install @babel/core @babel/preset-env @babel/preset-react
npm install webpack webpack-cli babel-loader clean-webpack-plugin html-webpack-plugin
1.クライアントでのみレンダリング
プロジェクトルートディレクトリにsrcフォルダを作成し、その下にホームを作成します.js, About.jsファイルを作成します.
各ファイルは、Webサイトのページを表し、ページ切り替えをテストします.
// Home.js
import React from "react";
export default function Home() {
return (
<div>
<h3>This is home page</h3>
</div>
);
}
// About.js
import React from "react";
export default function Ablut() {
return (
<div>
<h3>This is about page</h3>
</div>
);
}
この家.jsとAbout.jsをレンダリングするAppコンポーネントを作成します.アプリケーションコンポーネントは、ボタンを介して各ページに移動する機能を提供します.
import React, { useState, useEffect } from "react";
import Home from "./Home";
import About from "./About";
export default function App({ page }) {
const [page, setPage] = useState(page);
useEffect(() => {
window.onpopstate = (e) => {
setPage(e.state);
};
}, []);
function onChangePage(e) {
const newPage = e.target.dataset.page;
window.history.pushState(newPage, "", `/${newPage}`);
setPage(newPage);
}
const PageComponent = page === "home" ? Home : About;
return (
<div className="container">
<button data-page="home" onClick={onChangePage}>
Home
</button>
<button data-page="about" onClick={onChangePage}>
About
</button>
<PageComponent />
</div>
);
}
onpopstateって何ですか?* onpopstate(MDN)
つまり、popstateでサーバ側でレンダリングすると、2つのページ間でstateをコピーできるので、state管理が可能になります!
srcフォルダの下にあるindex.jsファイルを作成し、前に作成したAppコンポーネントをレンダリングします.
import React from "react";
import ReactDom from "react-dom";
import App from "./App";
ReactDom.render(<App page="home" />, document.getElementById("root"));
今からパッケージを設定しましょう!(WebPackが一番難しいと思います)プロジェクトルートディレクトリでwebpackを使用します.config.jsファイルを作成し、次のコードを入力します.
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js",
output: {
filename: "[name].[chunkhash].js",
path: path.resolve(__dirname, "dist"),
},
module: {
rules: [
{
test: /\.js$/,
use: "babel-loader",
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./template/index.html",
}),
],
mode: "production",
};
templateフォルダを作成し、その下にindexを作成します.htmlファイルを作成します.<!DOCTYPE html>
<html>
<head>
<title>test-ssr</title>
</head>
<body>
<div id="root" />
</body>
</html>
バーベルをセットするバーベル設定ファイルを作成してJavaScriptファイルをコンパイルします.
ルートにbabelnofigがありますjsファイルの作成
const presets = ["@babel/preset-react", "@babel/preset-env"];
const plugins = [];
module.exports = { presets, plugins };
babel.config.jsファイルの設定はbabel-loader実行時に適用されます.クライアントの表示を確認します!!
Webspecを実行します.
npx webpack
これはだめです.
これでいいです.
urlはfile://で始まるため、push Stateメソッドを呼び出すとエラーが発生します.これは、サーバを直接移動することで解決できます.
もちろん、最初のリクエストに対する応答として返されるHTMLには、ボタンや文を表すドーム要素はありません.ボタンまたは文のドーム要素は、JavaScriptを実行するときに追加されます.ブラウザオプションでJavaScriptの実行が許可されていない場合は、画面に何も表示されません.
2.サーバー側レンダリング関数の使用を試みる
4つのサーバ・エンド・プレゼンテーション関数
npm install express @babel/cli @babel/plugin-transform-modules-commonjs
expressパッケージをインストールしてWebサーバを解放します.@babel/cliパッケージをインストールして、サーバが使用するJavaScriptファイルをコンパイルします.=>サーバもJSX構文作成のJavaScriptを実行する必要があります.
ESMで作成したモジュールシステムをcommonJSに変更するために、後ろにパッケージをインストールしました.
Webサーバコードを記述するには、次の手順に従います.
srcフォルダの下にあるサーバ.jsファイルを作成し、次のコードを入力します.
import express from 'express';
import fs from 'fs';
import path from 'path';
import { renderToString } from 'react-dom/server';
import React from 'react';
import App from './App';
const app = express();
const html = fs.readFileSync(
path.resolve(__dirname, '../dist/index.html'),
'utf8'
);
app.use('/dist', express.static('dist'));
app.get('/favicon.ico', (req, res) => res.sendStatus(204));
app.get('*', (req, res) => {
const renderString = renderToString(<App page='home' />);
const result = html.replace(
'<div id="root"></div>',
`<div id="root">${renderString}</div>`
);
res.send(result);
});
app.listen(3000);
本を読みながら書くだけで、知らないところが多いです.片付けようサーバとクライアントに必要なバーベルプラグインとプリセットは次のとおりです.
// .babelrc.common.js
const presets = ['@babel/preset-react'];
const plugins = [];
module.exports = { presets, plugins };
// .babelrc.client.js
const config = require('./.babelrc.common.js');
config.presets.push('@babel/preset-env');
module.exports = config;
// .babelrc.server.js
const config = require('./.babelrc.common.js');
config.plugins.push('@babel/plugin-transform-modules-commonjs');
module.exports = config;
一般的な設定は次のとおりです.babel.common.jsによって管理され、クライアント側とサーバ側がこれらの設定をインポートし、使用します.Webパッケージの設定
Webパッケージ設定ファイルでは、HTMLに追加されたバンドルファイルのパスとバーベル設定ファイルのパスを変更する必要があります.
パブリックパスとオプションが追加されました.
サーバ側コード@babel/cliを使用してバーベルのみを実行し、クライアントコードはWebパッケージを実行します.package.jsonを修正します.
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build-server": "babel src --out-dir dist-server --config-file ./.babelrc.server.js",
"build": "npm run build-server && webpack",
"start": "node dist-server/server.js"
},
サーバ側レンダリングではドーム要素が作成されているので、クライアントが再レンダリングする必要はありません.ただし、各ドーム要素に必要なイベント処理関数を接続する必要があります.イベント処理関数が接続されていない場合、画面ははっきり表示されますが、ユーザーがボタンを押しても反応しません.リアクターが提供する水和物関数は、サーバ側のレンダリング結果によって生成されたドーム要素に必要なイベント処理関数を追加します.
index.jsファイルに追加するには、水和物関数を使用します.
ReactDom.hydrate(<App page='home' />, document.getElementById('root'));
次に、次の操作を行います.npm run build
npm start
また、ブラウザからローカルホスト3000に接続することで、画面が正しくレンダリングされ、ページを切り替えるボタンが正常に動作することがわかります.
内容は少し長いですが、サーバーデータがクライアントに転送された部分から、次のブログに書くつもりです.
Reference
この問題について([Next.js]私たちのサイトに翼を差し込む(1)), 我々は、より多くの情報をここで見つけました https://velog.io/@cyheum/Next.js-우리의-사이트에-날개를-달아보자テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol