Skip to content

Commit

Permalink
feat: add package.json exports for public packages (#6458)
Browse files Browse the repository at this point in the history
  • Loading branch information
bradzacher committed Feb 22, 2023
1 parent fc2df63 commit d676683
Show file tree
Hide file tree
Showing 59 changed files with 517 additions and 298 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Expand Up @@ -129,6 +129,7 @@ jobs:
'eslint-plugin-internal',
'eslint-plugin-tslint',
'parser',
'repo-tools',
'scope-manager',
'type-utils',
'typescript-estree',
Expand Down
20 changes: 12 additions & 8 deletions package.json
Expand Up @@ -16,6 +16,7 @@
"armano2",
"Jed Fox"
],
"type": "commonjs",
"license": "BSD-2-Clause",
"repository": "typescript-eslint/typescript-eslint",
"bugs": {
Expand Down Expand Up @@ -121,13 +122,16 @@
"jest-resolve": "^29",
"jest-util": "^29",
"pretty-format": "^29",
"@swc/core-android-arm-eabi": "npm:dummypkg-a@1.0.0",
"@swc/core-android-arm64": "npm:dummypkg-a@1.0.0",
"@swc/core-freebsd-x64": "npm:dummypkg-a@1.0.0",
"@swc/core-linux-arm-gnueabihf": "npm:dummypkg-a@1.0.0",
"@swc/core-linux-arm64-gnu": "npm:dummypkg-a@1.0.0",
"@swc/core-linux-arm64-musl": "npm:dummypkg-a@1.0.0",
"@swc/core-win32-arm64-msvc": "npm:dummypkg-a@1.0.0",
"@swc/core-win32-ia32-msvc": "npm:dummypkg-a@1.0.0"
"@swc/core-android-arm-eabi": "file:./tools/dummypkg",
"@swc/core-android-arm64": "file:./tools/dummypkg",
"@swc/core-freebsd-x64": "file:./tools/dummypkg",
"@swc/core-linux-arm-gnueabihf": "file:./tools/dummypkg",
"@swc/core-linux-arm64-gnu": "file:./tools/dummypkg",
"@swc/core-linux-arm64-musl": "file:./tools/dummypkg",
"@swc/core-win32-arm64-msvc": "file:./tools/dummypkg",
"@swc/core-win32-ia32-msvc": "file:./tools/dummypkg",
"@types/eslint": "file:./tools/dummypkg",
"@types/eslint-scope": "file:./tools/dummypkg",
"@types/estree": "file:./tools/dummypkg"
}
}
Expand Up @@ -13,6 +13,4 @@
* This should be the only place in the package that we import from typescript-estree.
*/

// We need to ignore this lint error regarding it being missing from the package.json, see above.
// eslint-disable-next-line import/no-extraneous-dependencies
export { parse } from '@typescript-eslint/typescript-estree';
Expand Up @@ -528,7 +528,7 @@ export default createRule<Options, MessageIds>({
}

const typeString = checker.typeToString(type);
if (/^RunTests\b/.test(typeString)) {
if (/^(TSESLint\.)?RunTests\b/.test(typeString)) {
checkedObjects.add(node);

for (const prop of node.properties) {
Expand Down Expand Up @@ -558,12 +558,12 @@ export default createRule<Options, MessageIds>({
return;
}

if (/^ValidTestCase\b/.test(typeString)) {
if (/^(TSESLint\.)?ValidTestCase\b/.test(typeString)) {
checkInvalidTest(node);
return;
}

if (/^InvalidTestCase\b/.test(typeString)) {
if (/^(TSESLint\.)?InvalidTestCase\b/.test(typeString)) {
checkInvalidTest(node);
for (const testProp of node.properties) {
if (
Expand Down
34 changes: 23 additions & 11 deletions packages/eslint-plugin-tslint/package.json
@@ -1,24 +1,26 @@
{
"name": "@typescript-eslint/eslint-plugin-tslint",
"version": "5.53.0",
"main": "dist/index.js",
"typings": "src/index.ts",
"description": "ESLint plugin that wraps a TSLint configuration and lints the whole source using TSLint",
"keywords": [
"eslint",
"eslintplugin",
"eslint-plugin",
"tslint"
],
"engines": {
"node": "^14.18.0 || ^16.0.0 || >=18.0.0"
},
"files": [
"dist",
"package.json",
"README.md",
"LICENSE"
],
"type": "commonjs",
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/index.js"
},
"./package.json": {
"require": "./package.json"
}
},
"engines": {
"node": "^14.18.0 || ^16.0.0 || >=18.0.0"
},
"repository": {
"type": "git",
"url": "https://github.com/typescript-eslint/typescript-eslint.git",
Expand All @@ -28,6 +30,12 @@
"url": "https://github.com/typescript-eslint/typescript-eslint/issues"
},
"license": "MIT",
"keywords": [
"eslint",
"eslintplugin",
"eslint-plugin",
"tslint"
],
"scripts": {
"build": "tsc -b tsconfig.build.json",
"clean": "tsc -b tsconfig.build.json --clean",
Expand All @@ -49,5 +57,9 @@
"devDependencies": {
"@types/lodash": "*",
"@typescript-eslint/parser": "5.53.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
}
5 changes: 0 additions & 5 deletions packages/eslint-plugin-tslint/tests/tsconfig.json

This file was deleted.

4 changes: 4 additions & 0 deletions packages/eslint-plugin-tslint/tsconfig.build.json
@@ -1,6 +1,10 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
// specifically disable declarations for the plugin
// see reasoning in packages/eslint-plugin/rules.d.ts
"declaration": false,
"declarationMap": false,
"outDir": "./dist",
"rootDir": "./src",
"resolveJsonModule": true
Expand Down
9 changes: 7 additions & 2 deletions packages/eslint-plugin/index.d.ts
@@ -1,4 +1,9 @@
import type { TSESLint } from '@typescript-eslint/utils';

export const rules: Record<string, TSESLint.RuleModule<string, unknown[]>>;
export const configs: Record<string, TSESLint.Linter.Config>;
import type rules from './rules';

declare const cjsExport: {
configs: Record<string, TSESLint.Linter.Config>;
rules: typeof rules;
};
export = cjsExport;
38 changes: 24 additions & 14 deletions packages/eslint-plugin/package.json
Expand Up @@ -2,15 +2,6 @@
"name": "@typescript-eslint/eslint-plugin",
"version": "5.53.0",
"description": "TypeScript plugin for ESLint",
"keywords": [
"eslint",
"eslintplugin",
"eslint-plugin",
"typescript"
],
"engines": {
"node": "^14.18.0 || ^16.0.0 || >=18.0.0"
},
"files": [
"dist",
"docs",
Expand All @@ -19,6 +10,23 @@
"README.md",
"LICENSE"
],
"type": "commonjs",
"exports": {
".": {
"types": "./index.d.ts",
"require": "./dist/index.js"
},
"./package.json": {
"require": "./package.json"
},
"./use-at-your-own-risk/rules": {
"types": "./rules.d.ts",
"require": "./dist/rules/index.js"
}
},
"engines": {
"node": "^14.18.0 || ^16.0.0 || >=18.0.0"
},
"repository": {
"type": "git",
"url": "https://github.com/typescript-eslint/typescript-eslint.git",
Expand All @@ -28,16 +36,20 @@
"url": "https://github.com/typescript-eslint/typescript-eslint/issues"
},
"license": "MIT",
"main": "dist/index.js",
"types": "index.d.ts",
"keywords": [
"eslint",
"eslintplugin",
"eslint-plugin",
"typescript"
],
"scripts": {
"build": "tsc -b tsconfig.build.json",
"check-docs": "jest tests/docs.test.ts --runTestsByPath --silent --runInBand",
"check-configs": "jest tests/configs.test.ts --runTestsByPath --silent --runInBand",
"clean": "tsc -b tsconfig.build.json --clean",
"postclean": "rimraf dist && rimraf coverage",
"format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore",
"generate:breaking-changes": "yarn tsx tools/generate-breaking-changes.ts",
"generate:breaking-changes": "yarn tsx tools/generate-breaking-changes.mts",
"generate:configs": "yarn tsx tools/generate-configs.ts",
"lint": "nx lint",
"test": "jest --coverage",
Expand All @@ -61,9 +73,7 @@
"@types/marked": "*",
"@types/natural-compare-lite": "^1.4.0",
"@types/prettier": "*",
"chalk": "^5.0.1",
"cross-fetch": "*",
"grapheme-splitter": "^1.0.4",
"json-schema": "*",
"markdown-table": "^3.0.2",
"marked": "^4.0.15",
Expand Down
44 changes: 44 additions & 0 deletions packages/eslint-plugin/rules.d.ts
@@ -0,0 +1,44 @@
/*
We purposely don't generate types for our plugin because TL;DR:
1) there's no real reason that anyone should do a typed import of our rules,
2) it would require us to change our code so there aren't as many inferred types
This type declaration exists as a hacky way to add a type to the export for our
internal packages that require it.
*** Long reason ***
When you turn on declaration files, TS requires all types to be "fully resolvable"
without changes to the code.
All of our lint rules `export default createRule(...)`, which means they all
implicitly reference the `TSESLint.Rule` type for the export.
TS wants to transpile each rule file to this `.d.ts` file:
```ts
import type { TSESLint } from '@typescript-eslint/utils';
declare const _default: TSESLint.RuleModule<TMessageIds, TOptions, TSESLint.RuleListener>;
export default _default;
```
Because we don't import `TSESLint` in most files, it means that TS would have to
insert a new import during the declaration emit to make this work.
However TS wants to avoid adding new imports to the file because a new module
could have type side-effects (like global augmentation) which could cause weird
type side-effects in the decl file that wouldn't exist in source TS file.
So TS errors on most of our rules with the following error:
```
The inferred type of 'default' cannot be named without a reference to
'../../../../node_modules/@typescript-eslint/utils/src/ts-eslint/Rule'.
This is likely not portable. A type annotation is necessary. ts(2742)
```
*/

import type { RuleModule } from '@typescript-eslint/utils/ts-eslint';

export interface TypeScriptESLintRules {
[ruleName: string]: RuleModule<string, unknown[]>;
}
declare const rules: TypeScriptESLintRules;
export = rules;
5 changes: 1 addition & 4 deletions packages/eslint-plugin/src/rules/prefer-ts-expect-error.ts
@@ -1,9 +1,6 @@
import type { TSESTree } from '@typescript-eslint/utils';
import { AST_TOKEN_TYPES } from '@typescript-eslint/utils';
import type {
RuleFix,
RuleFixer,
} from '@typescript-eslint/utils/dist/ts-eslint';
import type { RuleFix, RuleFixer } from '@typescript-eslint/utils/ts-eslint';

import * as util from '../util';

Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin/src/util/astUtils.ts
Expand Up @@ -4,7 +4,7 @@ import * as ts from 'typescript';
import { escapeRegExp } from './escapeRegExp';

// deeply re-export, for convenience
export * from '@typescript-eslint/utils/dist/ast-utils';
export * from '@typescript-eslint/utils/ast-utils';

// The following is copied from `eslint`'s source code since it doesn't exist in eslint@5.
// https://github.com/eslint/eslint/blob/145aec1ab9052fbca96a44d04927c595951b1536/lib/rules/utils/ast-utils.js#L1751-L1779
Expand Down
3 changes: 1 addition & 2 deletions packages/eslint-plugin/src/util/collectUnusedVariables.ts
@@ -1,5 +1,4 @@
import { ImplicitLibVariable } from '@typescript-eslint/scope-manager';
import { Visitor } from '@typescript-eslint/scope-manager/dist/referencer/Visitor';
import { ImplicitLibVariable, Visitor } from '@typescript-eslint/scope-manager';
import type { TSESTree } from '@typescript-eslint/utils';
import {
AST_NODE_TYPES,
Expand Down
8 changes: 5 additions & 3 deletions packages/eslint-plugin/tests/RuleTester.ts
Expand Up @@ -5,11 +5,13 @@ function getFixturesRootDir(): string {
return path.join(__dirname, 'fixtures');
}

const { batchedSingleLineTests, RuleTester, noFormat } = ESLintUtils;
const { batchedSingleLineTests } = ESLintUtils;
export {
RuleTester,
RunTests,
ValidTestCase,
InvalidTestCase,
} from '@typescript-eslint/utils/dist/eslint-utils/rule-tester/RuleTester';
noFormat,
} from '@typescript-eslint/utils/eslint-utils/rule-tester';

export { batchedSingleLineTests, getFixturesRootDir, noFormat, RuleTester };
export { batchedSingleLineTests, getFixturesRootDir };
2 changes: 1 addition & 1 deletion packages/eslint-plugin/tests/configs.test.ts
@@ -1,4 +1,4 @@
import type { RuleRecommendation } from '@typescript-eslint/utils/src/ts-eslint';
import type { RuleRecommendation } from '@typescript-eslint/utils/ts-eslint';

import plugin from '../src/index';
import rules from '../src/rules';
Expand Down
@@ -0,0 +1,4 @@
export type Type1 = 1;
export type Type2 = 1;
export const value1 = 2;
export const value2 = 2;
4 changes: 4 additions & 0 deletions packages/eslint-plugin/tests/fixtures/mixed-enums-decl.ts
@@ -0,0 +1,4 @@
export enum Enum {
A = 'A',
B = 'B',
}
7 changes: 6 additions & 1 deletion packages/eslint-plugin/tests/fixtures/tsconfig.json
Expand Up @@ -8,5 +8,10 @@
"lib": ["es2015", "es2017", "esnext"],
"experimentalDecorators": true
},
"include": ["file.ts", "react.tsx"]
"include": [
"file.ts",
"consistent-type-exports.ts",
"mixed-enums-decl.ts",
"react.tsx"
]
}

0 comments on commit d676683

Please sign in to comment.