フロントエンドの開発のためのライブリロードサーバの作成
19378 ワード
私は私の最初の数年間のWeb開発Altのタブを私のブラウザに手動で私はコードに変更を行うたびにページをリフレッシュするためにオーバーを費やした.私は近代的なフレームワーク(Vueと反応)を使用し始めたまで、これがどれだけ私を悩ましたかを理解しませんでした.私は、それがものであったということさえ知りませんでした、しかし、現在、私は決して戻ることができません.
あなたが現在自動再読み込みなしでウェブページを作っているならば、すべてを落として、現在フックされてください!
ホットリロード
どのような自動再読み込みですか?
要するに、あなたのコードへの変更のための開発サーバーの時計を持って、次に、レンダリングされたページがあなたのコードと同期しているように、それ自体をリフレッシュするためにあなたのブラウザーに話しています.
任意のソースファイルが変更されるたびにページが完全に再読み込みを行う場合、それはすでに有用です.しかし、物事はそれよりはるかにおかしくなります.
VueとReactionのような現代のフレームワークは、彼らが「熱い」再ローディングと呼ぶものを持っています.ホットリロードの目標は、ページ全体の代わりに、何かが変更されたときに、ページ上のコンテンツの最小の部分を更新することです.あなたのウェブサイトの状態(フォームのコンテンツ、ウィジェットのオープン/クローズド状態など)の残りの部分は、あなたが変更したものだけがページ上で変更されますが、これは素晴らしいです.
棚をホットリロードサーバーを取得
幸いなことに、非常にスマートな人々はあなたのためのホットリロード問題を解決しました.あなたが使用する既存のソリューションは、プロジェクトに依存しますが、最新のWebdevを使用している場合は、フレームワークやWebPackのようなモジュールバンドル(ホットパック/Live Reload Server)を使用している可能性があります.そうでなければ、いくつかの程度または別のトリックを行ういくつかのオープンソースプロジェクトにGoglingのビットを取得します.
または独自にロールバック!
あなたは間違いなくオフの棚、深刻な開発作業のためのホットリロードサーバーを取得する必要があります.しかし、それはあなた自身を作るために楽しい運動であり、プロセスの謎の一部を削除します.ソースファイルを変更するたびに、ブラウザをリフレッシュするシンプルなLive Reading開発サーバーを作成します.
サーバがブラウザにリロードを引き起こすように通知する方法には、2つの合理的な選択肢があります.
ポーリング我々は、サイトが何かが変わったかどうか尋ねるために100ミリ秒(またはそれ以上)ごとにpingしているプレーンな古いバニラHTTPルートをセットすることができました.
Websockets . サーバーが情報をブラウザにプッシュできるように、我々は2ウェイWebSocketを設定することができました.そのように、変化が変化して、サイトの上で見えるようになっているその変化はありません. WebSocketsはより楽しいですし、将来的に多くの柔軟性を与えます(このライブリローナを何か熱いものに変えたい場合)、そのルートに行こう.最終的には何が変わったかを知るのに役に立つかもしれませんが、始めるには、何かが変化し、結果としてサイトをリロードすることを知っておく必要があります.
以下に簡単なアプローチを示します. 開発HTTPサーバーと一緒にWebSocketサーバーを実行します. devサーバを起動するnodemon ソースファイルが変更されるたびに再起動されます. WebSocketクライアントをオープンしたHTMLファイルにスクリプトを挿入します.接続が終了すると、そのスクリプトはページを再読み込みします. 集合的に、ソースファイルへのどんな変更もサーバーを再起動させて、したがって、ブラウザでロードされたどんなページにもWebSocket接続を壊すようにします.これらの接続を切断すると、ページはすぐに再読み込みされ、新しく再起動されたサーバーへの新しい接続を確立します.したがって、ライブリロード!
「注入」は何か空想のように聞こえるが、ここでは、「注入された」コードを包むよりも、それ以上ではないことに注意してください
今それはコードのための時間です.
依存
nodemon ファイルの変更を検出し、結果としてサーバーを再起動します.(
ws サーバ側のウェブソケットを設定するには.(
Node.js 開発サーバーの実行.私はV 14を使用していますoptional chaining
クライアント側注入コード
私はWebSocket接続を開始する死んだ単純なスクリプトから始めました
それは世界的な名前空間を汚染する サーバーが十分に速くページを再起動しないならば、ページは再ロードすることができません、そして、あなたは手動でリフレッシュしなければならない死んだページで立ち往生しています. 最初の問題を解決するには、コードをIffeでラップできます"Immediately Invoked Function Expression" ). 第2の問題を解決するためには、リトライを得るためにもう少し複雑さが必要です.その結果:
開発サーバコード
あなたが長い方法を行う場合は、Expressのようなフレームワークを使用せずに.js
すべてのランニング
最後に、このデーモンを使用してこのサーバーを実行します.
あなたが現在自動再読み込みなしでウェブページを作っているならば、すべてを落として、現在フックされてください!
ホットリロード
どのような自動再読み込みですか?
要するに、あなたのコードへの変更のための開発サーバーの時計を持って、次に、レンダリングされたページがあなたのコードと同期しているように、それ自体をリフレッシュするためにあなたのブラウザーに話しています.
任意のソースファイルが変更されるたびにページが完全に再読み込みを行う場合、それはすでに有用です.しかし、物事はそれよりはるかにおかしくなります.
VueとReactionのような現代のフレームワークは、彼らが「熱い」再ローディングと呼ぶものを持っています.ホットリロードの目標は、ページ全体の代わりに、何かが変更されたときに、ページ上のコンテンツの最小の部分を更新することです.あなたのウェブサイトの状態(フォームのコンテンツ、ウィジェットのオープン/クローズド状態など)の残りの部分は、あなたが変更したものだけがページ上で変更されますが、これは素晴らしいです.
棚をホットリロードサーバーを取得
幸いなことに、非常にスマートな人々はあなたのためのホットリロード問題を解決しました.あなたが使用する既存のソリューションは、プロジェクトに依存しますが、最新のWebdevを使用している場合は、フレームワークやWebPackのようなモジュールバンドル(ホットパック/Live Reload Server)を使用している可能性があります.そうでなければ、いくつかの程度または別のトリックを行ういくつかのオープンソースプロジェクトにGoglingのビットを取得します.
または独自にロールバック!
あなたは間違いなくオフの棚、深刻な開発作業のためのホットリロードサーバーを取得する必要があります.しかし、それはあなた自身を作るために楽しい運動であり、プロセスの謎の一部を削除します.ソースファイルを変更するたびに、ブラウザをリフレッシュするシンプルなLive Reading開発サーバーを作成します.
サーバがブラウザにリロードを引き起こすように通知する方法には、2つの合理的な選択肢があります.
ポーリング我々は、サイトが何かが変わったかどうか尋ねるために100ミリ秒(またはそれ以上)ごとにpingしているプレーンな古いバニラHTTPルートをセットすることができました.
Websockets . サーバーが情報をブラウザにプッシュできるように、我々は2ウェイWebSocketを設定することができました.そのように、変化が変化して、サイトの上で見えるようになっているその変化はありません.
以下に簡単なアプローチを示します.
「注入」は何か空想のように聞こえるが、ここでは、「注入された」コードを包むよりも、それ以上ではないことに注意してください
<script/>
サーバーがブラウザに送信するときにHTML文書の最後にタグを追加します.HTMLパーサーがそうであるので、これは働きます.確かに、スクリプトのタグはすべての中にある必要があります<html/>
タグが、それらがない場合はブラウザがとにかく実行されます.今それはコードのための時間です.
依存
nodemon ファイルの変更を検出し、結果としてサーバーを再起動します.(
npm install nodemon
) ws サーバ側のウェブソケットを設定するには.(
npm install ws
) Node.js 開発サーバーの実行.私はV 14を使用していますoptional chaining
クライアント側注入コード
私はWebSocket接続を開始する死んだ単純なスクリプトから始めました
close
イベントが発生した場合、そのページを再読み込みします./**
* @file site/client-websocket.js
*/
const socket = new WebSocket('ws://localhost:8090');
socket.addEventListener('close',()=>{
location.reload();
});
そのスクリプトは簡単すぎた.コアの欠陥は以下の通りです.socket
変数名はドキュメントスコープ内の何かによって使用されるかもしれません./**
* @file site/client-websocket.js
*/
(()=>{
const socketUrl = 'ws://localhost:8090';
let socket = new WebSocket(socketUrl);
socket.addEventListener('close',()=>{
// Then the server has been turned off,
// either due to file-change-triggered reboot,
// or to truly being turned off.
// Attempt to re-establish a connection until it works,
// failing after a few seconds (at that point things are likely
// turned off/permanantly broken instead of rebooting)
const interAttemptTimeoutMilliseconds = 100;
const maxDisconnectedTimeMilliseconds = 3000;
const maxAttempts = Math.round(maxDisconnectedTimeMilliseconds/interAttemptTimeoutMilliseconds);
let attempts = 0;
const reloadIfCanConnect = ()=>{
attempts ++ ;
if(attempts > maxAttempts){
console.error("Could not reconnect to dev server.");
return;
}
socket = new WebSocket(socketUrl);
socket.addEventListener('error',()=>{
setTimeout(reloadIfCanConnect,interAttemptTimeoutMilliseconds);
});
socket.addEventListener('open',()=>{
location.reload();
});
};
reloadIfCanConnect();
});
})();
開発サーバコード
あなたが長い方法を行う場合は、Expressのようなフレームワークを使用せずに.js
/** @file site/dev-server.js */
const http = require('http');
const fs = require('fs');
const path = require('path');
const WebSocket = require('ws');
const HTTP_PORT = 8089;
const WEBSOCKET_PORT = 8090;
const CLIENT_WEBSOCKET_CODE = fs.readFileSync(path.join(__dirname,'client-websocket.js'),'utf8');
// Websocket server (for allowing browser and dev server to have 2-way communication)
// We don't even need to do anything except create the instance!
const wss = new WebSocket.Server({
port: WEBSOCKET_PORT
});
/**
* @typedef {import('http').IncomingMessage} req
* @typedef {import('http').ServerResponse} res
*/
/** Use classic server-logic to serve a static file (e.g. default to 'index.html' etc)
* @param {string} route
* @param {res} res
* @returns {boolean} Whether or not the page exists and was served
*/
function serveStaticPageIfExists(route,res) {
// We don't care about performance for a dev server, so sync functions are fine.
// If the route exists it's either the exact file we want or the path to a directory
// in which case we'd serve up the 'index.html' file.
if(fs.existsSync(route)){
if(fs.statSync(route).isDirectory()){
return serveStaticPageIfExists(path.join(route,'index.html'),res);
}
else if(fs.statSync(route).isFile()){
res.writeHead(200);
/** @type {string|Buffer} */
let file = fs.readFileSync(route);
if(route.endsWith('.html')){
// Inject the client-side websocket code.
// This sounds fancier than it is; simply
// append the script to the end since
// browsers allow for tons of deviation
// from *technically correct* HTML.
file = `${file.toString()}\n\n<script>${CLIENT_WEBSOCKET_CODE}</script>`;
}
res.end(file);
return true;
}
}
return false;
}
/** General request handler and router
* @param {req} req
* @param {res} res
*/
const requestHandler = function (req, res) {
const method = req.method.toLowerCase();
if(method=='get'){
// No need to ensure the route can't access other local files,
// since this is for development only.
const route = path.normalize(path.join(__dirname,'src',req.url));
if(serveStaticPageIfExists(route,res)){
return;
}
}
res.writeHead(404);
res.end();
}
const server = http.createServer(requestHandler);
server.listen(HTTP_PORT);
あなたのWebサーバーを効率的にフレームワークでより多くのコードを作ることができることに注意してくださいExpress.js (というのは、たぶん)しかし、時にはノードに組み込まれているものを作ることもあります.すべてのランニング
最後に、このデーモンを使用してこのサーバーを実行します.
npx nodemon ./site/dev-server.js --ext js,html,css,md
ブラウザタブを開きますhttp://localhost:8089
そして、それ!今、私たちはライブリロードを持つ死んだシンプルな開発サーバーがあります.Reference
この問題について(フロントエンドの開発のためのライブリロードサーバの作成), 我々は、より多くの情報をここで見つけました https://dev.to/adamcoster/create-a-live-reload-server-for-front-end-development-3gnpテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol