From c82dbbb11b144d771b6679471ba7ac94e50df194 Mon Sep 17 00:00:00 2001 From: JounQin Date: Wed, 20 Jul 2022 17:24:56 +0800 Subject: [PATCH] feat: replace tsconfig-paths + typescript with get-tsconfig --- .changeset/README.md | 8 ++++ .changeset/config.json | 9 ++++ .eslintignore | 2 + .github/FUNDING.yml | 23 +++++----- .github/workflows/rebase-upstream.yml | 29 ++++++++++++ .github/workflows/release.yml | 36 +++++++++++++++ .nycrc | 3 +- README.md | 21 +++++++++ package.json | 22 ++++----- src/ExportMap.js | 59 +++++++++++-------------- tests/src/core/getExports.js | 14 +++--- tests/src/rules/no-relative-packages.js | 4 +- 12 files changed, 163 insertions(+), 67 deletions(-) create mode 100644 .changeset/README.md create mode 100644 .changeset/config.json create mode 100644 .github/workflows/rebase-upstream.yml create mode 100644 .github/workflows/release.yml diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 000000000..e5b6d8d6a --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 000000000..29c7d325f --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://unpkg.com/@changesets/config/schema.json", + "commit": false, + "linked": [], + "access": "public", + "baseBranch": "fork-release", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.eslintignore b/.eslintignore index 9d2200682..b35ee2cee 100644 --- a/.eslintignore +++ b/.eslintignore @@ -7,6 +7,8 @@ tests/files/with-syntax-error tests/files/just-json-files/invalid.json tests/files/typescript-d-ts/ resolvers/webpack/test/files +# A downleveled vendor file generate by `npm run downlevel-get-tsconfig` +src/get-tsconfig.js # we want to ignore "tests/files" here, but unfortunately doing so would # interfere with unit test and fail it for some reason. # tests/files diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 0ef28872f..663dc4b5f 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,12 +1,11 @@ -# These are supported funding model platforms - -github: [ljharb] -patreon: # Replace with a single Patreon username -open_collective: eslint-plugin-import # Replace with a single Open Collective username -ko_fi: # Replace with a single Ko-fi username -tidelift: npm/eslint-plugin-import -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: # Replace with a single Liberapay username -issuehunt: # Replace with a single IssueHunt username -otechie: # Replace with a single Otechie username -custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] +github: + - JounQin + - 1stG + - rx-ts + - un-ts +patreon: 1stG +open_collective: unts +custom: + - https://opencollective.com/1stG + - https://opencollective.com/rxts + - https://afdian.net/@JounQin diff --git a/.github/workflows/rebase-upstream.yml b/.github/workflows/rebase-upstream.yml new file mode 100644 index 000000000..b305e42cd --- /dev/null +++ b/.github/workflows/rebase-upstream.yml @@ -0,0 +1,29 @@ +name: Rebase + +on: + workflow_dispatch: + schedule: + - cron: '0 0 * * *' + +jobs: + rebase: + name: Rebase and Push + runs-on: ubuntu-latest + steps: + - name: Checkout Repo + uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: fork-release + + - name: Set Git Info + run: | + git config --global user.email admin@1stg.me + git config --global user.name JounQin + git remote add upstream https://github.com/import-js/eslint-plugin-import.git + + - name: Rebase and Push + run: | + git fetch upstream main:main + git rebase upstream/main + git push -f diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..f78091c40 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,36 @@ +name: Release + +on: + push: + branches: + - fork-release + +jobs: + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Checkout Repo + uses: actions/checkout@v3 + with: + # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits + fetch-depth: 0 + + - name: Setup Node.js 16 + uses: actions/setup-node@v3 + with: + node-version: 16 + + - name: Install Dependencies + run: npm install + + - name: Publish to npm + uses: changesets/action@v1 + with: + publish: npx @changesets/cli publish + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Sync to cnpm + run: npx cnpm sync eslint-plugin-i diff --git a/.nycrc b/.nycrc index 5d75e2157..b12bec5a0 100644 --- a/.nycrc +++ b/.nycrc @@ -14,6 +14,7 @@ "resolvers/*/test", "scripts", "memo-parser", - "lib" + "lib", + "src/get-tsconfig.js" ] } diff --git a/README.md b/README.md index ca99b8faf..e23f7a242 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,24 @@ +# eslint-plugin-i + +A fork of [`eslint-plugin-import`] using [`get-tsconfig`] to replace [`tsconfig-paths`](https://github.com/dividab/tsconfig-paths) and heavy [`typescript`](https://github.com/microsoft/TypeScript) under the hood. + +It will rebase and try to release in order to sync with the upstream every day, see [.github/workflows/rebase-upstream.yml](.github/workflows/rebase-upstream.yml) for details. + +And also you can take https://github.com/import-js/eslint-plugin-import/pull/2447 and https://github.com/import-js/eslint-plugin-import/pull/2504 to understand why this forked project exists. + +Issues related to `get-tsconfig` should be posted here or [`get-tsconfig`] instead, and other issues should be posted to [`eslint-plugin-import`] instead. + +[`eslint-plugin-import`]: https://github.com/import-js/eslint-plugin-import +[`get-tsconfig`]: https://github.com/privatenumber/get-tsconfig + +## Installation + +```bash +$ npm install -D eslint-plugin-import@npm:eslint-plugin-i@latest +``` + +--- + # eslint-plugin-import [![github actions][actions-image]][actions-url] diff --git a/package.json b/package.json index feee6e46d..422b2ba70 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,8 @@ { - "name": "eslint-plugin-import", - "version": "2.27.5", - "description": "Import with sanity.", + "name": "eslint-plugin-i", + "version": "2.27.5-3", + "description": "A fork of `eslint-plugin-import` using `get-tsconfig` to replace `tsconfig-paths` and heavy `typescript` under the hood.", + "funding": "https://opencollective.com/unts", "engines": { "node": ">=4" }, @@ -24,7 +25,7 @@ "copy-metafiles": "node --require babel-register ./scripts/copyMetafiles", "watch": "npm run tests-only -- -- --watch", "pretest": "linklocal", - "posttest": "eslint . && npm run update:eslint-docs -- --check", + "posttest": "eslint .", "mocha": "cross-env BABEL_ENV=test nyc mocha", "tests-only": "npm run mocha tests/src", "test": "npm run tests-only", @@ -37,7 +38,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/import-js/eslint-plugin-import" + "url": "https://github.com/un-es/eslint-plugin-i" }, "keywords": [ "eslint", @@ -49,11 +50,10 @@ "export" ], "author": "Ben Mosher ", + "contributors": [ + "JounQin (https://www.1stG.me) " + ], "license": "MIT", - "bugs": { - "url": "https://github.com/import-js/eslint-plugin-import/issues" - }, - "homepage": "https://github.com/import-js/eslint-plugin-import", "devDependencies": { "@angular-eslint/template-parser": "^13.5.0", "@eslint/import-test-order-redirect-scoped": "file:./tests/files/order-redirect-scoped", @@ -107,13 +107,13 @@ "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.7", "eslint-module-utils": "^2.8.0", + "get-tsconfig": "^4.6.0", "has": "^1.0.3", "is-core-module": "^2.12.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.values": "^1.1.6", "resolve": "^1.22.3", - "semver": "^6.3.0", - "tsconfig-paths": "^3.14.2" + "semver": "^6.3.0" } } diff --git a/src/ExportMap.js b/src/ExportMap.js index f61d3c170..08d734796 100644 --- a/src/ExportMap.js +++ b/src/ExportMap.js @@ -1,5 +1,5 @@ import fs from 'fs'; -import { dirname } from 'path'; +import { resolve as pathResolve } from 'path'; import doctrine from 'doctrine'; @@ -15,16 +15,14 @@ import isIgnored, { hasValidExtension } from 'eslint-module-utils/ignore'; import { hashObject } from 'eslint-module-utils/hash'; import * as unambiguous from 'eslint-module-utils/unambiguous'; -import { tsConfigLoader } from 'tsconfig-paths/lib/tsconfig-loader'; +import { getTsconfig } from 'get-tsconfig'; import includes from 'array-includes'; -let ts; - const log = debug('eslint-plugin-import:ExportMap'); const exportCache = new Map(); -const tsconfigCache = new Map(); +const tsConfigCache = new Map(); export default class ExportMap { constructor(path) { @@ -548,41 +546,34 @@ ExportMap.parse = function (path, content, context) { const source = makeSourceCode(content, ast); - function readTsConfig(context) { - const tsconfigInfo = tsConfigLoader({ - cwd: context.parserOptions && context.parserOptions.tsconfigRootDir || process.cwd(), - getEnv: (key) => process.env[key], - }); - try { - if (tsconfigInfo.tsConfigPath !== undefined) { - // Projects not using TypeScript won't have `typescript` installed. - if (!ts) { ts = require('typescript'); } // eslint-disable-line import/no-extraneous-dependencies - - const configFile = ts.readConfigFile(tsconfigInfo.tsConfigPath, ts.sys.readFile); - return ts.parseJsonConfigFileContent( - configFile.config, - ts.sys, - dirname(tsconfigInfo.tsConfigPath), - ); - } - } catch (e) { - // Catch any errors - } - - return null; - } - function isEsModuleInterop() { + const parserOptions = context.parserOptions || {}; + let tsconfigRootDir = parserOptions.tsconfigRootDir; + const project = parserOptions.project; const cacheKey = hashObject({ - tsconfigRootDir: context.parserOptions && context.parserOptions.tsconfigRootDir, + tsconfigRootDir, + project, }).digest('hex'); - let tsConfig = tsconfigCache.get(cacheKey); + let tsConfig = tsConfigCache.get(cacheKey); if (typeof tsConfig === 'undefined') { - tsConfig = readTsConfig(context); - tsconfigCache.set(cacheKey, tsConfig); + tsconfigRootDir = tsconfigRootDir || process.cwd(); + let tsconfigResult; + if (project) { + const projects = Array.isArray(project) ? project : [project]; + for (const project of projects) { + tsconfigResult = getTsconfig(pathResolve(tsconfigRootDir, project)); + if (tsconfigResult) { + break; + } + } + } else { + tsconfigResult = getTsconfig(tsconfigRootDir); + } + tsConfig = tsconfigResult && tsconfigResult.config || null; + tsConfigCache.set(cacheKey, tsConfig); } - return tsConfig && tsConfig.options ? tsConfig.options.esModuleInterop : false; + return tsConfig && tsConfig.compilerOptions ? tsConfig.compilerOptions.esModuleInterop : false; } ast.body.forEach(function (n) { diff --git a/tests/src/core/getExports.js b/tests/src/core/getExports.js index 1dd6e8801..a5165b7b0 100644 --- a/tests/src/core/getExports.js +++ b/tests/src/core/getExports.js @@ -3,7 +3,7 @@ import semver from 'semver'; import sinon from 'sinon'; import eslintPkg from 'eslint/package.json'; import typescriptPkg from 'typescript/package.json'; -import * as tsConfigLoader from 'tsconfig-paths/lib/tsconfig-loader'; +import * as getTsconfig from 'get-tsconfig'; import ExportMap from '../../../src/ExportMap'; import * as fs from 'fs'; @@ -371,11 +371,11 @@ describe('ExportMap', function () { let imports; before('load imports', function () { this.timeout(20e3); // takes a long time :shrug: - sinon.spy(tsConfigLoader, 'tsConfigLoader'); + sinon.spy(getTsconfig, 'getTsconfig'); imports = ExportMap.get('./typescript.ts', context); }); after('clear spies', function () { - tsConfigLoader.tsConfigLoader.restore(); + getTsconfig.getTsconfig.restore(); }); it('returns something for a TypeScript file', function () { @@ -413,11 +413,11 @@ describe('ExportMap', function () { tsconfigRootDir: null, }, }; - expect(tsConfigLoader.tsConfigLoader.callCount).to.equal(0); + expect(getTsconfig.getTsconfig.callCount).to.equal(0); ExportMap.parse('./baz.ts', 'export const baz = 5', customContext); - expect(tsConfigLoader.tsConfigLoader.callCount).to.equal(1); + expect(getTsconfig.getTsconfig.callCount).to.equal(1); ExportMap.parse('./baz.ts', 'export const baz = 5', customContext); - expect(tsConfigLoader.tsConfigLoader.callCount).to.equal(1); + expect(getTsconfig.getTsconfig.callCount).to.equal(1); const differentContext = { ...context, @@ -427,7 +427,7 @@ describe('ExportMap', function () { }; ExportMap.parse('./baz.ts', 'export const baz = 5', differentContext); - expect(tsConfigLoader.tsConfigLoader.callCount).to.equal(2); + expect(getTsconfig.getTsconfig.callCount).to.equal(2); }); it('should cache after parsing for an ambiguous module', function () { diff --git a/tests/src/rules/no-relative-packages.js b/tests/src/rules/no-relative-packages.js index 2d27bcc91..1ca6e11d1 100644 --- a/tests/src/rules/no-relative-packages.js +++ b/tests/src/rules/no-relative-packages.js @@ -73,11 +73,11 @@ ruleTester.run('no-relative-packages', rule, { code: 'import bar from "../bar"', filename: testFilePath('./package-named/index.js'), errors: [ { - message: `Relative import from another package is not allowed. Use \`${normalize('eslint-plugin-import/tests/files/bar')}\` instead of \`../bar\``, + message: `Relative import from another package is not allowed. Use \`${normalize('eslint-plugin-i/tests/files/bar')}\` instead of \`../bar\``, line: 1, column: 17, } ], - output: `import bar from "eslint-plugin-import/tests/files/bar"`, + output: `import bar from "eslint-plugin-i/tests/files/bar"`, }), ], });