Next.js: Tanpa Server Berikutnya: buat ketergantungan `next` dev-only, perkenalkan `next-server` untuk build yang lebih kecil dan bootup yang lebih cepat

Dibuat pada 29 Mei 2018  ·  52Komentar  ·  Sumber: vercel/next.js

Masalahnya: saat mengoptimalkan build produksi, menjalankan next start atau menggunakan require('next') dalam server.js kustom melibatkan membawa seluruh rangkaian dependensi next , termasuk yang terkait secara eksklusif dengan pengembangan, seperti webpack .

Ini tidak hanya bermasalah dari sudut pandang gambar build dan kinerja waktu pengunduhan saat menghasilkan build produksi, tetapi juga kemungkinan akan mengganggu waktu boot. _Catatan: Ini dikurangi dengan fakta bahwa kami dengan hati-hati memuat dependensi berat seperti webpack dalam mode dev._

Untuk mereka yang sadar akan kinerja dan mereka yang sensitif terhadap _waktu mulai dingin_ (lihat misalnya: https://twitter.com/rauchg/status/990667331205447680), kami dapat memperkenalkan paket next-server .

Itu akan memiliki kemampuan yang sama dengan require('next') dikurangi semua pengaturan waktu pengembangan , ditambah next-server CLI yang sangat kecil yang dapat membuka port dan melakukan shutdown dengan baik.

Apa yang ingin kami optimalkan:

  • Total ketergantungan set next-server harus sekecil mungkin
  • Kami harus sangat mengoptimalkan waktu boot untuk memulai secepat mungkin

Selanjutnya, kita harus memberikan contoh di examples/ tentang cara menggunakan next-server dalam kombinasi dengan pkg untuk mengekspor aplikasi Next.js Anda sebagai biner ELF mandiri .

p1 feature request

Komentar yang paling membantu

Waktu mulai dingin yang kami lihat di Now 2.0 untuk frontend kami adalah 1,5 detik, untuk ukuran gambar 80mb IIRC

2018-05-29 16 50 37

Seharusnya dimungkinkan untuk membuatnya lebih dekat ke 1s tanpa perubahan apa pun pada Node atau V8 atau salah satu dependensi yang evaluasi dinginnya membutuhkan banyak waktu (seperti react dan react-dom )

Semua 52 komentar

Waktu mulai dingin yang kami lihat di Now 2.0 untuk frontend kami adalah 1,5 detik, untuk ukuran gambar 80mb IIRC

2018-05-29 16 50 37

Seharusnya dimungkinkan untuk membuatnya lebih dekat ke 1s tanpa perubahan apa pun pada Node atau V8 atau salah satu dependensi yang evaluasi dinginnya membutuhkan banyak waktu (seperti react dan react-dom )

wou, ini luar biasa!! :Hai

wah... bagus sekali.

beberapa pertanyaan untuk next-server .

  1. apakah ini akan menjadi server ekspres ringan?
  2. ya, apakah dapat dikonfigurasi dengan rute ekspres dan next-routes ?

@Nishchit14 Anda tidak akan menambahkan express jika Anda mencoba mengurangi ukuran build.

Saya yakin next-routes akan tetap berfungsi dengan baik.

Jadi yang kita bicarakan di sini adalah mengekstrak server yang ada ke dalam paketnya sendiri. Jadi ini akan bekerja dengan cara yang sama seperti sebelumnya, tetapi alih-alih mengimpor berikutnya, Anda mengimpor server berikutnya.

Ini luar biasa! Saya dan orang lain yang saya kenal telah menjalankan Next.js di atas AWS Lambda menggunakan scandium ( menggunakan panduan ini ) dan beberapa masalah utamanya adalah:

1) Ukuran paket. Lambda memberi Anda batas keras 50MB yang dapat dengan mudah didekati dengan semua alat pengembang yang disertakan.

2) Mulai dingin. Memiliki boot cepat sangat penting karena Lambda dapat memutuskan untuk memutar lebih banyak server kapan saja. Server yang ada juga aktif maksimal ~4 jam sehingga cold start akan menjadi penting di seluruh siklus hidup aplikasi.

Sangat senang melihat inisiatif ini dan senang membantu!

Ini adalah ide bagus, kami memiliki hal yang sama dengan Nuxt.js, kami menyebutnya nuxt-start karena itu adalah perintah yang Anda butuhkan untuk menjalankan nuxt start -> nuxt-start

Mengikuti ini dengan cermat. Sebagai titik data untuk apa yang mungkin, www.bustle.com adalah aplikasi preact SSR di AWS Lambda dengan cold start <1 detik. Seluruh file zip produksi yang digunakan adalah 166kb. Itu semua aplikasi dan kode perpustakaan. Webpack digunakan untuk bundling.

Terima kasih telah berbagi @southpolesteve. Itu sangat mengesankan. #sasaran

Kasing pengguna terlihat sangat mirip dengan micro dan micro-dev .

Mengapa tidak menggunakan nomenklatur yang sama? next dan next-dev

Saya bermain-main dengan next.js dan tanpa server menggunakan contoh ini dan ingin tahu apakah ada cara untuk menyelesaikan build yang lebih kecil sekarang. Apakah ada daftar node_modules yang sama sekali tidak kita perlukan dalam produksi dan dapat dikecualikan dengan file konfigurasi dalam packager seperti serverless atau repack-zip ?

@Enalmada Saya menjalankan next.js dengan beberapa deps dan material-ui menjadi salah satunya, saya memiliki aplikasi yang cukup besar dalam hal skala tetapi Zip bawaan yang saya unggah ke Lambda adalah ~ 45MB. Apa ukuran yang Anda cari?

@albinekb Saya terinspirasi oleh respons southpolesteve bustle.com di atas 166kb dan bertanya-tanya berapa banyak dari "45MB" saya yang tidak berguna dan mudah dihapus jika saya hanya tahu apa yang harus dimasukkan ke dalam file pengecualian dist sebagai peretasan sampai tiket yang luar biasa ini selesai .

@albinekb Sangat menyarankan Anda melihat menggunakan webpack, parcel, atau rollup untuk menggabungkan JS Anda untuk lambda. Anda akan menghemat ukuran, tetapi juga waktu boot karena mencapai sistem file melalui node normal memerlukan cukup lambat.

Jika Anda menerapkan ke ZEIT Now dan Anda ingin menjaga gambar Anda tetap kecil untuk boot dingin yang cepat, Anda dapat menggunakan alat seperti Package Phobia untuk memeriksa ukuran dependensi npm sebelum Anda menginstalnya (atau cukup periksa ukuran dependensi saat ini untuk memotong kembung).

Readme juga memiliki banyak alat serupa untuk membantu Anda melawan kembung. Lihat di sini: https://github.com/styfle/packagephobia

Bukankah ini seharusnya dibahas dalam rilis Next 7? :(

Jika Anda menggunakan zeit sekarang dan Anda ingin menjaga image Anda tetap kecil untuk fast cold boots, Anda dapat menggunakan alat seperti Package Phobia

Sialan kamu semut: https://packagephobia.now.sh/result?p=antd

@Enalmada mungkin dependensi antd yang bertanggung jawab, bukan perpustakaan itu sendiri. Saya telah mencarinya untuk https://packagephobia.now.sh/result?p=%40material-ui%2Fcore. Sebagian besar bobot berasal dari satu atau dua dependensi.

Bukankah ini seharusnya dibahas dalam rilis Next 7? :(

Untuk memperjelas tentang ini, Next.js 7 meletakkan dasar untuk Next.js Tanpa Server, kami telah menghapus sekitar 5 rute, hanya menyisakan 2 yang benar-benar diperlukan untuk produksi.

Adakah yang pernah mendapatkan next.js untuk bekerja dengan rollup? Saya merasa sudah sangat dekat...menjalankan rollup pada file dist 60m saya menurunkan ukurannya menjadi 6m. Sayangnya file dist tidak benar-benar memulai dan saya pikir itu karena ketergantungan melingkar tunggal dalam kode next.js yang merupakan peringatan selama rollup. Jika seseorang dapat mempertimbangkan kemungkinan menghapus ketergantungan melingkar pada kode next.js, kita semua mungkin sangat dekat dengan build yang jauh lebih kecil dan bootup yang lebih cepat:
https://github.com/zeit/next.js/issues/5392

Mengikuti ini dengan cermat. Sebagai titik data untuk apa yang mungkin, www.bustle.com adalah aplikasi preact SSR di AWS Lambda dengan cold start <1 detik. Seluruh file zip produksi yang digunakan adalah 166kb. Itu semua aplikasi dan kode perpustakaan. Webpack digunakan untuk bundling.

@southpolesteve apakah Anda dapat membagikan apa pun di sekitar konfigurasi bundel webpack Anda?

@shauns Sayangnya, saya tidak lagi sibuk dan tidak memiliki kode untuk dilihat lagi :/

@southpolesteve jangan khawatir! Senang mengetahui posisinya di webpack setidaknya.

Bisakah kami mendapatkan berita tentang server berikutnya? Saya melihat beberapa komitmen pada bulan ini yang lalu.

Periksa cabang kenari.

Kapan Anda berencana untuk merilisnya?

Saya tidak dapat membagikan garis waktu pada saat ini.

Baru saja mendarat #5927

@timneutkens Haruskah saya memindahkan next ke devDependencies dan menambahkan next-server ke dependensi saya atau apakah Anda melakukan ini secara otomatis melalui babel?
https://github.com/zeit/next.js/blob/canary/packages/next/build/babel/plugins/next-to-next-server.ts

@Skaronator jika Anda menerapkan menggunakan # 5927 bukan keduanya, sesuai spesifikasi itu akan menghasilkan satu bundel per halaman, tidak diperlukan ketergantungan. Berarti Anda dapat mengambil .next/serverless/index.js memerlukannya ( require('./.next/serverless/index.js') ) dan kemudian menyebutnya metode render :

const page = require('./.next/serverless/index.js')

page.render(req, res)

Ini akan membuat halaman dan menyelesaikan respons

Itu luar biasa!
Saya mencoba ini tetapi saya memiliki beberapa masalah untuk membuatnya bekerja di aws lambda. Apakah ada yang punya tips?

Saya kira kita tidak memerlukan server ekspres khusus lagi, kita bisa saja memerlukan file tanpa server berdasarkan jalurnya

edit
Ini tampaknya berhasil, perlu menggali lebih dalam untuk melihat cara mengoptimalkan langkah pembuatan:

const serverless = require("serverless-http");
const http = require('http');
const app = require('./.next/serverless/index.js');
const server = new http.Server((req, res) => app.render(req, res))
app.prepare().then(() => {
    const handler = serverless(server, {
        binary: binaryMimeTypes
    });
    return handler(event, context, callback);
});

Sepertinya Anda mengacaukan "server khusus" dengan "tanpa server", API mereka benar-benar terpisah, tidak ada metode .prepare dalam tanpa server karena tidak ada yang perlu disiapkan, kami segera merender halaman ke html dan menyelesaikan respon ketika render dipanggil.

const serverless = require("serverless-http");
const http = require('http');
const page = require('./.next/serverless/index.js');
const server = new http.Server((req, res) => page.render(req, res))
const handler = serverless(server, {
  binary: binaryMimeTypes
});
handler(event, context, callback);

Memang, dan saya tidak tahu mengapa kode di atas berfungsi (mungkin itu hanya cache) tetapi tidak satu pun dari saya atau kode Anda yang berfungsi karena serverless-http tampaknya tidak mendukung http.Server dan Saya tidak dapat mengembalikan page.render(req, res) karena objek event lambda tidak dapat menggantikan parameter render req ..

Juga, saya tidak ingin menggunakan express/koa/apa pun karena itu akan merusak seluruh tujuan fitur baru berikutnya.. ( serverless-http bebas ketergantungan jadi tidak apa-apa untuk digunakan)

aku kehabisan ide :/

Terima kasih @timneutkens , saya menghargai bantuan Anda.
Tetapi saat ini tidak berfungsi, saya masih memiliki kesalahan ini: typeError: Parameter "url" must be a string, not undefined

Saya akan berhenti mencemari utas ini dan terus menggali dan saya akan menulis contoh jika saya menemukan solusi

Saya agak tidak jelas. Utas ini sepertinya berlaku untuk dua skenario: aplikasi tanpa server dan server yang telah dikompilasi sebelumnya yang menyertakan semua paket npm sisi server yang diperlukan webpack'd bersama-sama.

Gif di komentar pertama di utas ini tampaknya menganggap skenario terakhir, yang merupakan salah satu yang saya minati. Sepertinya itu menggunakan next-server yang mungkin atau mungkin bukan paket npm ini --tidak 't memiliki repositori yang terlampir, dan saya tidak dapat menemukannya melalui pencarian google atau GitHub, meskipun salah satu tag versi adalah 8.0.0-canary.7--tag versi berikutnya--jadi saya menduga itu paket yang tepat.

Apakah yang saya tulis sejauh ini akurat? Jika demikian, meskipun dalam canary, apakah ada cara saya bisa mendapatkan akses awal ke sana?

Solusi saya saat ini (yang karena alasan yang jelas, saya tidak menggunakan di prod ) adalah menghapus fungsi dari config.externals di next.config.js .

Saya ingin sekali dapat menghasilkan server yang dibuat sebelumnya sehingga saya tidak perlu menginstal 200MB node_modules dan kemudian menghabiskan 2 menit mengkompilasi pada VM produksi kecil saya yang buruk setiap kali saya mendorong pembaruan.


* "prod" digunakan secara longgar, karena proyek ini bukan misi kritis atau profesional

Mengikuti ini dengan cermat. Sebagai titik data untuk apa yang mungkin, www.bustle.com adalah aplikasi preact SSR di AWS Lambda dengan cold start <1 detik. Seluruh file zip produksi yang digunakan adalah 166kb. Itu semua aplikasi dan kode perpustakaan. Webpack digunakan untuk bundling.

Target tanpa server Next.js 8 memiliki ukuran zip 42Kb secara default

Itu luar biasa! Menantikan ini!

Saya memiliki pertanyaan yang persis sama dengan @dfoverdx. Saya ingin membuat server build, yang juga mencakup semua node_modules yang diperlukan untuk menjalankan. Saya menggunakan server khusus dengan express jadi saya tidak berharap dependensi tersebut disertakan dalam paket, tetapi sekarang Anda harus menginstal _all_ dependensi di server Anda juga (bereaksi, selanjutnya, aksio, ...).

Saya tidak mengerti bagaimana ini tidak secara default?
Mengemas semua dependensi dan dapat meminimalkannya akan membawa peningkatan kinerja sisi server yang signifikan atau apakah saya sepenuhnya salah di sini?

Timpa bagian externals dari konfigurasi webpack sebagai berikut mencakup sebagian besar dependensi:

module.exports = {
  webpack: (config, { dev }) => {
    config.externals = [];
    return config;
  })
};

Tetapi reaksi dan reaksi-dom masih diperlukan di server. Saya tidak tahu bagaimana memasukkannya juga ...

Sayangnya, tidak mungkin membuat server khusus dengan mode tanpa server saat ini. Dan jika Anda menggunakan mode normal, Anda perlu menyertakan next dan semua dependensinya karena _app.js yang dihasilkan di .next bergantung misalnya pada next/router

Mengapa mode non-serverless juga tidak dapat digabungkan berikutnya?

Sayangnya, tidak mungkin membuat server khusus dengan mode tanpa server saat ini. Dan jika Anda menggunakan mode normal, Anda perlu menyertakan next dan semua dependensinya karena _app.js yang dihasilkan di .next bergantung misalnya pada next/router

Perhatikan, bahwa sejak 8 berikutnya, Anda dapat meminta 'server berikutnya' alih-alih 'berikutnya' di server.js Anda, dan Anda hanya kehilangan hot reload selama pengembangan lokal dengan melakukan itu. Secara teori, ini memberi Anda kemampuan untuk melakukan CI build di server perantara dan tidak menyalin dependensi terkait Webpack ke instance produksi. Tapi kami belum mencobanya di proyek kami.

@ElvenMonky menunggu sesuatu seperti ini sejak setahun, tetapi tidak dapat menemukan apa pun tentang ini di dokumen atau contoh.

@timneutkens bisakah Anda memverifikasi ini?

Jika demikian, saya mungkin bereksperimen dengan pengaturan seperti itu, dan mengirim PR untuk dokumen/contoh.

Perhatikan, bahwa sejak 8 berikutnya, Anda dapat meminta 'server berikutnya' alih-alih 'berikutnya' di server.js Anda, dan Anda hanya kehilangan hot reload selama pengembangan lokal dengan melakukan itu

Sayangnya ini tidak berhasil.

Pertama, menjalankan build tanpa server dengan target server secara aktif diblokir dengan pesan berikut: "Tidak dapat memulai server ketika target bukan server. https://err.sh/zeit/next.js/next-start-serverless "

Kemudian, jika Anda memutuskan untuk melakukan build normal, maka file build merujuk hal-hal dari paket next secara langsung (seperti next/router dalam file _app.js yang dikompilasi untuk sisi server). Itu berarti barang next dan webpack harus tetap dalam produksi.

@ElvenMonky

Perhatikan, bahwa sejak 8 berikutnya, Anda dapat meminta 'server berikutnya' alih-alih 'berikutnya' di server.js Anda, dan Anda hanya kehilangan hot reload selama pengembangan lokal dengan melakukan itu.

Selanjutnya lakukan itu secara internal sebagai Plugin Babel seperti yang Anda lihat di sini:
https://github.com/zeit/next.js/blob/709850154754278d2fc86b987eebe1b3f0565255/packages/next/build/babel/plugins/commonjs.ts#L5 -L32

@sheerun seperti yang saya sebutkan juga di # 7011 Anda dapat menghilangkan belum terselesaikan next/router ketergantungan oleh transpiling next modul menggunakan next-transpile-modules Plugin.

Saya telah memotong dan menyesuaikan contoh untuk server ekspres khusus untuk menggambarkan solusinya: https://github.com/ElvenMonky/next.js/tree/custom-next-server-express/examples/custom-server-express

PS: Saya masih sangat senang dengan #5927 tidak masalah, bahwa aplikasi saya memerlukan semua yang terdaftar di TODO, belum lagi rute dinamis dan penyajian konten statis.
Kabar baiknya adalah bahwa solusi di atas tampaknya cocok dengan https://www.npmjs.com/package/next-serverless pengaturan server khusus, sehingga memungkinkan untuk menyebarkan berikutnya ke misalnya AWS Lambda tanpa batasan yang disebutkan di atas.

Perhatikan, bahwa sejak 8 berikutnya, Anda dapat meminta 'server berikutnya' alih-alih 'berikutnya' di server.js Anda, dan Anda hanya kehilangan hot reload selama pengembangan lokal dengan melakukan itu.

Saya telah menggunakan saran ini, tetapi sayangnya tidak dapat menggunakan Konfigurasi Runtime karena memerlukan next/config yang membutuhkan next .

Saya tidak tahu mengapa tetapi require('next/config') digunakan untuk bekerja dalam produksi tanpa next diinstal di node_modules dengan versi berikutnya 8.0.3 tetapi tidak bekerja dengan versi 8.1.0 berikutnya

Apakah mungkin untuk memindahkan next/config ke paket yang berbeda, seperti next-runtime-config ?
Atau next-runtime-vars (menghindari istilah config untuk menghindari kebingungan dengan next.config.js).

Beri tahu saya jika dapat diterima, saya akan membuat PR.

Hai semuanya! Masalah ini telah diterapkan sejak Next.js 8, dan masih ada di Next.js 9. Saya akan menutup ini setelah selesai. 😌

Maaf saya bingung dengan masalah ini: https://github.com/zeit/next.js/issues/7011
Saya belum memeriksa dengan target: "tanpa server"


Lihat komentar yang dihapus

Beberapa "next/*" dapat diganti dengan "next-server/*" , seperti:

  • berikutnya/config -> server/konfigurasi berikutnya
  • berikutnya/amp -> server berikutnya/amp
  • berikutnya/dinamis -> server berikutnya/dinamis
  • berikutnya/konstanta -> server/konstanta berikutnya
  • berikutnya/kepala -> server/kepala berikutnya

Tetapi ada beberapa yang tidak ada dukungan untuk pengoptimalan seperti yang disebutkan oleh OP untuk masalah ini.

  • berikutnya/router -> server-berikutnya/dist/lib/router/router (mungkin)? (Harus kosong atau harus membuang kesalahan jika digunakan di server)
  • berikutnya/tautan?

Tidak diperlukan karena inline bahkan di server (AKAIK)

  • berikutnya/aplikasi
  • berikutnya/dokumen

Hai semuanya! Masalah ini telah diterapkan sejak Next.js 8, dan masih ada di Next.js 9. Saya akan menutup ini setelah selesai.

Hai @Timer - Apakah Anda mengacu pada target servless, atau penggantian 'next' dengan 'next-server' ?

Jika kita mengganti next dengan server berikutnya, itu tidak mengubah ukuran folder node_modules kecuali dependensi package.json juga diperbarui.

Apakah ada contoh dari kedua pendekatan yang tersedia? dengan tanpa server, kasus penggunaan saya diterapkan ke AWS Lambda.

Pendekatan yang diuraikan dalam masalah awal berkembang menjadi target serverless , kami sarankan Anda menggunakannya.

@timneutkens serverless target tidak dan tidak dapat menyelesaikan masalah dengan server khusus, yang menggunakan rute dinamis. #5927 Bukan solusi untuk banyak aplikasi bisnis dunia nyata seperti dalam kasus saya, di mana kita harus menggunakan halaman yang dibuat secara dinamis, awalan aset, _app kustom, _dokumen dan _err: pada dasarnya semua yang dinyatakan dalam daftar TODO.
next-server memberi kita solusi parsial untuk diterapkan ke produksi tanpa ketergantungan pengembangan yang aneh saja, seperti webpack dan babel. Namun ini dapat dilakukan dengan beberapa retasan dan tarian kayu, yang sedang kita diskusikan di sini.

Saya mendapat kesan bahwa Anda memahami perbedaan ini dan berharap untuk melihat solusi yang lebih kuat suatu hari nanti untuk masalah awal seperti yang dijelaskan oleh @rauchg

Apakah halaman ini membantu?
0 / 5 - 0 peringkat