次はじめに
Next.jsは、軽量、サーバー側レンダリングアプリケーションフレームワークが反応であります
次の特長
- サーバーによってレンダリングデフォルトで
- コード自動分割は、ページの読み込みを高速化することができます
- (ページに基づいて)単純なクライアントのルーティング
- WebPACKのベースの開発環境は、ホットモジュール交換(HMR)をサポートしています
- Expressまたは他のNode.js HTTPサーバで達成することができます
- バベルは、独自のカスタム設定とのWebPACKを使用することができます
システム要件
Next.jsは一緒に使用するWindows、MacとLinuxに使用することができます。あなただけのNext.jsアプリケーションの構築を開始するために、システム上のNode.jsをインストールする必要があります。より良いエディタがあれば
プロジェクトを初期化します
mkdir next-demo
cd next-demo
npm init -y // 快速创建package.json而不用进行一些选择
npm install --save react react-dom next
mkdir pages
次の世代には、次のページのjs JSX TSXファイルに従ってルーティングされるためは、mkdirページこのステップでは、ページと呼ばれるファイルフォルダを作成する必要があります
そして、次のデモファイルpackage.jsonディレクトリを開き、次のスクリプトを置き換えます。
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
}
開発用サーバを起動するには、次のコマンドを実行します。
npm run dev
あなたはできるようになりましオープンはlocalhost:3000あなたは、以下のコマンドを実行し、3000ポートの競合を好きではない場合、結果ページを参照するには
npm run dev -p 6688(你喜欢的端口)
6688の結果のページを参照してください。私たちはローカルホストにすることができます。この時間
こんにちは世界
この時点では、フォルダのホームページとしてindex.jsを作成します
const Index = () => (
<div>
<p>Hello Next.js</p>
</div>
);
export default Index;
現在のページはハロー世界を示して6688あなたが見ることができます:localhostをもう一度確認してください
ページ間のナビゲーション
次のルーティングは非常に単純な、新しいページ/ about.jsに実装します
export default function About() {
return (
<div>
<p>This is the about page</p>
</div>
);
}
この訪問はlocalhostで:6688 /については、対応する結果のページ(ルーティングページと完全一致でファイル名を)見ることができます
ページ間のナビゲーション、我々は、ラベルに移動することができますが、それは、クライアント側のナビゲーションを実行しません。また、サーバーあたりのクリックのブラウザは、次のページを要求し、同時にページを更新します。したがって、クライアントのナビゲーションをサポートするために、我々は、リンクAPIのNext.js、次/リンクをエクスポートすることにより、APIを使用する必要があります。リンクがページをプリフェッチし、ナビゲーションはページを更新することなく実行されます。
リンクAPIを使用します
ページ/ index.jsを変更
import Link from 'next/link';
const Index = () => (
<div>
<Link href="/about">
<a>About Page</a>
</Link>
<p>Hello Next.js</p>
</div>
);
export default Index;
再び訪問はlocalhost:6688を、次いで約ページインデックスに戻るには、ブラウザの[戻る]ボタンをクリックし、ページジャンプの後についてのページをクリックしてください。..
次/リンクは唯一の高次成分(高次成分)、次に配置された小道具であるため、/リンクアセンブリ無効。hrefが唯一の小道具などを受け入れる。あなたが小道具を追加する必要がある場合、下位のコンポーネントを追加する必要があります。次/小道具は、サブアセンブリに合格しないアセンブリをリンクし、あなたに警告エラーになります。この場合は、次の/サブアセンブリリンクアセンブリ/受信要素は、好ましくは、スタイルやその他の小道具のキャリアです任意のコンポーネントまたはラベルすることができ、唯一の要件は、onClickイベントを受け入れることができるということです。
<Link href="/about">
<a className="redLink">About Page</a>
</Link>
<Link href="/show">
<div>Show Page</div>
</Link>
これは、クライアントのナビゲーションで、操作は鑑賞用の開発ツールのネットワークを開くために、サーバーに要求を加えることなく、ブラウザで行われます。
パッケージ
現在Next.jsコードがページ上にある。私たちは、およびエクスポートすることにより、その後、それはファイル名に基づいて固定されたURLを持つことになりますが、同時に共有コンポーネントの数がプロジェクトもする必要があります。ページを作成するページ・ディレクトリにアセンブリの構成要素を反応することができます我々は複数のページに共通のヘッダーおよびコンポーネントを作成します。
新しいコンポーネント/ Header.js
import Link from "next/link";
const linkStyle = {
marginRight: 15
};
const Header = () => (
<div>
<Link href="/">
<a style={linkStyle}>Home</a>
</Link>
<Link href="/about">
<a style={linkStyle}>About</a>
</Link>
<Link href="/show">
<a style={linkStyle}>Show</a>
</Link>
</div>
);
export default Header;
Index.jsはその後/ about.js / show.js下のページのディレクトリを変更します
import Header from '../components/Header';
export default function Index() {
return (
<div>
<Header />
<p>Hello Next.js</p>
</div>
);
}
オープンはlocalhost:6688をクリックして3のリンクボタンで前後のページ間のジャンプします
私たちは/ページ。ディレクトリには任意の名前を命名することができます。コンポーネントという名前のディレクトリに私たちのコンポーネントを必要としないと/静的は特別ですが、ページ内の共有コンポーネントを作成していない、多くの無効を生成します経路案内。
レイアウトコンポーネント
私たちのアプリケーションでは、各ページに、一般的なスタイルを使用します。これを行うために、我々は一般的なレイアウト・コンポーネントを作成し、私達のページのそれぞれのためにすることができます。
コンポーネント/ MyLayout.js
import Header from './Header';
const layoutStyle = {
margin: 20,
padding: 20,
border: '1px solid #DDD'
};
const Layout = props => (
<div style={layoutStyle}>
<Header />
{props.children}
</div>
);
export default Layout;
Index.jsはその後/ about.js / show.js下のページのディレクトリを変更します
import Layout from '../components/MyLayout';
export default function Index() {
return (
<Layout>
<p>Hello Next.js</p>
</Layout>
);
}
さらなる成分はまた、アドホック取得したコンテンツ配信属性は小道具を使用して送信を使用することができます
動的なページ
実用的なアプリケーションでは、我々は動的なコンテンツを表示する動的なページを作成する必要があります。
最初のページ/ about.jsファイルを変更
import Layout from "../components/MyLayout";
import Link from "next/link";
const PostLink = props => (
<li>
<Link href={`/post?title=${props.title}`}>
<a>{props.title}</a>
</Link>
</li>
);
export default function About() {
return (
<Layout>
<h1>My Blog</h1>
<ul>
<PostLink title="Hello Next.js" />
<PostLink title="Learn Next.js is awesome" />
<PostLink title="Deploy apps with Zeit" />
</ul>
</Layout>
);
}
ページ/ post.jsを作成します
import { useRouter } from 'next/router';
import Layout from '../components/MyLayout';
const Page = () => {
const router = useRouter();
return (
<Layout>
<h1>{router.query.title}</h1>
<p>This is the blog post content.</p>
</Layout>
);
};
export default Page;
オープンはlocalhost:6688タイトルページにそこに対応することになる、およそ次の三つの記事をクリックして、結果ページを参照するには
- これは、クエリ文字列パラメータ(クエリパラメータ)、クエリ文字列を通過したデータの任意のタイプを介してデータを渡します。
- 私たちは、インポートし、機能をuseRouter使用し、次/ルータ機能はNext.jsルータオブジェクトを返します。
- 私たちは、クエリ文字列パラメータを取得するためにクエリを使用します
- 必要なパラメータにrouter.query.titleタイトルを取得します。
投稿ページにも、一般的なヘッダを追加することができます
import { useRouter } from "next/router";
import Layout from "../components/MyLayout";
const Content = () => {
const router = useRouter();
return (
<Layout>
<h1>{router.query.title}</h1>
<p>This is the blog post content.</p>
</Layout>
);
};
const Page = () => (
<Layout>
<Content />
</Layout>
);
export default Page;
もう一度確認のlocalhost:6688を別の見て
ダイナミックルーティング
現時点では、私たちのルートはそうです。http:// localhostを:6688 /ポストタイトル=こんにちは%20Next.js、今よりきれいなルーティングを必要とします。http:?// localhostを:. 6688 / P / 10私たちを作成するために、新しいページを追加します最初の動的ルーティングP / [ID]の.js
新しいページ/ P / [ID]の.js
import { useRouter } from 'next/router';
import Layout from '../../components/MyLayout';
export default function Post() {
const router = useRouter();
return (
<Layout>
<h1>{router.query.id}</h1>
<p>This is the blog post content.</p>
</Layout>
);
}
- 以降の処理は次のルーティング/ P /たとえば、/ P /れるページ処理ハローnextjsする。なお、/ P /ポスト-1 /別のではありません。
- 角カッコは、ダイナミックルーティングします。そして、ダイナミックルーティングを照合するとき、あなたは完全な名前を使用する必要があります。例えば、/ページ/ P / [ID] .jsファイルはサポートではなく/pages/p/post-[id].jsサポート。
- 動的ルーティングを作成する場合、角括弧の間に配置された我々のIDは、受信したページへのクエリパラメータの名前であるため、/ Pは/クエリオブジェクトは、{ID:「ハローnextjs」}であるハローnextjs、我々はuseRouterを使用することができます。 ()それにアクセスします。
リンク複数のページ、新しいページ/ page.js
import Layout from '../components/MyLayout';
import Link from 'next/link';
const PostLink = props => (
<li>
<Link href="/p/[id]" as={`/p/${props.id}`}>
<a>{props.id}</a>
</Link>
</li>
);
export default function Blog() {
return (
<Layout>
<h1>My Blog</h1>
<ul>
<PostLink id="hello-nextjs" />
<PostLink id="learn-nextjs" />
<PostLink id="deploy-nextjs" />
</ul>
</Layout>
);
}
このページでは、我々は見て の要素は、ブラウザのURLバーに表示されるべきであり、ブラウザの履歴に関連して使用されるように、ページhref属性pをフォルダのパス、URL.as。
リモートデータ収集
実際に、私たちはしばしば、我々はページ上のリモートデータソースにデータを取得できるように、我々は一般的にこれを行うには、非同期機能getInitialPropsを使用しています。彼らは、ページデータを取得するための標準的なAPIを持っているリモート・データ・ソース・.Next.jsからデータを取得する必要がありますページの.getInitialProps端に小道具は、サーバーとクライアントで使用することができると、それを渡します。
我々は最初のライブラリのデータを取得する必要があります
npm install --save isomorphic-unfetch
次に、ページ/ index.jsを変更
import Layout from '../components/MyLayout';
import Link from 'next/link';
import fetch from 'isomorphic-unfetch';
const Index = props => (
<Layout>
<h1>Batman TV Shows</h1>
<ul>
{props.shows.map(show => (
<li key={show.id}>
<Link href="/detail/[id]" as={`/detail/${show.id}`}>
<a>{show.name}</a>
</Link>
</li>
))}
</ul>
</Layout>
);
Index.getInitialProps = async function() {
const res = await fetch('https://api.tvmaze.com/search/shows?q=batman');
const data = await res.json();
console.log(`Show data fetched. Count: ${data.length}`);
return {
shows: data.map(entry => entry.show)
};
};
export default Index;
我々は、サーバー上でレンダリングされるため、現状では、我々は、サーバー上のデータを取得します。
その後、詳細ページを作成し、ここでは、ダイナミックルーティングを使用します
新しいページ/詳細/ [ID]の.js
import Layout from "../../components/MyLayout";
import fetch from "isomorphic-unfetch";
import Markdown from "react-markdown";
const Post = props => (
<Layout>
<h1>{props.show.name}</h1>
<div className="markdown">
<Markdown source={props.show.summary.replace(/<[/]?p>/g, "")} />
</div>
<img src={props.show.image.medium} />
<style jsx global>{`
.markdown {
font-family: "Arial";
}
.markdown a {
text-decoration: none;
color: blue;
}
.markdown a:hover {
opacity: 0.6;
}
.markdown h3 {
margin: 0;
padding: 0;
text-transform: uppercase;
}
`}</style>
</Layout>
);
Post.getInitialProps = async function(context) {
const { id } = context.query;
const res = await fetch(`https://api.tvmaze.com/shows/${id}`);
const show = await res.json();
return { show };
};
export default Post;
カジュアルでオープンネットワークコンソールとブラウザでリストをクリックすると、これは、ブラウザのインターフェイス要求がわかります。
スタイルコンポーネント
JSフレームワークでNext.jsは、それはあなたがコンポーネントおなじみのCSSルールを記述することができます。CSSを書くのはあなたのコードが容易になり、-JSXスタイルのプリロードされたCSSと呼ばれる。成分以外のルール(あるいはサブコンポーネント)の何も何の効果は、単にCSSのスコープではありません。
ページ/ page.jsを変更
import Layout from "../components/MyLayout";
import Link from "next/link";
function getPosts() {
return [
{ id: "hello-nextjs", title: "Hello Next.js" },
{ id: "learn-nextjs", title: "Learn Next.js is awesome" },
{ id: "deploy-nextjs", title: "Deploy apps with ZEIT" }
];
}
export default function Blog() {
return (
<Layout>
<h1>My Blog</h1>
<ul>
{getPosts().map(post => (
<li key={post.id}>
<Link href="/p/[id]" as={`/p/${post.id}`}>
<a>{post.title}</a>
</Link>
</li>
))}
</ul>
<style jsx>{`
h1,
a {
font-family: "Arial";
}
ul {
padding: 0;
}
li {
list-style: none;
margin: 5px 0;
}
a {
text-decoration: none;
color: red;
}
a:hover {
opacity: 0.6;
}
`}</style>
</Layout>
);
}
上記のコードでは、テンプレート文字列に直接書き込み、そしてCSSで記述されたテンプレートの文字列( `` {})を使用しなければなりません。
この時点で、コードを変更
import Layout from "../components/MyLayout";
import Link from "next/link";
function getPosts() {
return [
{ id: "hello-nextjs", title: "Hello Next.js" },
{ id: "learn-nextjs", title: "Learn Next.js is awesome" },
{ id: "deploy-nextjs", title: "Deploy apps with ZEIT" }
];
}
const PostLink = ({ post }) => (
<li>
<Link href="/p/[id]" as={`/p/${post.id}`}>
<a>{post.title}</a>
</Link>
</li>
);
export default function Blog() {
return (
<Layout>
<h1>My Blog</h1>
<ul>
{getPosts().map(post => (
<PostLink key={post.id} post={post} />
))}
</ul>
<style jsx>{`
h1,
a {
font-family: "Arial";
}
ul {
padding: 0;
}
li {
list-style: none;
margin: 5px 0;
}
a {
text-decoration: none;
color: blue;
}
a:hover {
opacity: 0.6;
}
`}</style>
</Layout>
);
}
スタイルJSXこの文体がスコープであるため、ブラウザは、オープン観察が有効ではないでしょう。この時、CSSは現在のスコープに適用されます。
1を解決する、サブコンポーネントは、スタイルのサブコンポーネントに加え
const PostLink = ({ post }) => (
<li>
<Link href="/p/[id]" as={`/p/${post.id}`}>
<a>{post.title}</a>
</Link>
<style jsx>{`
li {
list-style: none;
margin: 5px 0;
}
a {
text-decoration: none;
color: blue;
font-family: 'Arial';
}
a:hover {
opacity: 0.6;
}
`}</style>
</li>
);
2解決し、グローバルスタイル
<style jsx global>{`
......css
`}
一般的にグローバルスタイルを解決するために使用されていません
グローバルスタイルを使用します
時々、私たちは、スタイルのサブコンポーネント、特にいくつかのサードパーティのライブラリを使用すると、いくつかは、時間のスタイルに満足していないの内部を変更する必要があります。
インストールが反応し、マークダウン
npm install --save react-markdown
ページ/ post.jsを変更
import { useRouter } from "next/router";
import Layout from "../components/MyLayout";
import Markdown from "react-markdown";
const Content = () => {
const router = useRouter();
return (
<Layout>
<h1>{router.query.title}</h1>
<div className="markdown">
<Markdown
source={` # Live demo
Changes are automatically rendered as you type.
## Table of Contents
* Implements [GitHub Flavored Markdown](https://github.github.com/gfm/)
* Renders actual, "native" React DOM elements
* Allows you to escape or skip HTML (try toggling the checkboxes above)
* If you escape or skip the HTML, no dangerouslySetInnerHTML is used! Yay!
## HTML block below
<blockquote>
This blockquote will change based on the HTML settings above.
</blockquote>`}
/>
</div>
<style jsx global>{`
.markdown {
font-family: "Arial";
}
.markdown a {
text-decoration: none;
color: blue;
}
.markdown a:hover {
opacity: 0.6;
}
.markdown h3 {
margin: 0;
padding: 0;
text-transform: uppercase;
}
`}</style>
</Layout>
);
};
const Page = () => (
<Layout>
<Content />
</Layout>
);
export default Page;
オープンはlocalhost:6688についてのページスタイルの効果を見るためにクリック
[他の解決策](https://github.com/zeit/next.js#css-in-js)
導入されたUIライブラリー
現在のページスタイルで提示したコードは、このポイントに開発のラインを開くことが原則に付着し、よりカジュアルで、我々は少し造園をご覧ください。
以下の紹介
まず、必要なライブラリをインストールします
npm install --save @zeit/next-less less
次いで、内部インラインスタイルヘッダ除去mylayout
新しい資産/ CSS / styles.less
.header {
display: block;
z-index: 500;
width: 100%;
height: 60px;
font-size: 14px;
background: #fff;
color: rgba(0, 0, 0, 0.44);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
letter-spacing: 0;
font-weight: 400;
font-style: normal;
box-sizing: border-box;
top: 0;
&:after {
box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.07);
display: block;
position: absolute;
top: 60px;
color: rgba(0, 0, 0, 0.07);
content: "";
width: 100%;
height: 2px;
}
.header-inner {
width: 1000px;
margin: 0 auto;
a {
height: 60px;
line-height: 60px;
font-size: 18px;
color: #c7c7c7;
cursor: pointer;
margin-right: 25px;
&:hover {
font-size: 18px;
color: #2d2d2f;
}
}
}
}
.content {
width: 1000px;
margin: 0 auto;
padding-top: 30px;
}
next.config.jsを変更
// next.config.js
const withLess = require('@zeit/next-less')
module.exports = withLess({
/* config options here */
})
MyLayout内部で少ないの紹介
import "../assets/css/styles.less";
ローカルホストでは:6688ビューページには、適切なスタイルを表示されます
導入antd
npm install antd --save
npm install babel-plugin-import --save-dev
touch.babelrc
.babelrc
{
"presets": ["next/babel"],
"plugins": [
[
"import",
{
"libraryName": "antd",
"style": "less"
}
]
]
}
antdスタイルの導入後
資産/ CSS / styles.less
@import "~antd/dist/antd.less";
この時間は、通常はそれを使用することantdアセンブリに導入され、
import { Typography, Card, Avatar } from "antd";
const { Title, Paragraph, Text } = Typography;
エラー解決
ValidationErrorを:無効なオプションオブジェクト。CSS LoaderはAPIスキーマと一致していないオプションのオブジェクトを使用して初期化されています。 - オプションは、未知のプロパティ「最小化」を有します。これらのプロパティは有効です。#541
新しいバージョンのCSS-ローダーとのWebPACKあり、このような間違いは、これはアップグレードコードの変更は、CSS-ローダは全くこのオプションを最小化している、つながっていません。
ソリューションは、next.config.js内のコードの除去を追加します
const withLess = require("@zeit/next-less");
if (typeof require !== "undefined") {
require.extensions[".less"] = file => {};
}
function HACK_removeMinimizeOptionFromCssLoaders(config) {
console.warn(
"HACK: Removing `minimize` option from `css-loader` entries in Webpack 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 = withLess({
lessLoaderOptions: {
javascriptEnabled: true
},
webpack(config) {
HACK_removeMinimizeOptionFromCssLoaders(config);
return config;
}
});
アプリケーションデプロイメントNext.js
今すぐインストール、静的リソースサーバホスティング
npm i -g now
now
静的リンクを生成します一定の時間を待った後、道を開くために、あなたのページhttps://next-demo.fuhuodemao.now.sh/を見ることができますクリックしてください
コードの生産環境をパッケージング
スクリプトpackage.jsonを見ます
"dev": "next -p 6688",
"build": "next build",
"start": "next start -p 6688",
今すぐコードとプレビューを生成するためのコマンドを実行
npm run build // 构建用于生产的Next.js应用程序
npm start // 在6688端口上启动Next.js应用程序.该服务器将进行服务器端渲染并提供静态页面
ローカルホストでは:6688の私たちは、同じ効果を見ることができます
オープン複数のポート
スクリプトコマンドを変更します。
"start": "next start -p 6688",
実行してnpm start
、我々はlocalhostをすることができます:8866上でアプリケーションを再度開きます
ウィンドウ内の追加ツールクロスENVの必要性
npm install cross-env --save-dev