Rabu, 26 October 2022

Welcome to Next.js 13!

Next.js 13 sudah keluar, dan pastinya ada beberapa major rilis disini yang mungkin akan mengejutkan kita, atau bahkan biasa saja.

Next.js

Next.js 13 sudah keluar, dan pastinya ada beberapa major rilis disini yang mungkin akan mengejutkan kita, atau bahkan biasa saja. Tapi kita akan mulai dulu dari apa yang baru dalam Next.js 13 ini.

Turbopack (Alpha)

Turbopack adalah successor dari webpack sendiri yang dibangun dengan bahasa Rust, yang itu sudah pasti tidak di ragukan lagi kecepatannya. Berikut adalah perbandingan Next.js dengan Next.js.

  1. 700x lebih cepat dari pada Webpack
  2. 10x lebih cepat dari pada Vite
  3. 4x lebih cepat dari pada cold start Webpack

Next.js with Turbopack

Turbopack saat ini hanya mendukung untuk next dev, belum untuk next build. Turbopack juga belum mendukung postcss dan tailwindcss.

Jangan khawatir, karena turbopack masih alpha. Jadi ini masih akan terus dikembangkan sampai stabil.

Nah untuk menggunakannya, kita bisa menambahkan --turbo pada next dev nya yang ada di scripts pada file package.json seperti:

{
    "name": "irsyadnotes.com",
    "version": "0.1.0",
    "private": true,
    "scripts": {
        "dev": "next dev --turbo",
        "build": "next build",
        "start": "next start",
        "lint": "next lint",
        "format": "prettier --write ."
    },
    ...
}

Setelah itu, kita bisa jalankan ulang seperti biasa seperti:

npm run dev

Atau jika mau directly dari terminal bisa juga, jalankan perintah berikut:

npx next dev --turbo

Oia, karena turbopack ini belum mendukung yang namanya Postcss dan juga Tailwindcss, maka jika project kita ada tailwindcss nya, dia akan mengeluarkan peringatan semacam warning yang kurang lebih akan seperti ini:

Warning: You are using configuration that may require additional
setup with Turbopack. If you already made these changes please
ignore this warning.

- PostCSS detected (postcss.config.js)
  PostCSS is not yet supported by Next.js v13 with Turbopack.
  To use with Turbopack, see: https://nextjs.link/turbopack-postcss

- Tailwind detected (tailwind.config.js)
  Tailwind is not yet supported by Next.js v13 with Turbopack.
  To use with Turbopack, see: https://nextjs.link/turbopack-tailwind

Jadi pastikan Anda akan menggunakan next js dengan turbopack ini jika memang Anda tidak memakai Postcss ataupun Tailwindcss. Wajar kok, karena ini masih alpha rilis, nanti lama-kelaman pasti didukung juga kok. Kita tinggal nunggu tanggal main nya aja, kapan mereka ready, ya kita tunggu aja.

Next Image

Salah satu kebanggaan kita menggunakan menggunakan next/image ini adalah sangat meningkatkan yang namanya Core Web Vitals, yang mana itu adalah salah satu yang harus kita miliki saat kita bicara tentang SEO friendly.

Dan itu adalah pengakuan dari komunitas yang sudah memakai next/image di environment production, sehingga memang sudah terbukti ke optimalannya. Dan di versi Next 13 ini, next/image juga mendapat update yang sangat luar biasa.

Jika dulu kita tidak mudah mengkonfigurasi nya, sekarang harusnya akan lebih mudah. Dan juga, kita diwajibkan untuk memberikan alt ketika menggunakan next/image ini.

import Image from "next/image";

function Home() {
    return <Image alt="irsyadadl" src="picture.png" placeholder="blur" />;
}

Next Font

Dalam versi 13 ini, Next.js sendiri memperkenalkan sistem font baru yang lebih optimal untuk kita. Berikut adalah fitur baru yang diberikannya:

  1. Optimasi font secara otomatis baik dari cdn maupun custom
  2. Menghapus external network requests untuk meningkatkan privasi dan kinerja
  3. Otomatis menggunakan size-adjust
  4. Hosting mandiri otomatis bawaan untuk file font apa pun

Berikut adalah penulisan untuk menggunakan font, dan dalam contoh ini. Kita menggunakan font dari google yaitu adalah Inter.

import { Inter } from '@next/font/google';

const inter = Inter();

<html className={inter.className}>

Next Link

Dulunya ketika kita menggunakan next/link ini, kita diwajibkan untuk menambahkan <a> didalamnya. Namun sejak versi 13 ini, itu tidak lagi jadi masalah. Saya sendiri juga sangat bersukur akan hal ini, karena rasanya gak enak aja membuat link yang terlihat seperti 2 kali.

Sebelumnya, kita akan melakukan hal ini:

import Link from 'next/link';

<Link href="/articles">
    <a className='text-violet-600'>
        Articles
    </a>
</Link>

Namun sekarang, kita tidak perlu lagi khawatir tentang anchor itu.

import Link from 'next/link';

<Link className='text-violet-600' href="/articles">
    Articles
</Link>

app/ Directory (Beta)

Next.js meningkatkan routing dan layout sistem nya di versi Next.js 13 ini dnegan memperkenalkan kita folder baru yaitu app/.

Fitur Dasar

Beberapa fitur yang bisa kita dapat dari app/ ini adalah:

  1. Layouts
  2. Server components
  3. Streaming
  4. Suspense for Data Fetching

Jangan khawatir, kita akan bahas satu persatu dari fitur ini.

Install Next.js 13

Untuk memulainya, mari kita lakukan instalasi Next.js versi 13 dengan memberi flag --experimental-app. Buka terminal dan jalankan perintah berikut:

npx create-next-app@latest --experimental-app next-13

Nanti akan di tanya, kita ingin pakai typescript / eslint atau tidak, jadi kurang lebih tampilannya akan seperti ini:

Need to install the following packages:
  [email protected]
Ok to proceed? (y)
✔ What is your project named? … next-13
✔ Would you like to use TypeScript with this project? … No / Yes

Gunakan tombol kanan kiri untuk pilih no / yes pada keyboard. Jika kita pilih typescript, maka dia akan melakukan instalasi dependencies seperti berikut:

Installing dependencies:
- react
- react-dom
- next
- typescript
- @types/react
- @types/node
- @types/react-dom
- eslint
- eslint-config-next

Setelah itu selesai, maka silakan buka project ini di text editor yang Anda pakai, dan harusnya akan sudah ada folder baru yang itu sejajar dengan pages.

.
├── app
├── pages
│   └── api
└── public

Didalam folder app akan ada beberapa file seperti css dan file typescript react seperti:

app
├── globals.css
├── layout.tsx
├── page.module.css
└── page.tsx

Layouts

Anda bisa perhatikan pada file layout.tsx yang itu isinya adalah layout dari halaman kita, ada head, meta, title dan sebagainya. Kurang lebih tampilannya akan seperti ini:

import './globals.css';

export default function RootLayout({ children }: { children: React.ReactNode }) {
    return (
        <html lang='en'>
            <head>
                <title>Create Next App</title>
                <meta name='description' content='Generated by create next app' />
                <link rel='icon' href='/favicon.ico' />
            </head>
            <body>{children}</body>
        </html>
    );
}

Karena ini adalah root layout kita, jadi kita legal untuk memasukkan semacam navigasi yang kita inginkan. Dalam folder app ini, saya akan buat file navbar.tsx untuk komponen navigasi kita, yang isinya kurang lebih seperti:

import React from 'react';
import Link from 'next/link';

export default function Navbar() {
    return (
        <nav>
            <ul>
                <li>
                    <Link href='/'>Home</Link>
                </li>
                <li>
                    <Link href='/posts'>Posts</Link>
                </li>
            </ul>
        </nav>
    );
}

Kemudian, mari kita masukan komponen navbar ini kedalam root layout kita.

import './globals.css';
import Navbar from "./navbar";

export default function RootLayout({ children }: { children: React.ReactNode }) {
    return (
        <html lang='en'>
            <head>
                <title>Create Next App</title>
                <meta name='description' content='Generated by create next app' />
                <link rel='icon' href='/favicon.ico' />
            </head>
            <body>
                <Navbar/>
                {children}
            </body>
        </html>
    );
}

Setelah itu, buka file page.tsx untuk kemudian memodifikasinya menjadi seperti ini:

export default function Home() {
    return (
        <div>
            <h1>Welcome to Next.js 13!</h1>
            <p>
                The home page.
            </p>
        </div>
    )
}

Setelah itu, mari kita buka terminal untuk menjalankan dev server nya seperti:

npm run dev

Buka browser Anda dan kunjungi alamat yang diberikan nya. Biasanya itu adalah http://localhost:3000/.

Struktur Posts

Waktu pembuatan navigasi itu, saya sengaja membuat halaman artikel, yang jika di kunjungi itu akan pergi ke 404. Baik, sekarang mari kita buat 1 folder dengan nama posts, dan didalamnya kita buat file dan folder yang kurang lebih struktur nya seperti:

app/posts
├── [id]
│   └── page.tsx
└── page.tsx

Data Fetching

Buka file page.tsx dan kita akan melakukan fetching data seperti layakanya kita melakukannya di folder pages.

import { use } from 'react';
import Link from 'next/link';

const getPosts = async () => {
    let posts = await fetch('https://dummyjson.com/posts?limit=7');
    return posts.json();
};

type Post = { id: any; title: string; };

export default function PostLayout() {
    let { posts } = use(getPosts());
    return (
        <div>
            <h1 className='text-2xl'>Post page</h1>
            {posts.map((post: Post) => (
                <Link href={`/posts/${post.id}`} key={post.id}>
                    <div>{post.title}</div>
                </Link>
            ))}
        </div>
    );
}

Anda bisa perhatikan pada bagian use, itu adalah hook yang kita dapat dari React sendiri. Yang mana itu juga dikembangkan dari React suspense. Kurang lebih, use ini sama seperti sewaktu kita menggunakan getStaticProps dan getServerSideProps.

Regular Function

Pertama, kita fetch datanya seperti layaknya menggunakan regular function pada javascript:

const getPosts = async () => {
    let posts = await fetch('https://dummyjson.com/posts?limit=7');
    return posts.json();
};

use Hook

Setelah itu, panggil dia tepat di dalam komponen kita melalui use hook seperti:

import { use } from 'react';
import Link from 'next/link';

const getPosts = async () => {...};

export default function PostLayout() {
    let { posts } = use(getPosts());
    return (...);
}

Params

Sekarang, mari kita buka halaman [id]/page.tsx untuk mengambil id yang kita dapat dari posts ini:

export default function Page({ params }) {
    let id = params.id;
    return <div>Post of id: {id}</div>;
}

Saya sengaja tidak melakukan data fetching di komponen, yang seharusnya Anda ia. Saya hanya ingin memastikan bahwa Anda sekarang mengerti konsep nya.

Loading

Dulunya sewaktu kita menggunakan react suspense, yang biasa kita lakukan adalah kurang lebih seperti ini:

<Suspense fallback={<LoadingSkeleton/>}>
    {/* ... */}
</Suspense>

Sekarang, untuk melakukan hal itu, Anda hanya perlu membuat 1 file di dalam folder app dengan nama loading.tsx. Setelah itu semua akan di konfigurasi otomatis, tidak perlu cek apakah data ada dan sebagainya.

export default function Loading() {
    return (
        <div>
            Loading...
        </div>
    );
}

Mantap tidak ? Oia jangan lupa untuk membaca-baca lagi lebih jauh tentang update ini.

Next.js API seperti getServerSideProps, getStaticProps dan getInitialProps tidak akan di dukung di direktori app ini.

Fitur Secara Detail

Berikut ini adalah detail-detail fitur yang di dukung dalam folder app ini:

Dokumentasi Baru

Harus diakui bahwa dokumentasi baru yang dibuat oleh tim Next.js ini benar-benar 🔥. Yang dulunya tidak mendukung mode gelap dan sekarang sudah mendukung. Tidak sekedar itu, dokumentasi baru ini juga mengizinkan kita berkomentar, quote, bahkan memberi reaction. Namun karena belum siap, ini masih di klaim sebagai beta docs untuk Next.js.

Kesimpulan

Hal yang baru akan terus muncul di dalam dunia teknologi ini, tinggal kita saja yang bisa atau tidak mengikutinya. Kita adalah web developer, bukan tuhan. Jadi kita legal untuk tidak harus mengetahui segala-galanya. Saya Irsyad, I'll see you next time.