mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-23 07:07:09 -05:00
Add a new compiler option moduleSuffixes to expand the node module resolver's search algorithm (#48189)
* Add moduleSuffixes compiler option and related tests. Update baselines for compiler options tests. * Add a flag to the command-line parser which allows "list" params to preserve "falsy" values such as empty strings. Falsy values are normally stripped out. * Add tests. Rework resolver logic to only run module-suffix code when needed. * PR feedback * Add test * Remove unnecessary conditional.
This commit is contained in:
14
tests/cases/compiler/moduleResolutionWithSuffixes_empty.ts
Normal file
14
tests/cases/compiler/moduleResolutionWithSuffixes_empty.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
// moduleSuffixes is empty. Normal module resolution should occur.
|
||||
|
||||
// @filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"traceResolution": true,
|
||||
"moduleSuffixes": []
|
||||
}
|
||||
}
|
||||
// @filename: /index.ts
|
||||
import { base } from "./foo";
|
||||
// @filename: /foo.ts
|
||||
export function base() {}
|
||||
@@ -0,0 +1,12 @@
|
||||
// moduleSuffixes is not specified. Normal module resolution should occur.
|
||||
// @filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"traceResolution": true,
|
||||
}
|
||||
}
|
||||
// @filename: /index.ts
|
||||
import { base } from "./foo";
|
||||
// @filename: /foo.ts
|
||||
export function base() {}
|
||||
17
tests/cases/compiler/moduleResolutionWithSuffixes_one.ts
Normal file
17
tests/cases/compiler/moduleResolutionWithSuffixes_one.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
// moduleSuffixes has one entry and there's a matching file.
|
||||
|
||||
// @filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"traceResolution": true,
|
||||
"moduleSuffixes": [".ios"]
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: /index.ts
|
||||
import { ios } from "./foo";
|
||||
// @filename: /foo.ios.ts
|
||||
export function ios() {}
|
||||
// @filename: /foo.ts
|
||||
export function base() {}
|
||||
@@ -0,0 +1,15 @@
|
||||
// moduleSuffixes has one blank entry. Normal module resolution should occur.
|
||||
|
||||
// @filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"traceResolution": true,
|
||||
"moduleSuffixes": [""]
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: /index.ts
|
||||
import { base } from "./foo";
|
||||
// @filename: /foo.ts
|
||||
export function base() {}
|
||||
@@ -0,0 +1,15 @@
|
||||
// moduleSuffixes has one entry but there isn't a matching file. Module resolution should fail.
|
||||
|
||||
// @filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"traceResolution": true,
|
||||
"moduleSuffixes": [".ios"]
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: /index.ts
|
||||
import { ios } from "./foo";
|
||||
// @filename: /foo.ts
|
||||
export function base() {}
|
||||
@@ -0,0 +1,17 @@
|
||||
// moduleSuffixes has one entry and there's a matching dir with an index file.
|
||||
|
||||
// @filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"traceResolution": true,
|
||||
"moduleSuffixes": [".ios"]
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: /index.ts
|
||||
import { ios } from "./foo";
|
||||
// @filename: /foo/index.ios.ts
|
||||
export function ios() {}
|
||||
// @filename: /foo/index.ts
|
||||
export function base() {}
|
||||
@@ -0,0 +1,31 @@
|
||||
// moduleSuffixes has one entry and there's a matching package.
|
||||
// @fullEmitPaths: true
|
||||
// @filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": false,
|
||||
"outDir": "bin",
|
||||
"moduleResolution": "node",
|
||||
"traceResolution": true,
|
||||
"moduleSuffixes": [".ios"]
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: /node_modules/some-library/index.ios.js
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
function ios() {}
|
||||
exports.ios = ios;
|
||||
// @filename: /node_modules/some-library/index.ios.d.ts
|
||||
export declare function ios(): void;
|
||||
// @filename: /node_modules/some-library/index.js
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
function base() {}
|
||||
exports.base = base;
|
||||
// @filename: /node_modules/some-library/index.d.ts
|
||||
export declare function base(): void;
|
||||
|
||||
// @filename: /index.ts
|
||||
import { ios } from "some-library";
|
||||
@@ -0,0 +1,31 @@
|
||||
// moduleSuffixes has one entry and there's a matching package with a specific path.
|
||||
// @fullEmitPaths: true
|
||||
// @filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": false,
|
||||
"outDir": "bin",
|
||||
"moduleResolution": "node",
|
||||
"traceResolution": true,
|
||||
"moduleSuffixes": [".ios"]
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: /node_modules/some-library/foo.ios.js
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
function iosfoo() {}
|
||||
exports.iosfoo = iosfoo;
|
||||
// @filename: /node_modules/some-library/foo.ios.d.ts
|
||||
export declare function iosfoo(): void;
|
||||
// @filename: /node_modules/some-library/foo.js
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
function basefoo() {}
|
||||
exports.basefoo = basefoo;
|
||||
// @filename: /node_modules/some-library/foo.d.ts
|
||||
export declare function basefoo(): void;
|
||||
|
||||
// @filename: /index.ts
|
||||
import { iosfoo } from "some-library/foo";
|
||||
@@ -0,0 +1,38 @@
|
||||
// moduleSuffixes has one entry and there's a matching package. use the 'paths' option to map the package.
|
||||
// @fullEmitPaths: true
|
||||
// @filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": false,
|
||||
"outDir": "bin",
|
||||
"moduleResolution": "node",
|
||||
"traceResolution": true,
|
||||
"moduleSuffixes": [".ios"],
|
||||
"baseUrl": "/",
|
||||
"paths": {
|
||||
"some-library": ["node_modules/some-library/lib"],
|
||||
"some-library/*": ["node_modules/some-library/lib/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: /node_modules/some-library/lib/index.ios.js
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
function ios() {}
|
||||
exports.ios = ios;
|
||||
// @filename: /node_modules/some-library/lib/index.ios.d.ts
|
||||
export declare function ios(): void;
|
||||
// @filename: /node_modules/some-library/lib/index.js
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
function base() {}
|
||||
exports.base = base;
|
||||
// @filename: /node_modules/some-library/lib/index.d.ts
|
||||
export declare function base(): void;
|
||||
|
||||
// @filename: /test.ts
|
||||
import { ios } from "some-library";
|
||||
import { ios as ios2 } from "some-library/index";
|
||||
import { ios as ios3 } from "some-library/index.js";
|
||||
@@ -0,0 +1,18 @@
|
||||
// moduleSuffixes has one entry and there's a matching package with TS files.
|
||||
// @fullEmitPaths: true
|
||||
// @filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "bin",
|
||||
"moduleResolution": "node",
|
||||
"traceResolution": true,
|
||||
"moduleSuffixes": [".ios"]
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: /node_modules/some-library/index.ios.ts
|
||||
export function ios() {}
|
||||
// @filename: /node_modules/some-library/index.ts
|
||||
export function base() {}
|
||||
// @filename: /test.ts
|
||||
import { ios } from "some-library";
|
||||
@@ -0,0 +1,26 @@
|
||||
// moduleSuffixes has one entry and there's a matching file. module name explicitly includes JS file extension.
|
||||
// @fullEmitPaths: true
|
||||
// @filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": false,
|
||||
"outDir": "bin",
|
||||
"moduleResolution": "node",
|
||||
"traceResolution": true,
|
||||
"moduleSuffixes": [".ios"]
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: /index.ts
|
||||
import { ios } from "./foo.js";
|
||||
// @filename: /foo.ios.js
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
function ios() {}
|
||||
exports.ios = ios;
|
||||
// @filename: /foo.js
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
function base() {}
|
||||
exports.base = base;
|
||||
@@ -0,0 +1,25 @@
|
||||
// moduleSuffixes has one entry and there's a matching file. module name explicitly includes JSON file extension.
|
||||
// @fullEmitPaths: true
|
||||
// @filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
"outDir": "bin",
|
||||
"moduleResolution": "node",
|
||||
"traceResolution": true,
|
||||
"moduleSuffixes": [".ios"]
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: /index.ts
|
||||
import foo from "./foo.json";
|
||||
console.log(foo.ios);
|
||||
// @filename: /foo.ios.json
|
||||
{
|
||||
"ios": "platform ios"
|
||||
}
|
||||
// @filename: /foo.json
|
||||
{
|
||||
"base": "platform base"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// moduleSuffixes has three entries, and the last one is blank. Module resolution should match on the first suffix.
|
||||
|
||||
// @filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"traceResolution": true,
|
||||
"moduleSuffixes": ["-ios", "__native", ""]
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: /index.ts
|
||||
import { ios } from "./foo";
|
||||
// @filename: /foo-ios.ts
|
||||
export function ios() {}
|
||||
// @filename: /foo__native.ts
|
||||
export function native() {}
|
||||
// @filename: /foo.ts
|
||||
export function base() {}
|
||||
@@ -0,0 +1,17 @@
|
||||
// moduleSuffixes has three entries, and the last one is blank. Module resolution should match on the second suffix.
|
||||
|
||||
// @filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"traceResolution": true,
|
||||
"moduleSuffixes": ["-ios", "__native", ""]
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: /index.ts
|
||||
import { native } from "./foo";
|
||||
// @filename: /foo__native.ts
|
||||
export function native() {}
|
||||
// @filename: /foo.ts
|
||||
export function base() {}
|
||||
@@ -0,0 +1,15 @@
|
||||
// moduleSuffixes has three entries, and the last one is blank. Module resolution should match on the blank suffix.
|
||||
|
||||
// @filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"traceResolution": true,
|
||||
"moduleSuffixes": ["-ios", "__native", ""]
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: /index.ts
|
||||
import { base } from "./foo";
|
||||
// @filename: /foo.ts
|
||||
export function base() {}
|
||||
@@ -0,0 +1,13 @@
|
||||
// moduleSuffixes has three entries, and the last one is blank. Module resolution should fail.
|
||||
|
||||
// @filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"traceResolution": true,
|
||||
"moduleSuffixes": ["-ios", "__native", ""]
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: /index.ts
|
||||
import { base } from "./foo";
|
||||
Reference in New Issue
Block a user