Terkadang, Anda tidak bisa begitu saja membukanya index.html
di Chrome untuk menguji situs web Anda. Anda memerlukan fitur server web nyata seperti NGINX.
Kasus umum ketika pemuatan langsung index.html
gagal adalah mencoba menyajikan file lokal menggunakan Fetch API. Anda mengalami kesalahan Berbagi Sumber Daya Lintas Asal (CORS). Saya mengalami masalah kecil ini ketika membuat contoh untuk posting blog ini tentang ClipBoard API . Selain mencegah kesalahan CORS, lebih realistis menggunakan server web produksi di lingkungan pengembangan Anda.
Untuk memulai, Anda hanya perlu menginstal Docker dan menjalankan satu perintah.
$ docker run -d --name nginx-development -v $(pwd):/usr/share/nginx/html -p 80:80 nginx
Perintah di atas melakukan beberapa hal. Bendera -d
memastikan Anda tidak terjebak di wadah. Menggunakan --name nginx-development
argumen kata kunci memberi nama pada instance container ini, sehingga kita dapat mereferensikannya nanti. Ini -p 80:80
memetakan port mesin lokal kami 80
ke port container yang digunakan NGINX untuk melayani HTTP. Pemetaan port ini memungkinkan kami mengunjungi http://localhost
situs pengembangan kami.
Argumen -v $(pwd):/usr/share/nginx/html
kata kunci perlu penjelasan lebih lanjut. Ini menghubungkan direktori kerja kita saat ini ke direktori dalam instance container yang sedang berjalan. Direktori dalam container ini adalah lokasi default tempat NGINX mencari file untuk disajikan. Jika Anda ingin menyajikan direktori yang berbeda, maka Anda perlu mengubah argumennya --volume
. Misalnya, saya ingin meletakkan index.html
di ./src/index.html
di direktori proyek saya. Untuk menyesuaikannya, -v
argumen saya akan terlihat seperti ini -v "$(pwd)/src:/usr/share/nginx/html"
.
Jika Anda menggunakan browser untuk bernavigasi ke http://localhost
, Anda seharusnya dapat melihat situs Anda. Namun jika Anda membuat perubahan pada file Anda index.html
atau file lain di situs Anda, menyegarkan browser Anda tidak akan menampilkannya. Untuk memuat ulang situs setelah Anda melakukan perubahan, gunakan perintah berikut.
$ docker restart nginx-development
Ada baiknya kita dapat memuat ulang perubahan kita, tetapi ini memerlukan langkah ekstra: menjalankan docker restart
perintah di atas. Dengan alur kerja sebelumnya – membuka index.html
secara langsung – kita hanya memerlukan satu langkah: menyegarkan browser kita. Mari kita perbaiki
Menulis Skrip Muat Ulang Otomatis
Untuk membuat skrip ini, kita perlu melakukannya
- Jajak pendapat direktori sesering mungkin dan catat sendiri perubahannya
- Miliki cara untuk diberitahu ketika ada perubahan
Untuk menghindari pengelolaan negara kita sendiri dan menjaga skrip bash tetap sederhana, mari kita pilih opsi 2. Bagaimana kita bisa mendapatkan notifikasi ini? Di Linux, ada alat baris perintah inotifywait
yang mengandalkan inotify C API yang mendasarinya . Kita bisa menggunakan ini, tapi kemudian kita akan terkunci di Linux. Saya mengembangkannya di Mac OS dan Linux, jadi saya ingin mendukung keduanya – bahkan lebih baik lagi jika kami juga dapat mendukung Windows.
Ada alat lain fswatch
yang berfungsi di Mac OS, Linux, dan Windows. Ini mungkin tidak diinstal secara default di sistem operasi Anda. Di Mac OS, saya perlu menginstal fswatch
menggunakan perintah berikut.
$ brew install fswatch
Sekarang mari kita lihat cara kerja alat ini. Mari kita coba jalankan alat ini dan arahkan ke direktori sumber kita.
$ fswatch src
Konsol saya hang dengan kursor berkedip. Mari kita lihat apa yang terjadi jika kita mengubah salah satu file di src
direktori. Saya akan mencoba mengedit salah satu file css saya...
$ fswatch src
/Users/curtis/git/licorice-works/src/styles/4913
/Users/curtis/git/licorice-works/src/styles/projects.css
/Users/curtis/git/licorice-works/src/styles/projects.css
/Users/curtis/git/licorice-works/src/styles/projects.css~
Sekarang, fswatch
berikan kita keluaran di atas dengan nama file yang saya modifikasi.
Ini adalah pemberitahuan perubahan yang banyak untuk memodifikasi satu file. Sepertinya kami tidak ingin pemberitahuan untuk 4913
file atau .css~
file tersebut. Ini tampaknya merupakan keanehan dalam cara kerja penyimpanan file di Mac OS. Untungnya, fswatch
alat ini memiliki beberapa argumen yang dapat kita gunakan untuk memfilter notifikasi perubahan. Secara default, ini mencakup semuanya. Perilaku ini membuat penyertaan jenis file yang kita inginkan menjadi sedikit aneh. Pertama, kita perlu menggunakan -e '.*'
untuk mengecualikan semuanya. Kemudian kita dapat menggunakan -i 'css$'
untuk memasukkan kembali hanya file yang berakhiran css
. Dengan perintah baru kami, kami hanya mendapat notifikasi untuk file CSS yang kami ubah – bukan file aneh lainnya.
$ fswatch -e '.*' -i 'css$' src
/Users/curtis/git/licorice-works/src/styles/projects.css
/Users/curtis/git/licorice-works/src/styles/projects.css
Ini masih berupa dua notifikasi. Kami hanya ingin memuat ulang NGINX satu kali per perubahan. Untungnya, fswatch
ada --one-per-batch
tanda yang dapat kita gunakan untuk mengelompokkan perubahan bersama-sama.
$ fswatch -o -e '.*' -i 'css$' src
2
Setelah menambahkan -o
, kita hanya mendapatkan satu baris keluaran saat kita memodifikasi file. Mari kita gunakan output ini untuk memicu restart container Docker kita.
$ fswatch -o -e '.*' -i 'css$' -i 'html$' -i 'js$' src | \
while read -r line; do docker restart nginx-development; done
Perintah itu terlihat lebih rumit dibandingkan perintah yang kita gunakan selama ini. Mari kita gali lebih dalam. Pertama, saya menambahkan dua -i
filter penyertaan lagi. Satu untuk menyertakan pembaruan apa pun yang kami buat pada .html
file dan satu lagi untuk menyertakan .js
file. Kemudian kita menyalurkan |
output dari perintah ini ke dalam loop while. Jika Anda tidak terbiasa dengan pipa, ia hanya mengirimkan keluaran dari perintah pertama sebagai masukan ke perintah kedua. Perintah kedua yang kita masukkan adalah while loop. Sintaks umum dari perulangan while terlihat seperti berikut.
while <condition>;
do
<command to execute>
done
Akan lebih mudah dibaca jika tidak dipadatkan menjadi satu baris. Untuk <condition>
bagian ini, kami menggunakan perintah read -r line
. Setiap kali ada baris input untuk dibaca, perintah ini membacanya, menyimpannya dalam variabel line
, dan mengembalikan nilai true. Dalam skrip kami, ini berarti setiap kali fswatch
mencetak sekumpulan perubahan, loop kami akan dijalankan satu kali. Jadi setiap kali ada perubahan, kami akan menjalankan perintah restart yang sama seperti di atas docker restart nginx-development
.
Anda bisa memulai dengan menjalankan dua perintah.
$ docker run -d --name nginx-development -v $(pwd):/usr/share/nginx/html -p 80:80 nginx
$ fswatch -o -e '.*' -i 'css$' -i 'html$' -i 'js$' $(pwd) | while read -r line; do docker restart nginx-development; done
Tapi ini banyak yang perlu diingat atau disalin-tempel setiap saat, jadi saya menulis skrip yang hanya membutuhkan satu argumen: direktori sumber Anda. Anda dapat menyalin skrip ini dan menggunakannya kembali dengan mudah untuk setiap proyek Anda.
nginx-autoreload.sh
#!/bin/bash
CONTAINER_NAME="nginx-development"
# Use the first argument as our source dir.
# Default to current working directory if no argument is supplied.
SOURCE_DIRECTORY=$1
if [ ! $1 ]; then
SOURCE_DIRECTORY="$(pwd)";
echo "No source directory provided. Defaulting to current working directory: ${SOURCE_DIRECTORY}";
else
# Get the full path
SOURCE_DIRECTORY=$(realpath "${SOURCE_DIRECTORY}")
fi
docker rm --force "${CONTAINER_NAME}" &> /dev/null;
docker run -d --name "${CONTAINER_NAME}" -v "${SOURCE_DIRECTORY}":/usr/share/nginx/html -p 80:80 nginx > /dev/null;
if [ $? -ne 0 ]; then
echo "Failed to initialize container";
exit 1;
else
echo "Successfully started container: ${CONTAINER_NAME}";
fi
echo "Waiting for changes..."
fswatch -o -e '.*' -i 'css$' -i 'html$' -i 'js$' "${SOURCE_DIRECTORY}" |
while read -r line; do
docker restart "${CONTAINER_NAME}" > /dev/null;
if [ $? -eq 0 ]; then
echo "Successfully reloaded ${CONTAINER_NAME}";
else
echo "Failed realoading ${CONTAINER_NAME}";
fi
done
Anda dapat menggunakan skrip seperti $ ./nginx-autoreload.sh <your-source-directory
, dan skrip ini akan mengatur penyiapan penampung dan mengamati perubahan. Catatan: ingatlah untuk menginstal Docker dan fswatch terlebih dahulu!