日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

.12-浅析webpack源码之NodeWatchFileSystem模块总览

發布時間:2023/12/18 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .12-浅析webpack源码之NodeWatchFileSystem模块总览 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  剩下一個watch模塊,這個模塊比較深,先大概過一下整體涉及內容再分部講解。

  流程圖如下:

NodeWatchFileSystem

const Watchpack = require("watchpack");class NodeWatchFileSystem {constructor(inputFileSystem) {this.inputFileSystem = inputFileSystem;this.watcherOptions = {aggregateTimeout: 0};this.watcher = new Watchpack(this.watcherOptions);}watch(files, /*Array*/dirs, /*Array*/missing, /*Array*/startTime, /*number*/options, /*object*/callback, /*function*/callbackUndelayed /*function*/) {// params validate...const oldWatcher = this.watcher;// 生成Watchpack對象this.watcher = new Watchpack(options);if (callbackUndelayed)this.watcher.once("change", callbackUndelayed);this.watcher.once("aggregated", (changes, removals) => { /**/ });// 調用watch方法this.watcher.watch(files.concat(missing), dirs.concat(missing), startTime);if (oldWatcher) {oldWatcher.close();}return {close: () => { /**/ },pause: () => { /**/ }};} }module.exports = NodeWatchFileSystem;

  除去細節代碼,該模塊大體如下;

1、引入Watchpack模塊

2、接受一個inputFileSystem作為構造函數的參數

3、根據配置選項實例化一個Watchpack類

4、核心watch方法為調用實例類的watch方法,傳入給定參數,綁定兩個一次性事件綁定并返回了一個對象

  模塊核心的方法調用的是Watchpack實體類上的,所以需要進一步探究該類。

  該模塊涉及到了nodejs的event模塊,內容非常簡單,這里就不做介紹了,詳情可查看官網API:https://nodejs.org/dist/latest-v8.x/docs/api/events.html

?

Watchpack

var watcherManager = require("./watcherManager"); var EventEmitter = require("events").EventEmitter; Watchpack.prototype = Object.create(EventEmitter.prototype);class Watchpack {constructor(options) {EventEmitter.call(this);if (!options) options = {};if (!options.aggregateTimeout) options.aggregateTimeout = 200;this.options = options;this.watcherOptions = {ignored: options.ignored,poll: options.poll};this.fileWatchers = [];this.dirWatchers = [];this.mtimes = Object.create(null);this.paused = false;this.aggregatedChanges = [];this.aggregatedRemovals = [];this.aggregateTimeout = 0;this._onTimeout = this._onTimeout.bind(this);}watch(files, directories, startTime) {this.paused = false;var oldFileWatchers = this.fileWatchers;var oldDirWatchers = this.dirWatchers;this.fileWatchers = files.map(function(file) {return this._fileWatcher(file, watcherManager.watchFile(file, this.watcherOptions, startTime));}, this);this.dirWatchers = directories.map(function(dir) {return this._dirWatcher(dir, watcherManager.watchDirectory(dir, this.watcherOptions, startTime));}, this);oldFileWatchers.forEach(function(w) {w.close();}, this);oldDirWatchers.forEach(function(w) {w.close();}, this);};pause() { /**/ };getTimes() { /**/ };_fileWatcher(file, watcher) { /**/ };_dirWatcher(item, watcher) { /**/ };_onChange(item, mtime, file) { /**/ };_onRemove(item, file) { /**/ };_onTimeout() { /**/ };close() { /**/ }; }module.exports = Watchpack;function addWatchersToArray(watchers, array) { /**/ }

  本模塊引入了并繼承了nodejs的EventEmitter,并引入了新模塊watcherManager,主要內容羅列如下:

1、構造函數接受一個對象,鍵包括aggregateTimeout、ignored、poll,本例只傳入第一個并設置為0

2、核心方法為watch,依賴于引入的watchManager模塊

3、其余方法均為工具方法

?

WatcherManager

var path = require("path");class WatcherManager {constructor() {this.directoryWatchers = {};};// 工廠函數 getDirectoryWatcher(directory, options) {// 引入模塊var DirectoryWatcher = require("./DirectoryWatcher");options = options || {};var key = directory + " " + JSON.stringify(options);if (!this.directoryWatchers[key]) {this.directoryWatchers[key] = new DirectoryWatcher(directory, options);// 文件監視結束則從容器刪除this.directoryWatchers[key].on("closed", function() {delete this.directoryWatchers[key];}.bind(this));}return this.directoryWatchers[key];};// 監視文件 watchFile(p, options, startTime) {var directory = path.dirname(p);return this.getDirectoryWatcher(directory, options).watch(p, startTime);};// 監視目錄 watchDirectory(directory, options, startTime) {return this.getDirectoryWatcher(directory, options).watch(directory, startTime);}; } module.exports = new WatcherManager();

  可以看出這是一個中間處理函數,其中構造函數生成了一個容器,容器的鍵為目錄+參數生成的一個字符串,當監視關閉后會并立即刪除。

  這個模塊類似于tapable,是一個監視對象管理器。

?

  然后是監視核心實現模塊,模塊內容比較多,這里只簡單看一下構造函數以及watch方法:

var EventEmitter = require("events").EventEmitter; var async = require("async"); var chokidar = require("chokidar"); var fs = require("graceful-fs");class Watcher {constructor(directoryWatcher, filePath, startTime) {EventEmitter.call(this);this.directoryWatcher = directoryWatcher;this.path = filePath;this.startTime = startTime && +startTime;this.data = 0;};checkStartTime(mtime, initial) { /**/ };close() { /**/ }; }function DirectoryWatcher(directoryPath, options) {EventEmitter.call(this);this.options = options;this.path = directoryPath;this.files = Object.create(null);this.directories = Object.create(null);this.watcher = chokidar.watch(directoryPath, {ignoreInitial: true,persistent: true,followSymlinks: false,depth: 0,atomic: false,alwaysStat: true,ignorePermissionErrors: true,ignored: options.ignored,usePolling: options.poll ? true : undefined,interval: typeof options.poll === "number" ? options.poll : undefined,disableGlobbing: true});this.watcher.on("add", this.onFileAdded.bind(this));this.watcher.on("addDir", this.onDirectoryAdded.bind(this));this.watcher.on("change", this.onChange.bind(this));this.watcher.on("unlink", this.onFileUnlinked.bind(this));this.watcher.on("unlinkDir", this.onDirectoryUnlinked.bind(this));this.watcher.on("error", this.onWatcherError.bind(this));// ... }DirectoryWatcher.prototype.watch = function watch(filePath, startTime) {this.watchers[withoutCase(filePath)] = this.watchers[withoutCase(filePath)] || [];this.refs++;var watcher = new Watcher(this, filePath, startTime);watcher.on("closed", function() { /**/ }.bind(this));// ...return watcher; };// ... module.exports = DirectoryWatcher;

  從構造函數和模塊引入可以得到很多信息,如下:

1、引入了graceful-js模塊,可以看出底層還是利用nodejs的fs模塊來進行監視

2、所有的監視事件都是基于nodejs的EventEmitter模塊來進行操作

3、內部還有一個輔助類Watcher

4、根據構造函數的代碼,監視的操作包含(可能不限于)新增文件、新增文件夾、改變內容、刪除文件、刪除文件夾等

?

  async模塊是一個類似于tapable的輔助工具,用于異步處理批量方法,詳細內容可自行去網上查閱。

  構造函數中,該模塊又再次引用了chokidar模塊,并調用其watch方法進行初始化,看似調用方法,源碼簡化后如下:

class FSWatcher {// ... } exports.FSWatcher = FSWatcher; exports.watch = function(paths, options) {return new FSWatcher(options).add(paths); };

  假的,這還是個new操作,只是為了方便把兩步合成到了一個方法中。

?

  所有的模塊整理如上,下面幾節再來剖析每一塊內容。

轉載于:https://www.cnblogs.com/QH-Jimmy/p/8059129.html

總結

以上是生活随笔為你收集整理的.12-浅析webpack源码之NodeWatchFileSystem模块总览的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。