大家好奥喻,今天我們來學習一下服務器如何熱重載,關于熱重載這個特性,只要是運行在DartVM下都可以實現(xiàn)熱重載蹦魔,嗯嗯激率,這樣說,大家應該能明白Flutter為什么能夠熱重載了吧勿决,F(xiàn)lutter實際也是運行在一個DartVM的環(huán)境之下,下次我會介紹快照乒躺,好了,我們來開始學習服務器熱重載吧低缩!
1.介紹
熱重載其實就是將一個文件加入到監(jiān)聽中嘉冒,如果有改變,就會對程序進行更新表制,我們可以集成jaguar_hotreload這個包,添加之后控乾,就可以實現(xiàn)無需重啟服務器進行更新了
2. 使用熱重載
-
添加依賴
在我們的pubspec.yaml文件下添加下面代碼dependencies: jaguar_hotreload: ^2.0.2
-
執(zhí)行
pub get
命令
-
導包
import 'package:jaguar_hotreload/jaguar_hotreload.dart';
-
添加熱重載
main(){ final reloader = HotReloader(debounceInterval: const Duration(seconds: 10), vmServiceUrl: 'ws://localhost:8181/ws'); reloader.addPackageDependencies(); reloader.addGlob(Glob('jaguar_*/lib')); reloader.addFile(File('pubspec.yaml')); reloader.addPackagePath(Uri(scheme: 'package', path: 'jaguar/')); reloader.addUri(new Uri(scheme: 'file', path: '/usr/lib/dart')); reloader.addPath('lib/'); await reloader.go(); }
-
debounceInterval
用于更新間隔么介,如果在間隔內(nèi)更新,會等待下一次才更新蜕衡,默認為1秒 -
vmServiceUrl
指定一個vm service的地址 -
addPackageDependencies()
監(jiān)聽.packages
里面的所有文件 -
addGlob()
使用正則監(jiān)聽 -
addFile ()
添加單個文件監(jiān)聽 -
addPackagePath
添加包路徑監(jiān)聽 -
addUri()
使用uri添加監(jiān)聽 -
addPath()
添加監(jiān)聽路徑(運行的.dart
文件為跟目錄) -
go()
執(zhí)行監(jiān)聽
-
手動觸發(fā)監(jiān)聽
我們可以調(diào)用reloader.onReload
進行手動觸發(fā)監(jiān)聽-
注意在運行的時候壤短,我們需要啟用Dart VM服務。
首先要區(qū)分以下:DartVM虛擬機和DartVM服務慨仿,DartVM服務是在DartVM虛擬機的久脯,正常是不會啟用服務,我們需要使用命令--enable-vm-service
或者--observe
進行啟用镰吆,例如:dart --observe main.dart
,所以:實現(xiàn)熱重載需要啟用DartVM服務 這一句比較重點帘撰,先記下
熱重載的部分代碼:/// Reloads the application Future<void> reload() async { print('Reloading the application...'); // Get vm service _client ??= await vmServiceConnectUri(vmServiceUrl); // Find main isolate id to reload it final vm = await _client.getVM(); final ref = vm.isolates.first; // Reload final rep = await _client.reloadSources(ref.id); if (!rep.success) throw Exception('Reloading failed! Reason: $rep'); _onReload.add(DateTime.now()); }
3.實例
添加如下代碼:
main() => runService();
runService() async {
final reloader = HotReloader(debounceInterval: const Duration(seconds: 10));
reloader.addPath('.');//添加當前項目進行監(jiān)聽
await reloader.go();
Jaguar()
..get('/', (Context ctx) => 'Hello World')
..log.onRecord.listen(print)
..serve(logRequests: true);
}
然后我們使用命令行啟用服務器
dart --enable-vm-service bin/main.dart
然后,我們請求以下服務器
我們來改一下代碼看看万皿,將
Hello World
改為 'Hello Rhyme'
main() => runService();
runService() async {
final reloader = HotReloader(debounceInterval: const Duration(seconds: 10));
reloader.addPath('.');
await reloader.go();
Jaguar()
//edit
..get('/', (Context ctx) => 'Hello Rhyme')
//edit
..log.onRecord.listen(print)
..serve(logRequests: true);
}
可以看到摧找,控制臺輸出了Reloading the application...
然后刷新一下頁面
emmm...出現(xiàn)bug了我們來看看
dart-lang
的sdk里面的一個wiki,大家應該明白牢硅。在DartVM熱重載中蹬耘,只會改變程序的行為,而不能改變程序的狀態(tài),所以我們在定義Jaguar的時候减余,已經(jīng)把
(Context ctx) => 'Hello World'
這個狀態(tài)定義到堆棧中综苔,再次熱重載的時候,并不會發(fā)生改變位岔,我們再修改一下程序看看
main() => runService();
runService() async {
final reloader = HotReloader(debounceInterval: const Duration(seconds: 10));
reloader.addPath('.');
await reloader.go();
Jaguar()
//edit
..get('/', (Context ctx) => sayhello())
//edit
..log.onRecord.listen(print)
..serve(logRequests: true);
}
//new
sayhello() => 'Hello World';
//new
我們在這里將字符串搬到一個方法里面如筛,這樣,堆棧只記錄這個方法抒抬,當熱重載的時候妙黍,方法再次被搜索的時候,返回的字符串變了瞧剖,就能實現(xiàn)熱重載
我們重新運行看看
dart --enable-vm-service bin/main.dart
然后拭嫁,我們請求以下服務器
我們來改一下這個方法的返回看看
可以看到可免,我們成功的實現(xiàn)了熱重載。做粤。
OK浇借,我們今天就到這里了,下次有機會再見怕品,如果你在這篇文章中得到收獲妇垢,希望能支持一下作者,給作者一個大大禮包(****** 點亮紅心 ****** **關注******** 轉發(fā) ******) 你的支持肉康,是我創(chuàng)作和分享的動力闯估!