Next.js telah dikritik hebat kerana pengendaliannya terhadap pembolehubah persekitaran. Walaupun ia telah dipertingkatkan selama bertahun-tahun, ia masih mempunyai beberapa keanehan yang boleh mengelirukan terutamanya apabila ia melibatkan pembolehubah awam yang terdedah melalui objek process.env.
Semua pembolehubah awalan NEXT_PUBLIC_ boleh diakses oleh pihak klien, tetapi seperti yang dinyatakan dalam dokumentasi rasmi, ia hanya tersedia pada masa binaan, oleh itu tidak boleh berubah pada masa jalan apabila digunakan dengan Docker.
Walaupun saya telah membincangkan isu ini pada masa lalu, saya telah menemui pendekatan lain yang mungkin menarik untuk diterokai, menggunakan pembolehubah yang dikongsi secara global yang boleh diubah semasa masa jalan.
Pembolehubah global sebahagiannya disokong oleh Next.js, tetapi kita boleh menggunakan polyfill untuk menyediakannya menggunakan skrip suntikan kecil.
// app/layout.tsx <script dangerouslySetInnerHTML={{ __html: `!function(t){function e(){var e=this||self;e.globalThis=e,delete t.prototype._T_}"object"!=typeof globalThis&&(this?e():(t.defineProperty(t.prototype,"_T_",{configurable:!0,get:e}),_T_))}(Object);`, }} />
Kod asal diambil daripada ulasan ini pada GitHub, dan ia pada asasnya mencipta objek globalThis global yang boleh digunakan untuk berkongsi pembolehubah antara klien dan pelayan. Polyfill akan datang dengan Next.js 14.x, tetapi nampaknya memecahkan objek globalThis dalam sesetengah penyemak imbas, itulah sebabnya kami menggunakan sifat __html untuk menyuntik kod terus ke dalam halaman.
Seterusnya, kita boleh menggunakan Zod untuk mengesahkan pembolehubah pada masa jalan dan membuang ralat jika pembolehubah tidak sah. Langkah ini penting untuk memastikan pembolehubah sentiasa tersedia dan sah, mengelakkan ralat masa jalan serta mendedahkan aplikasi kepada isu keselamatan.
npm install zod
Kami kemudian mencipta fail variables.ts yang akan mengandungi beberapa fungsi utiliti untuk mengambil pembolehubah daripada process.env dan menghantarnya dengan selamat ke jenis yang dijangkakan.
// lib/env.ts import { z } from 'zod'; // Load the variables export const load = () => { return process.env; }; // Parse or throw the variables export function parseOrThrow(schema: z.Schema, data: unknown, error: Error) { const parsed = schema.safeParse(data); // Log the errror if (parsed.success) return parsed.data; console.error(parsed.error); throw error; } // Some zod helpers to use export const port = z .string() .refine( (port) => parseInt(port) > 0 && parseInt(port) < 65536, 'Invalid port number' ); export const str = z.string(); export const url = z.string().url(); export const num = z.coerce.number(); export const bool = z.coerce.boolean();
load ialah fungsi mudah yang mengembalikan objek process.env, manakala parseOrThrow ialah fungsi utiliti yang menghuraikan pembolehubah menggunakan skema Zod dan melemparkan ralat jika pembolehubah tidak sah.
Akhir sekali, kita boleh mencipta fail variables.ts yang akan mengandungi skema pembolehubah dan fungsi utiliti untuk memuatkan dan menghuraikan pembolehubah.
// lib/vars.ts import { z } from 'zod'; import { load, parseOrThrow } from './env'; import { parseOrThrow, load, str, num, bool, port } from './env'; // Define the variables schema const schema = z.object({ PUBLIC_VARIABLE: str.optional(), PUBLIC_MY_NUM: num, PUBLIC_BOOL: bool, PUBLIC_PORT: port, }); export const loadEnv = () => { const env = load(); const parsed = parseOrThrow(schema, env, new Error('Invalid variables')); for (const key of Object.keys(parsed)) { if (!globalThis[key]) { globalThis[key] = parsed[key]; } } };
Untuk menggunakan pembolehubah, kita perlu memuatkannya terlebih dahulu. Kami boleh melakukannya dalam fail app/layout.tsx atau mana-mana fail susun atur lain untuk mendedahkannya secara beransur-ansur kepada seluruh aplikasi, pada klien dan pelayan.
// app/layout.tsx import { loadEnv } from '@/lib/vars'; loadEnv(); export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <body>{children}</body> </html> ); }
Atas ialah kandungan terperinci Next.js Pembolehubah Awam. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!