@farmfe/core
Version:
Farm is a extremely fast web build tool written in Rust. Farm can start a project in milliseconds and perform HMR within 10ms, making it much faster than similar tools like webpack and vite.
107 lines • 4.12 kB
JavaScript
import { createRequire } from 'node:module';
import { Compiler } from '../compiler/index.js';
import { Server } from '../server/index.js';
import { compilerHandler } from '../utils/index.js';
import { existsSync } from 'node:fs';
import { createWatcher } from './create-watcher.js';
export class FileWatcher {
constructor(serverOrCompiler, options, _logger) {
this.serverOrCompiler = serverOrCompiler;
this.options = options;
this._logger = _logger;
this._close = false;
this._watchedFiles = new Set();
this._root = options.root;
}
getInternalWatcher() {
return this._watcher;
}
filterWatchFile(file, root) {
const suffix = process.platform === 'win32' ? '\\' : '/';
return (!file.startsWith(`${root}${suffix}`) &&
!file.includes(`node_modules${suffix}`) &&
!file.includes('\0') &&
existsSync(file));
}
getExtraWatchedFiles() {
const compiler = this.getCompilerFromServerOrCompiler(this.serverOrCompiler);
return [
...compiler.resolvedModulePaths(this._root),
...compiler.resolvedWatchPaths()
].filter((file) => this.filterWatchFile(file, this._root));
}
watchExtraFiles() {
const files = this.getExtraWatchedFiles();
for (const file of files) {
if (!this._watchedFiles.has(file)) {
this._watcher.add(file);
this._watchedFiles.add(file);
}
}
}
async watch() {
// Determine how to compile the project
const compiler = this.getCompilerFromServerOrCompiler(this.serverOrCompiler);
const handlePathChange = async (path) => {
if (this._close) {
return;
}
try {
if (this.serverOrCompiler instanceof Server) {
await this.serverOrCompiler.hmrEngine.hmrUpdate(path);
}
if (this.serverOrCompiler instanceof Compiler &&
this.serverOrCompiler.hasModule(path)) {
compilerHandler(async () => {
const result = await compiler.update([path], true);
handleUpdateFinish(result);
compiler.writeResourcesToDisk();
}, this.options, this._logger, { clear: true });
}
}
catch (error) {
this._logger.error(error);
}
};
const watchedFiles = this.getExtraWatchedFiles();
const files = [this.options.root, ...watchedFiles];
this._watchedFiles = new Set(files);
this._watcher = createWatcher(this.options, files);
this._watcher.on('change', (path) => {
if (this._close)
return;
handlePathChange(path);
});
const handleUpdateFinish = (updateResult) => {
const added = [
...updateResult.added,
...updateResult.extraWatchResult.add
].map((addedModule) => {
const resolvedPath = compiler.transformModulePath(this._root, addedModule);
return resolvedPath;
});
const filteredAdded = added.filter((file) => this.filterWatchFile(file, this._root));
if (filteredAdded.length > 0) {
this._watcher.add(filteredAdded);
}
};
if (this.serverOrCompiler instanceof Server) {
this.serverOrCompiler.hmrEngine?.onUpdateFinish(handleUpdateFinish);
}
}
getCompilerFromServerOrCompiler(serverOrCompiler) {
return serverOrCompiler instanceof Server
? serverOrCompiler.getCompiler()
: serverOrCompiler;
}
close() {
this._close = true;
this._watcher = null;
this.serverOrCompiler = null;
}
}
export function clearModuleCache(modulePath) {
const _require = createRequire(import.meta.url);
delete _require.cache[_require.resolve(modulePath)];
}
//# sourceMappingURL=index.js.map