|
| 1 | +import { extname } from 'path'; |
| 2 | +import resolve from 'resolve'; |
| 3 | + |
| 4 | +export class ReactDocgenResolveError extends Error { |
| 5 | + // the magic string that react-docgen uses to check if a module is ignored |
| 6 | + readonly code = 'MODULE_NOT_FOUND'; |
| 7 | + |
| 8 | + constructor(filename: string) { |
| 9 | + super(`'${filename}' was ignored by react-docgen.`); |
| 10 | + } |
| 11 | +} |
| 12 | + |
| 13 | +/* The below code was copied from: |
| 14 | + * https://github.com/reactjs/react-docgen/blob/df2daa8b6f0af693ecc3c4dc49f2246f60552bcb/packages/react-docgen/src/importer/makeFsImporter.ts#L14-L63 |
| 15 | + * because it wasn't exported from the react-docgen package. |
| 16 | + * watch out: when updating this code, also update the code in code/presets/react-webpack/src/loaders/docgen-resolver.ts |
| 17 | + */ |
| 18 | + |
| 19 | +// These extensions are sorted by priority |
| 20 | +// resolve() will check for files in the order these extensions are sorted |
| 21 | +export const RESOLVE_EXTENSIONS = [ |
| 22 | + '.js', |
| 23 | + '.cts', // These were originally not in the code, I added them |
| 24 | + '.mts', // These were originally not in the code, I added them |
| 25 | + '.ctsx', // These were originally not in the code, I added them |
| 26 | + '.mtsx', // These were originally not in the code, I added them |
| 27 | + '.ts', |
| 28 | + '.tsx', |
| 29 | + '.mjs', |
| 30 | + '.cjs', |
| 31 | + '.mts', |
| 32 | + '.cts', |
| 33 | + '.jsx', |
| 34 | +]; |
| 35 | + |
| 36 | +export function defaultLookupModule(filename: string, basedir: string): string { |
| 37 | + const resolveOptions = { |
| 38 | + basedir, |
| 39 | + extensions: RESOLVE_EXTENSIONS, |
| 40 | + // we do not need to check core modules as we cannot import them anyway |
| 41 | + includeCoreModules: false, |
| 42 | + }; |
| 43 | + |
| 44 | + try { |
| 45 | + return resolve.sync(filename, resolveOptions); |
| 46 | + } catch (error) { |
| 47 | + const ext = extname(filename); |
| 48 | + let newFilename: string; |
| 49 | + |
| 50 | + // if we try to import a JavaScript file it might be that we are actually pointing to |
| 51 | + // a TypeScript file. This can happen in ES modules as TypeScript requires to import other |
| 52 | + // TypeScript files with .js extensions |
| 53 | + // https://www.typescriptlang.org/docs/handbook/esm-node.html#type-in-packagejson-and-new-extensions |
| 54 | + switch (ext) { |
| 55 | + case '.js': |
| 56 | + case '.mjs': |
| 57 | + case '.cjs': |
| 58 | + newFilename = `${filename.slice(0, -2)}ts`; |
| 59 | + break; |
| 60 | + |
| 61 | + case '.jsx': |
| 62 | + newFilename = `${filename.slice(0, -3)}tsx`; |
| 63 | + break; |
| 64 | + default: |
| 65 | + throw error; |
| 66 | + } |
| 67 | + |
| 68 | + return resolve.sync(newFilename, { |
| 69 | + ...resolveOptions, |
| 70 | + // we already know that there is an extension at this point, so no need to check other extensions |
| 71 | + extensions: [], |
| 72 | + }); |
| 73 | + } |
| 74 | +} |
0 commit comments