From b11ede3c9fafbc548db011729fd64e958cde6e51 Mon Sep 17 00:00:00 2001 From: JounQin Date: Sun, 30 Jun 2019 14:57:03 +0800 Subject: [PATCH 1/6] feat: resolve .ts/.tsx/.d.ts first, and then fallback to @types/* --- index.js | 24 ++++++++++++++++++------ package-lock.json | 8 +++++++- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index 7a147927..665223eb 100644 --- a/index.js +++ b/index.js @@ -25,11 +25,9 @@ function resolveFile(source, file, config) { } let foundTsPath = null; - const extensions = Object.keys(require.extensions).concat( - '.ts', - '.tsx', - '.d.ts', - ); + const extensions = Object.keys(require.extensions); + + extensions.unshift('.ts', '.tsx', '.d.ts'); // setup tsconfig-paths const searchStart = config.directory || process.cwd(); @@ -64,6 +62,20 @@ function resolveFile(source, file, config) { foundNodePath = null; } + // naive attempt at @types/* resolution, + // iff path is neither absolute nor relative + if ( + /\.jsx?$/.test(foundNodePath) && + !/^@types[\/\\]/.test(source) && + !path.isAbsolute(source) && + source[0] !== '.' + ) { + const definitely = resolveFile('@types/' + source, file, config); + if (definitely.found) { + return definitely; + } + } + if (foundNodePath) { log('matched node path:', foundNodePath); @@ -73,7 +85,7 @@ function resolveFile(source, file, config) { }; } - log('didnt find', source); + log("didn't find", source); return { found: false, diff --git a/package-lock.json b/package-lock.json index c2501566..abdb4fe9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "eslint-import-resolver-typescript", - "version": "1.1.0", + "version": "1.1.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1111,6 +1111,12 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "prettier": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz", + "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==", + "dev": true + }, "progress": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", From 74de3d9fa2552b5d1b0eb799638a657c9af67887 Mon Sep 17 00:00:00 2001 From: JounQin Date: Sun, 30 Jun 2019 15:27:27 +0800 Subject: [PATCH 2/6] feat: use types/typings/module first to use .d.ts whenever possible --- index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 665223eb..1f577d62 100644 --- a/index.js +++ b/index.js @@ -92,9 +92,8 @@ function resolveFile(source, file, config) { }; } function packageFilter(pkg) { - if (pkg['jsnext:main']) { - pkg['main'] = pkg['jsnext:main']; - } + pkg.main = + pkg.types || pkg.typings || pkg.module || pkg['jsnext:main'] || pkg.main; return pkg; } From b4e72a54966bda12ef70791f09df5cbe0f04b889 Mon Sep 17 00:00:00 2001 From: JounQin Date: Sun, 30 Jun 2019 16:36:43 +0800 Subject: [PATCH 3/6] feat: support scoped packages from DefinitelyTyped --- index.js | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 1f577d62..4c8ff3b1 100644 --- a/index.js +++ b/index.js @@ -66,13 +66,17 @@ function resolveFile(source, file, config) { // iff path is neither absolute nor relative if ( /\.jsx?$/.test(foundNodePath) && - !/^@types[\/\\]/.test(source) && + !/^@types[/\\]/.test(source) && !path.isAbsolute(source) && source[0] !== '.' ) { - const definitely = resolveFile('@types/' + source, file, config); - if (definitely.found) { - return definitely; + const definitelyTyped = resolveFile( + '@types' + path.sep + mangleScopedPackage(source), + file, + config, + ); + if (definitelyTyped.found) { + return definitelyTyped; } } @@ -91,12 +95,29 @@ function resolveFile(source, file, config) { found: false, }; } + function packageFilter(pkg) { pkg.main = pkg.types || pkg.typings || pkg.module || pkg['jsnext:main'] || pkg.main; return pkg; } +/** + * For a scoped package, we must look in `@types/foo__bar` instead of `@types/@foo/bar`. + * + * @param {string} moduleName + * @returns {string} + */ +function mangleScopedPackage(moduleName) { + if (moduleName[0] === '@') { + const replaceSlash = moduleName.replace(path.sep, '__'); + if (replaceSlash !== moduleName) { + return replaceSlash.slice(1); // Take off the "@" + } + } + return moduleName; +} + module.exports = { interfaceVersion: 2, resolve: resolveFile, From 4f9c6dc691fed2a2073b5cbb52b6afd924b921d4 Mon Sep 17 00:00:00 2001 From: JounQin Date: Fri, 5 Jul 2019 07:40:28 +0800 Subject: [PATCH 4/6] chore: use concat instead of unshift --- index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 4c8ff3b1..a253bc9a 100644 --- a/index.js +++ b/index.js @@ -25,9 +25,9 @@ function resolveFile(source, file, config) { } let foundTsPath = null; - const extensions = Object.keys(require.extensions); - - extensions.unshift('.ts', '.tsx', '.d.ts'); + const extensions = ['.ts', '.tsx', '.d.ts'].concat( + Object.keys(require.extensions), + ); // setup tsconfig-paths const searchStart = config.directory || process.cwd(); From fe0aa6f0001904274c122d78cf0fd0757005b61f Mon Sep 17 00:00:00 2001 From: JounQin Date: Thu, 25 Jul 2019 10:12:42 +0800 Subject: [PATCH 5/6] feat: add alwaysTryTypes option, add tests --- index.js | 4 ++-- package-lock.json | 6 ++++++ package.json | 1 + tests/baseEslintConfig.js | 1 + tests/withoutPaths/dtsImportee.d.ts | 3 +++ tests/withoutPaths/index.ts | 8 ++++++++ tests/withoutPaths/subfolder/dtsImportee.d.ts | 3 +++ 7 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 tests/withoutPaths/dtsImportee.d.ts create mode 100644 tests/withoutPaths/subfolder/dtsImportee.d.ts diff --git a/index.js b/index.js index a253bc9a..b04ac7b3 100644 --- a/index.js +++ b/index.js @@ -63,9 +63,9 @@ function resolveFile(source, file, config) { } // naive attempt at @types/* resolution, - // iff path is neither absolute nor relative + // if path is neither absolute nor relative if ( - /\.jsx?$/.test(foundNodePath) && + (config.alwaysTryTypes || /\.jsx?$/.test(foundNodePath)) && !/^@types[/\\]/.test(source) && !path.isAbsolute(source) && source[0] !== '.' diff --git a/package-lock.json b/package-lock.json index abdb4fe9..6fd093d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,12 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" }, + "@types/unist": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", + "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==", + "dev": true + }, "acorn": { "version": "5.7.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", diff --git a/package.json b/package.json index f0f471db..c239bac9 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "eslint-plugin-import": "*" }, "devDependencies": { + "@types/unist": "^2.0.3", "dummy.js": "file:dummy.js", "eslint": "^5.6.1", "eslint-plugin-import": "^2.14.0", diff --git a/tests/baseEslintConfig.js b/tests/baseEslintConfig.js index d89d0483..dc61b8d4 100644 --- a/tests/baseEslintConfig.js +++ b/tests/baseEslintConfig.js @@ -26,6 +26,7 @@ module.exports = dirname => ({ 'import/resolver': { [path.resolve(`${__dirname}/../index.js`)]: { directory: dirname, + alwaysTryTypes: true }, }, }, diff --git a/tests/withoutPaths/dtsImportee.d.ts b/tests/withoutPaths/dtsImportee.d.ts new file mode 100644 index 00000000..dbca4190 --- /dev/null +++ b/tests/withoutPaths/dtsImportee.d.ts @@ -0,0 +1,3 @@ +declare const content : 'yes'; + +export default content; diff --git a/tests/withoutPaths/index.ts b/tests/withoutPaths/index.ts index b050f75f..e612f25a 100644 --- a/tests/withoutPaths/index.ts +++ b/tests/withoutPaths/index.ts @@ -1,9 +1,17 @@ // import relative import './tsImportee' import './tsxImportee' +import './dtsImportee' +import './subfolder/dtsImportee' import './subfolder/tsImportee' import './subfolder/tsxImportee' // import from node_module import 'typescript' import 'dummy.js' + +// import from `@types/` +import 'json5' + +// enable alwaysTryTypes +import 'unist' diff --git a/tests/withoutPaths/subfolder/dtsImportee.d.ts b/tests/withoutPaths/subfolder/dtsImportee.d.ts new file mode 100644 index 00000000..dbca4190 --- /dev/null +++ b/tests/withoutPaths/subfolder/dtsImportee.d.ts @@ -0,0 +1,3 @@ +declare const content : 'yes'; + +export default content; From 23e2e8cf71ee6c19da9f55e85b2ab34543d2a12e Mon Sep 17 00:00:00 2001 From: JounQin Date: Thu, 25 Jul 2019 10:51:31 +0800 Subject: [PATCH 6/6] fix: only check alwaysTryTypes if foundNodePath is null --- index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index b04ac7b3..bf96e653 100644 --- a/index.js +++ b/index.js @@ -65,7 +65,8 @@ function resolveFile(source, file, config) { // naive attempt at @types/* resolution, // if path is neither absolute nor relative if ( - (config.alwaysTryTypes || /\.jsx?$/.test(foundNodePath)) && + (/\.jsx?$/.test(foundNodePath) || + (config.alwaysTryTypes && !foundNodePath)) && !/^@types[/\\]/.test(source) && !path.isAbsolute(source) && source[0] !== '.'