Skip to content

Commit 8edf247

Browse files
authored
release: v0.1.2 - custom module resolving
1 parent 01b4e57 commit 8edf247

File tree

1 file changed

+126
-2
lines changed

1 file changed

+126
-2
lines changed

README.md

Lines changed: 126 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# `std.module.format`
22

3-
> version 0.1.1
3+
> version 0.1.2
44
55
- [`std.module.format`](#-stdmoduleformat-)
66
* [Overview](#overview)
@@ -23,11 +23,14 @@
2323
* [Note](#note)
2424
+ [Needs two lines for non-class / non-function](#needs-two-lines-for-non-class---non-function)
2525
+ [React.js - Named Exports](#reactjs---named-exports)
26-
* [The {} type](#---type)
26+
* [{} type](#---type)
2727
+ [If you want a type that means "empty object"](#if-you-want-a-type-that-means--empty-object-)
2828
+ [If you are using React, and you want to define `type Props = {}`.](#if-you-are-using-react--and-you-want-to-define--type-props------)
2929
+ [`GenericObject`](#-genericobject-)
3030
+ [Module-related host hooks](#module-related-host-hooks)
31+
* [Customizing module resolution](#customizing-module-resolution)
32+
+ [parserOptions.moduleResolver](#parseroptionsmoduleresolver)
33+
* [License](#license)
3134

3235
<small><i><a href='#'>This is a work in progress</a></i></small>
3336

@@ -596,6 +599,127 @@ The following are not valid module specifiers according to the above algorithm:
596599
- `.\yam.es`
597600
598601
602+
## Customizing module resolution
603+
604+
> [source, https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#customizing-module-resolution]
605+
606+
You can override the standard way the compiler resolves modules by implementing optional method: CompilerHost.resolveModuleNames:
607+
608+
```typescript
609+
CompilerHost.resolveModuleNames(moduleNames: string[], containingFile: string): string[].
610+
```
611+
612+
The method is given a list of module names in a file, and is expected to return an array of size moduleNames.length, each element of the array stores either:
613+
614+
an instance of ResolvedModule with non-empty property resolvedFileName - resolution for corresponding name from moduleNames array or undefined if module name cannot be resolved.
615+
616+
You can invoke the standard module resolution process via calling resolveModuleName:
617+
618+
```typescript
619+
resolveModuleName(moduleName: string, containingFile: string, options: CompilerOptions, moduleResolutionHost: ModuleResolutionHost): ResolvedModuleNameWithFallbackLocations.
620+
```
621+
622+
This function returns an object that stores result of module resolution (value of resolvedModule property) as well as list of file names that were considered candidates before making current decision.
623+
624+
```typescript
625+
import * as ts from "typescript";
626+
import * as path from "path";
627+
628+
function createCompilerHost(options: ts.CompilerOptions, moduleSearchLocations: string[]): ts.CompilerHost {
629+
return {
630+
getSourceFile,
631+
getDefaultLibFileName: () => "lib.d.ts",
632+
writeFile: (fileName, content) => ts.sys.writeFile(fileName, content),
633+
getCurrentDirectory: () => ts.sys.getCurrentDirectory(),
634+
getDirectories: path => ts.sys.getDirectories(path),
635+
getCanonicalFileName: fileName =>
636+
ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(),
637+
getNewLine: () => ts.sys.newLine,
638+
useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames,
639+
fileExists,
640+
readFile,
641+
resolveModuleNames
642+
};
643+
644+
function fileExists(fileName: string): boolean {
645+
return ts.sys.fileExists(fileName);
646+
}
647+
648+
function readFile(fileName: string): string | undefined {
649+
return ts.sys.readFile(fileName);
650+
}
651+
652+
function getSourceFile(fileName: string, languageVersion: ts.ScriptTarget, onError?: (message: string) => void) {
653+
const sourceText = ts.sys.readFile(fileName);
654+
return sourceText !== undefined
655+
? ts.createSourceFile(fileName, sourceText, languageVersion)
656+
: undefined;
657+
}
658+
659+
function resolveModuleNames(
660+
moduleNames: string[],
661+
containingFile: string
662+
): ts.ResolvedModule[] {
663+
const resolvedModules: ts.ResolvedModule[] = [];
664+
for (const moduleName of moduleNames) {
665+
// try to use standard resolution
666+
let result = ts.resolveModuleName(moduleName, containingFile, options, {
667+
fileExists,
668+
readFile
669+
});
670+
if (result.resolvedModule) {
671+
resolvedModules.push(result.resolvedModule);
672+
} else {
673+
// check fallback locations, for simplicity assume that module at location
674+
// should be represented by '.d.ts' file
675+
for (const location of moduleSearchLocations) {
676+
const modulePath = path.join(location, moduleName + ".d.ts");
677+
if (fileExists(modulePath)) {
678+
resolvedModules.push({ resolvedFileName: modulePath });
679+
}
680+
}
681+
}
682+
}
683+
return resolvedModules;
684+
}
685+
}
686+
687+
function compile(sourceFiles: string[], moduleSearchLocations: string[]): void {
688+
const options: ts.CompilerOptions = {
689+
module: ts.ModuleKind.AMD,
690+
target: ts.ScriptTarget.ES5
691+
};
692+
const host = createCompilerHost(options, moduleSearchLocations);
693+
const program = ts.createProgram(sourceFiles, options, host);
694+
695+
/// do something with program...
696+
}
697+
```
698+
699+
### parserOptions.moduleResolver
700+
701+
> [source, https://www.npmjs.com/package/@typescript-eslint/parser](https://www.npmjs.com/package/@typescript-eslint/parser)
702+
703+
Default: `undefined`
704+
705+
This option allows you to provide a custom module resolution. The value should point to a JS file that default exports (`export default`, or `module.exports =`, or `export =`) a file with the following interface:
706+
707+
```
708+
interface ModuleResolver {
709+
version: 1;
710+
resolveModuleNames(
711+
moduleNames: string[],
712+
containingFile: string,
713+
reusedNames: string[] | undefined,
714+
redirectedReference: ts.ResolvedProjectReference | undefined,
715+
options: ts.CompilerOptions,
716+
): (ts.ResolvedModule | undefined)[];
717+
}
718+
```
719+
Refer to the TypeScript Wiki for an example on how to write the resolveModuleNames function.
720+
721+
Note that if you pass custom programs via options.programs this option will not have any effect over them (you can simply add the custom resolution on them directly).
722+
599723
## License
600724
601725
CC-SA-2.5

0 commit comments

Comments
 (0)