Tutorial Node.js: Mulakan dengan Node.js

Node.js, persekitaran runtime JavaScript lintas platform untuk pelayan dan aplikasi, menawarkan banyak faedah. Penggunaan memori yang rendah, prestasi yang baik, dan pakej ekosistem yang besar, yang kini berjumlah sekitar 475,000, menjadikan Node.js sebagai pilihan popular untuk membina pelayan web, API REST, aplikasi rangkaian masa nyata (misalnya sembang, permainan), dan bahkan aplikasi desktop merentas platform.

Sekiranya anda belum memulakan dengan Node.js, mungkin sudah tiba masanya. Lihat penjelasan Node.js saya untuk mengetahui bagaimana Node.js berfungsi keajaibannya. Dalam artikel ini, kita akan melalui pemasangan Node.js dan pengurus pakej NPM, memutar pelayan web mudah, dan menggunakan modul kluster Node.js untuk memanfaatkan beberapa teras CPU.

Kami juga akan melihat pemasangan modul Node.js tambahan dan pakej JavaScript lain menggunakan pengurus pakej NPM. Dan kita akan menggunakan rangka kerja Node.js, dalam kes ini Koa, untuk membuat pelayan Node.js yang lebih kaya dengan ciri dan fleksibel.  

Mari kita mulakan.

Cara memasang Node.js dan NPM

Mulakan dengan melayari ke //nodejs.org:

Yayasan Node.js

Klik pada butang untuk muat turun LTS (sokongan jangka panjang), melainkan anda tahu bahawa anda memerlukan beberapa ciri baru dalam siaran semasa. Tepat bagaimana penampilan pemasang yang dimuat turun mungkin berbeza di antara sistem operasi, tetapi pada Mac ia kelihatan seperti ini pada awalnya:

Setelah pemasangan selesai, ia kelihatan seperti ini:

Sekarang anda harus memastikan bahawa Node.js dan NPM dipasang dengan betul. Buka shell baris perintah (Terminal pada Mac; Prompt pada Windows) dan periksa versi kedua-duanya yang dipasang:

$ node — penukaran

v6.11.3

$ npm — penukaran

3.10.10

Sekiranya anda mendapat ralat yang mengatakan bahawa Node.js atau NPM tidak dijumpai, cuba mulakan semula aplikasi shell anda atau reboot komputer anda. Sekiranya tidak berjaya, anda mungkin perlu mengedit $ PATH (Mac dan Linux) atau PATH (Windows) anda dan mulakan semula.

Kedua-dua Node.js dan NPM sesuai dengan versi yang dimaksudkan dalam tangkapan skrin Terminal di atas, jadi saya bersedia untuk bergerak maju dan benar-benar mengembangkan sesuatu dengan Node.js. Mari mulakan dengan sesuatu yang senang dibina dengan Node tulen.

Anda memerlukan editor kod atau IDE, lebih baik yang menyokong JavaScript dan Node.js seperti Teks Sublime, Kod Visual Studio, Kurungan, Atom, atau WebStorm.

Contoh Node.js: Pelayan web yang mudah

Untuk memulakan dengan sederhana, mari kita mencuri contoh mudah dari laman Node.js. Salin kod tersebut dan tampalkannya ke editor kod anda (saya menggunakan Visual Studio Code, tetapi mana-mana editor yang menyimpan teks biasa akan mencukupi), kemudian simpan sebagai contoh.js.

const http = memerlukan ('http');

const hostname = '127.0.0.1';

port const = 3000;

pelayan const = http.createServer ((req, res) => {

   res.statusCode = 200;

   res.setHeader ('Content-Type', 'text / plain');

   res.end ('Hello World \ n');

});

server.listen (port, nama host, () => {

   console.log (`Pelayan berjalan di // $ {hostname}: $ {port} /`);

});

Buka shell di direktori tempat anda menyimpan fail, dan jalankan fail dari baris arahan anda:

$ simpul contoh.js

Pelayan berjalan pada //127.0.0.1:3000/

Dalam kes saya, saya menggunakan tetingkap Terminal dalam Visual Studio Code. Saya dengan mudah menukar tingkap shell bebas.

Sekarang layari URL yang disenaraikan oleh pelayan:

Tekan Control-C di Terminal untuk menghentikan pelayan Node.

Sebelum meneruskan, mari kita hancurkan kodnya.

const http = memerlukan ('http');

Baris 1 menggunakan require, iaitu bagaimana anda memuat modul di Node.js. Pernyataan memuat modul Node.js http, yang membekalkan createServerkaedah yang disebut pada baris 6 hingga 10 dan listenkaedah yang disebut pada baris 12 hingga 14. Pengendali "anak panah lemak" =>pada baris 6 dan 12 adalah singkatan untuk membuat fungsi Lambda tanpa nama , yang sering digunakan dalam aplikasi Node.js.

pelayan const = http.createServer ((req, res) => {

  res.statusCode = 200;

  res.setHeader ('Content-Type', 'text / plain');

  res.end ('Hello World \ n');

});

The reshujah untuk createServer()selaras 6 digunakan untuk membina tindak balas; yang reqhujah mengandungi permintaan HTTP masuk, yang diabaikan dalam kod ini. The res.endCara menetapkan data tindak balas kepada 'Hello World \ n' dan memberitahu pelayan bahawa itu semua dilakukan mewujudkan tindak balas.

server.listen (port, nama host, () => {

  console.log (`Pelayan berjalan di // $ {hostname}: $ {port} /`);

});

Penutupan pelayan yang dihasilkan dengan server.listen()kaedah memberitahu pelayan untuk mendengar permintaan pada host yang ditentukan (127.0.0.1, misalnya localhost) dan port (3000). Penutupan yang dihasilkan dengan createServer()kaedah menangani permintaan ketika mereka masuk pada host dan port yang ditentukan.

Idea bahawa penutupan JavaScript didefinisikan sebagai pengendali acara adalah salah satu bahagian Node.js yang paling halus dan kuat, dan merupakan kunci kepada seni bina tanpa sekatan Node. Node.js menyembunyikan gelung acara, tetapi selalu beralih kepada menangani acara apabila tidak terlibat. Di samping itu, penutupan JavaScript menggunakan memori yang jauh lebih sedikit daripada kaedah alternatif untuk menangani pelbagai sambungan pelanggan, seperti benang pemijahan atau proses penempaan.

Contoh Node.js: Pelayan web pelbagai proses

Selain hanya mencetak "Hello World", contoh di atas hanya terdapat dalam satu utas, yang bermaksud bahawa ia hanya dapat menggunakan satu teras komputer host. Ada kalanya anda akan mempunyai banyak teras yang ingin anda curahkan kepada pelayan.

Contoh rasmi untuk modul kluster Node menunjukkan cara memperbaikinya. Seperti sebelumnya, kami akan mencuri kod dan menjalankannya. Semak imbas ke dokumentasi kluster Node.js, salin kodnya, tampal ke penyunting kod atau IDE anda, dan simpan sebagai pelayan.js.

const cluster = memerlukan ('cluster');

const http = memerlukan ('http');

const numCPUs = memerlukan ('os'). cpus (). panjang;

jika (cluster.isMaster) {

console.log (`Master $ {process.pid} sedang berjalan`);

// Pekerja garpu.

untuk (leti = 0; i

kluster.fork ();

}

cluster.on ('exit', (pekerja, kod, isyarat) => {

console.log (`pekerja $ {pekerja.process.pid} mati`);

});

} lain {

// Pekerja boleh berkongsi sebarang sambungan TCP

// Dalam kes ini, ia adalah pelayan HTTP

http.createServer ((req, res) => {

res.writeHead (200);

res.end (`hello world from $ {process.pid} \ n`);

}). dengar (8000);

console.log (`Worker $ {process.pid} bermula`);

}

Apabila anda melaksanakan node server.jsdari baris arahan anda, log akan memaparkan ID proses untuk proses master dan pekerja. Seharusnya terdapat seberapa banyak pekerja yang komputer anda mempunyai inti logik — lapan untuk MacBook Pro saya dengan pemproses Core i7, yang mempunyai empat teras perkakasan dan hyper-threading.

Sekiranya anda melayari ke localhost: 8000 atau ke 127.0.0.1:8000, anda akan melihat "hello world" dipaparkan. Anda boleh menekan Control-C di tetingkap terminal untuk menghentikan proses pelayan Node.

const cluster = memerlukan ('cluster');

const http = memerlukan ('http');

const numCPUs = memerlukan ('os'). cpus (). panjang;

Garis 1 dan 2 harus kelihatan biasa dari contoh terakhir. Baris 3 sedikit berbeza. Daripada hanya memerlukan osmodul, ia juga memanggil cpus()fungsi anggota dan mengembalikan panjang array yang dikembalikan, yang merupakan jumlah CPU. Susunan itu sendiri dan ospautan modul kemudiannya tidak dapat dicapai, dan mungkin sampah yang dikumpulkan oleh mesin JavaScript di lain waktu.

jika (cluster.isMaster) {

   console.log (`Master $ {process.pid} sedang berjalan`);

   // Pekerja garpu.

   untuk (let i = 0; i <num CPU; i ++) {

      kluster.fork ();

   }

   cluster.on ('exit', (pekerja, kod, isyarat) => {

      console.log (`pekerja $ {pekerja.process.pid} mati`);

   });

}

Baris 5 memulakan blok yang hanya berjalan untuk proses induk. Ini mencatatkan PID, garpu pekerja setiap CPU yang ada, dan membuat penutupan untuk menangani dan log peristiwa keluar kluster.

} lain {

   // Pekerja boleh berkongsi sebarang sambungan TCP

   // Dalam kes ini, ia adalah pelayan HTTP

   http.createServer ((req, res) => {

      res.writeHead (200);

      res.end ('hello world \ n');

   }). dengar (8000);

   console.log (`Worker $ {process.pid} bermula`);

Blok yang bermula pada baris 16 hanya dijalankan oleh proses pekerja. Kod ini seharusnya kelihatan biasa dari contoh sebelumnya: Ini membuat pelayan web yang bertindak balas terhadap permintaan apa pun dengan "hello world."

Sudah jelas dari output yang kita lihat di atas bahawa kod ini berlari lapan kali pada mesin saya, mewujudkan lapan pekerja pelayan web yang berkongsi sambungan TCP proses induk pada port 8000. Tetapi bagaimana sistem berkongsi beban di antara mereka?

Dokumentasi mengatakan bahawa modul kluster Node.js menggunakan algoritma round-robin yang diubah secara lalai, kecuali pada Windows. Algoritma dikendalikan oleh cluster.schedulingPolicysifat.

Bagaimana kita tahu bahawa ini berfungsi? Mari mengujinya. Hanya perlu mengubah satu baris kod. Edit baris 21 untuk membaca:

      res.end (`hello world from $ {process.pid} \ n`);

Perhatikan bahawa anda tidak hanya harus menambahkan from ${process.pid}, tetapi anda juga harus mengubah pembatas dari tanda kutip tunggal menjadi tanda centang belakang, sehingga JavaScript akan melakukan penggantian berubah pada rentetan.

Simpan fail, hentikan sebarang kejadian berjalan sebelumnya, dan jalankan lagi. Anda mungkin berfikir bahawa setiap kali anda menyegarkan semula klien penyemak imbas anda, ID proses yang dikembalikan akan berubah, tetapi anda salah. Penyemak imbas terlalu pintar, dan kami belum menandakan laman web sebagai laman web yang habis masa berlakunya, jadi penyemak imbas akan menyembunyikan respons pada kali pertama dijalankan dan terus menunjukkan nombor yang sama. Itu akan berlaku walaupun anda membuat beberapa tab penyemak imbas atau halaman yang menunjuk ke URL yang sama. Walau bagaimanapun, anda dapat melihat bahawa pengiriman round-robin dari master berfungsi dengan menjalankan beberapa penyemak imbas secara serentak, dalam hal ini Chrome, Safari, dan Opera:

Sekiranya anda biasa dengan pelayan web lain, anda mungkin akan melihat skema untuk permintaan penghalaan, dan untuk mengekalkan keadaan berterusan untuk memelihara setiap pengguna masuk dan persekitaran di Node. Sayangnya, Node tidak mempunyai bawaan itu. Jangan takut: Terdapat banyak kerangka web yang dibina di atas Node.js yang melakukan semua yang anda harapkan.

Cara memasang modul Node.js dengan NPM

Untuk menggunakan sebahagian besar modul Node, anda pada dasarnya hanya memasang modul dari pendaftaran NPM, baik secara global atau dalam direktori projek, dan kemudian require()dari kod anda. Selalunya projek bergantung pada beberapa modul NPM dan menyimpan senarai itu dalam fail projek.json. Daripada memasang setiap kebergantungan dari baris arahan, anda boleh memasangnya sekaligus, selalunya setelah memeriksa projek dari repositori GitHubnya:

$

$ cd my_projek

pemasangan $ npm

Tidak setiap pakej NPM berfungsi dengan betul. Beberapa, termasuk React, mempunyai aplikasi "kilang" untuk membuat aplikasi pemula sebagai salah satu pilihan pemasangannya.

$ npm install -g create-react-app

$ cd ~ / kerja

$ create-react-app my-app

$ cd aplikasi saya /

permulaan $ npm

Alat yang dipasang secara global tidak biasa. Sebagai contoh, alat baris arahan Ang dipasang oleh global. Anda kemudian menjalankannya secara tempatan untuk membuat aplikasi dalam folder.

$ npm pasang -g @ angular / cli

$ cd ~ / kerja

$ ng aplikasi baru saya

Sudut kebetulan mempunyai kaedah pemasangan lain yang lebih menyerupai corak standard. Itu untuk biji QuickStart Angular:

$ git clone //github.com/angular/quickstart.git memulakan

$ cd memulakan

pemasangan $ npm

Fail package.json dalam folder permulaan cepat memberitahu npm installuntuk mengambil senarai kebergantungan yang hampir sama dengan pemasangan CLI.

Contoh Node.js: Pelayan web Koa

Walaupun kedua-dua React dan Angular adalah sebahagian daripada ekosistem Node.js, dan memerlukan Node.js dan NPM untuk pembangunan, mereka bukan kerangka kerja Node.js secara khusus - mereka boleh berjalan di penyemak imbas. Saya merangkumi puluhan kerangka kerja Node.js yang sebenarnya dalam "Panduan lengkap untuk kerangka kerja Node.js."

Sebagai contoh, Express adalah pelayan web Node yang lengkap, mengendalikan aplikasi web, permintaan dan respons HTTP, penghalaan, dan perisian tengah. Pilihan yang lebih baru, Koa, menggunakan generator dan bukannya panggilan balik untuk middleware.

Anda memasang Koa dengan corak standard di dalam folder aplikasi anda:

$ npm pasang koa  

Berikut adalah kod untuk aplikasi "Hello World" Koa, yang boleh anda simpan dan jalankan seperti contoh sebelumnya.

const Koa = memerlukan ('koa');

const app = Koa baru ();

// masa tindak balas x

app.use (async (ctx, next) => {

const start = Date.now ();

tunggu seterusnya ();

const ms = Date.now () -start;

ctx.set ('X-Response-Time', `$ {ms} ms`);

});

// pembalak

app.use (async (ctx, next) => {

const start = Date.now ();

tunggu seterusnya ();

const ms = Date.now () -start;

console.log (`$ {ctx.method} $ {ctx.url} - $ {ms}`);

});

// tindak balas

app.use (async ctx => {

ctx.body = 'Hello World';

});

app.listen (3000);

Terdapat perbezaan antara generator middleware seperti yang digunakan oleh Koa dan callback seperti yang digunakan oleh Express dan kerangka Node.js yang lain. Banyak pelaksanaan panggilan balik hanya melalui kawalan melalui rangkaian fungsi sehingga satu kembali, sementara Koa menghasilkan "hilir," kemudian kawalan mengalir kembali "hulu."

Dalam contoh di atas, masa tindak balas x "membungkus" penjana tindak balas, dengan  await next() pernyataan menandakan panggilan. Penggunaan fungsi tak segerak ini lebih fleksibel daripada panggilan fungsi eksplisit, kerana memudahkan memasukkan penjana lain ke dalam urutan, misalnya pembalak web antara pemasa dan tindak balas.

Anda mungkin menemui kod Koa lama yang menggunakan yield nextdan bukannya await next(). Perbezaannya ialah Koa kini menyokong fungsi ES2015 dan async. Aliran kawalan berjumlah sama: Ia bergerak ke pengendali seterusnya dalam rantai semasa yield nextpanggilan, dan kemudian kembali apabila semua pengendali selesai.