|
| 1 | +import fs, { type Stats } from 'node:fs'; |
| 2 | +import path from 'node:path'; |
| 3 | +import { debuglog } from 'node:util'; |
| 4 | + |
| 5 | +import { getExtensions, importModule } from '@eggjs/utils'; |
| 6 | +import globby from 'globby'; |
| 7 | +import { readJSONSync } from 'utility'; |
| 8 | + |
| 9 | +const debug = debuglog('egg/loader-fs'); |
| 10 | +const extensionNames = Object.keys(getExtensions()).concat(['.cjs', '.mjs']); |
| 11 | + |
| 12 | +export type LoaderFSGlobOptions = globby.GlobbyOptions; |
| 13 | + |
| 14 | +export interface LoaderFS { |
| 15 | + exists(filepath: string): boolean; |
| 16 | + stat(filepath: string): Stats; |
| 17 | + realpath(filepath: string): string; |
| 18 | + readJSON<T = unknown>(filepath: string): T; |
| 19 | + glob(patterns: string | string[], options?: LoaderFSGlobOptions): string[]; |
| 20 | + loadFile(filepath: string): Promise<unknown>; |
| 21 | +} |
| 22 | + |
| 23 | +export class RealLoaderFS implements LoaderFS { |
| 24 | + exists(filepath: string): boolean { |
| 25 | + return fs.existsSync(filepath); |
| 26 | + } |
| 27 | + |
| 28 | + stat(filepath: string): Stats { |
| 29 | + return fs.statSync(filepath); |
| 30 | + } |
| 31 | + |
| 32 | + realpath(filepath: string): string { |
| 33 | + return fs.realpathSync(filepath); |
| 34 | + } |
| 35 | + |
| 36 | + readJSON<T = unknown>(filepath: string): T { |
| 37 | + return readJSONSync(filepath) as T; |
| 38 | + } |
| 39 | + |
| 40 | + glob(patterns: string | string[], options?: LoaderFSGlobOptions): string[] { |
| 41 | + return globby.sync(patterns, options); |
| 42 | + } |
| 43 | + |
| 44 | + async loadFile(filepath: string): Promise<unknown> { |
| 45 | + debug('[loadFile:start] filepath: %s', filepath); |
| 46 | + try { |
| 47 | + const extname = path.extname(filepath); |
| 48 | + if (extname && !extensionNames.includes(extname) && extname !== '.ts') { |
| 49 | + return fs.readFileSync(filepath); |
| 50 | + } |
| 51 | + return await importModule(filepath, { importDefaultOnly: true }); |
| 52 | + } catch (err) { |
| 53 | + if (!(err instanceof Error)) { |
| 54 | + console.trace(err); |
| 55 | + throw err; |
| 56 | + } |
| 57 | + const error = new Error(`[egg/loader-fs] load file: ${filepath}, error: ${err.message}`); |
| 58 | + error.cause = err; |
| 59 | + debug('[loadFile] handle %s error: %s', filepath, err); |
| 60 | + throw error; |
| 61 | + } |
| 62 | + } |
| 63 | +} |
0 commit comments