Skip to content

Commit e70a572

Browse files
authored
replace wildcard re-exports with individual exports (#12508)
1 parent f79bf70 commit e70a572

File tree

20 files changed

+367
-119
lines changed

20 files changed

+367
-119
lines changed

.api-reports/api-report-react.api.md

Lines changed: 70 additions & 70 deletions
Large diffs are not rendered by default.

.size-limits.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (CJS)": 42554,
3-
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (production) (CJS)": 37874,
4-
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\"": 32871,
5-
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (production)": 27681
2+
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (CJS)": 42953,
3+
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (production) (CJS)": 38255,
4+
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\"": 32954,
5+
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (production)": 27724
66
}

eslint-local-rules/import-from-export.ts

Lines changed: 62 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { dirname, join, relative, resolve, sep } from "node:path";
22

3+
import type { TSESTree as AST } from "@typescript-eslint/types";
34
import { ESLintUtils } from "@typescript-eslint/utils";
45
import { $ } from "zx";
56

@@ -41,37 +42,81 @@ function findNearestEntryPointFolder(filename: string) {
4142

4243
export const importFromExport = ESLintUtils.RuleCreator.withoutDocs({
4344
create(context) {
45+
function rule(node: AST.ImportDeclaration | AST.ExportNamedDeclaration) {
46+
if (!node.source || !node.source.value.startsWith(".")) {
47+
return;
48+
}
49+
const resolvedTarget = resolve(
50+
dirname(context.physicalFilename),
51+
node.source.value
52+
);
53+
if (resolvedTarget in entryPoints) {
54+
context.report({
55+
node: node.source,
56+
messageId: "importFromExport",
57+
fix(fixer) {
58+
return fixer.replaceTextRange(
59+
node.source.range,
60+
`"${entryPoints[resolvedTarget]}"`
61+
);
62+
},
63+
});
64+
}
65+
}
4466
return {
45-
ImportDeclaration(node) {
46-
if (!node.source.value.startsWith(".")) {
67+
ImportDeclaration: rule,
68+
// TODO: enable this in a separate PR for easier review
69+
// ExportNamedDeclaration: rule,
70+
};
71+
},
72+
meta: {
73+
messages: {
74+
importFromExport:
75+
"Don't use relative imports to import from official entrypoints.",
76+
},
77+
type: "problem",
78+
schema: [],
79+
fixable: "code",
80+
},
81+
defaultOptions: [],
82+
});
83+
84+
export const noDuplicateExports = ESLintUtils.RuleCreator.withoutDocs({
85+
create(context) {
86+
const seenExports = new Map<string, AST.ExportNamedDeclaration>();
87+
return {
88+
ExportNamedDeclaration(node) {
89+
if (!node.source) {
4790
return;
4891
}
49-
const resolvedTarget = resolve(
50-
dirname(context.physicalFilename),
51-
node.source.value
52-
);
53-
if (resolvedTarget in entryPoints) {
92+
const name = node.source.value + ":" + node.exportKind;
93+
const alreadySeen = seenExports.get(name);
94+
if (alreadySeen) {
5495
context.report({
55-
node: node.source,
56-
messageId: "importFromExport",
57-
fix(fixer) {
58-
return fixer.replaceTextRange(
59-
node.source.range,
60-
`"${entryPoints[resolvedTarget]}"`
61-
);
96+
node: node,
97+
messageId: "noDuplicateExports",
98+
*fix(fixer) {
99+
for (const specifier of node.specifiers) {
100+
yield fixer.insertTextBefore(
101+
alreadySeen.specifiers[0],
102+
context.sourceCode.getText(specifier) + ","
103+
);
104+
}
105+
yield fixer.remove(node);
62106
},
63107
});
64108
}
109+
seenExports.set(name, node);
65110
},
66111
};
67112
},
68113
meta: {
69114
messages: {
70-
importFromExport:
71-
"Don't use relative imports to import from official entrypoints.",
115+
noDuplicateExports:
116+
"Don't use multiple exports statements with the same source.",
72117
},
73-
type: "problem",
74118
schema: [],
119+
type: "problem",
75120
fixable: "code",
76121
},
77122
defaultOptions: [],

eslint-local-rules/index.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { rule as forbidActInDisabledActEnvironment } from "./forbid-act-in-disab
22
import {
33
importFromExport,
44
importFromInsideOtherExport,
5+
noDuplicateExports,
56
noInternalImportOfficialExport,
67
} from "./import-from-export.ts";
78
import { rule as requireDisableActEnvironment } from "./require-disable-act-environment.ts";
@@ -14,4 +15,5 @@ export default {
1415
"import-from-export": importFromExport,
1516
"import-from-inside-other-export": importFromInsideOtherExport,
1617
"no-internal-import-official-export": noInternalImportOfficialExport,
18+
"no-duplicate-exports": noDuplicateExports,
1719
};

eslint.config.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ export default [
106106
].map((file) => path.resolve(__dirname, file)),
107107
},
108108
],
109+
"local-rules/no-duplicate-exports": "error",
109110
},
110111
},
111112
...fixupConfigRules(compat.extends("plugin:react-hooks/recommended")).map(
@@ -139,7 +140,6 @@ export default [
139140

140141
rules: {
141142
"react-compiler/react-compiler": "error",
142-
143143
"@typescript-eslint/consistent-type-imports": [
144144
"error",
145145
{
@@ -177,6 +177,7 @@ export default [
177177
message:
178178
"Please only use the namespace import syntax (`import * as React from 'react'`) for React imports!",
179179
},
180+
"ExportAllDeclaration",
180181
],
181182

182183
"import/consistent-type-specifier-style": ["error", "prefer-top-level"],

src/cache/index.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,19 @@ export { Policies } from "./inmemory/policies.js";
4747
export type { FragmentRegistryAPI } from "./inmemory/fragmentRegistry.js";
4848
export { createFragmentRegistry } from "./inmemory/fragmentRegistry.js";
4949

50-
export type * from "./inmemory/types.js";
50+
export type {
51+
ApolloReducerConfig,
52+
DiffQueryAgainstStoreOptions,
53+
IdGetter,
54+
IdGetterObj,
55+
InMemoryCacheConfig,
56+
MergeInfo,
57+
MergeTree,
58+
NormalizedCache,
59+
NormalizedCacheObject,
60+
OptimisticStoreItem,
61+
ReadMergeModifyContext,
62+
ReadQueryOptions,
63+
StoreObject,
64+
StoreValue,
65+
} from "./inmemory/types.js";

src/core/index.ts

Lines changed: 89 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,35 @@ export type {
2222
WatchQueryOptions,
2323
} from "./watchQueryOptions.js";
2424
export { isNetworkRequestSettled, NetworkStatus } from "./networkStatus.js";
25-
export type * from "./types.js";
25+
export type {
26+
ApolloQueryResult,
27+
DefaultContext,
28+
ErrorLike,
29+
InternalRefetchQueriesInclude,
30+
InternalRefetchQueriesMap,
31+
InternalRefetchQueriesOptions,
32+
InternalRefetchQueriesResult,
33+
InternalRefetchQueryDescriptor,
34+
MethodKeys,
35+
MutateResult,
36+
MutationQueryReducer,
37+
MutationQueryReducersMap,
38+
MutationUpdaterFn,
39+
MutationUpdaterFunction,
40+
OnQueryUpdated,
41+
OperationVariables,
42+
PureQueryOptions,
43+
QueryListener,
44+
QueryResult,
45+
RefetchQueriesInclude,
46+
RefetchQueriesOptions,
47+
RefetchQueriesPromiseResults,
48+
RefetchQueriesResult,
49+
RefetchQueryDescriptor,
50+
Resolvers,
51+
SubscribeResult,
52+
TypedDocumentNode,
53+
} from "./types.js";
2654
export type { FragmentMatcher, Resolver } from "./LocalState.js";
2755
export {
2856
CombinedGraphQLErrors,
@@ -34,6 +62,7 @@ export {
3462
/* Cache */
3563

3664
export type {
65+
Cache,
3766
DataProxy,
3867
FieldFunctionOptions,
3968
FieldMergeFunction,
@@ -50,7 +79,7 @@ export type {
5079
WatchFragmentOptions,
5180
WatchFragmentResult,
5281
} from "../cache/index.js";
53-
export type { Cache } from "../cache/index.js";
82+
5483
export {
5584
ApolloCache,
5685
defaultDataIdFromObject,
@@ -59,12 +88,67 @@ export {
5988
MissingFieldError,
6089
} from "../cache/index.js";
6190

62-
export type * from "../cache/inmemory/types.js";
91+
export type {
92+
ApolloReducerConfig,
93+
DiffQueryAgainstStoreOptions,
94+
IdGetter,
95+
IdGetterObj,
96+
MergeInfo,
97+
MergeTree,
98+
NormalizedCache,
99+
NormalizedCacheObject,
100+
OptimisticStoreItem,
101+
ReadMergeModifyContext,
102+
ReadQueryOptions,
103+
StoreValue,
104+
} from "../cache/inmemory/types.js";
63105

64106
/* Link */
65107

66-
export * from "../link/core/index.js";
67-
export * from "../link/http/index.js";
108+
export {
109+
ApolloLink,
110+
concat,
111+
empty,
112+
execute,
113+
from,
114+
split,
115+
} from "../link/core/index.js";
116+
export type {
117+
ApolloPayloadResult,
118+
DocumentNode,
119+
ExecutionPatchIncrementalResult,
120+
ExecutionPatchInitialResult,
121+
ExecutionPatchResult,
122+
FetchResult,
123+
GraphQLRequest,
124+
IncrementalPayload,
125+
NextLink,
126+
Operation,
127+
Path,
128+
RequestHandler,
129+
SingleExecutionResult,
130+
} from "../link/core/index.js";
131+
132+
export {
133+
checkFetcher,
134+
createHttpLink,
135+
createSignalIfSupported,
136+
defaultPrinter,
137+
fallbackHttpConfig,
138+
HttpLink,
139+
parseAndCheckHttpResponse,
140+
rewriteURIForGET,
141+
selectHttpOptionsAndBody,
142+
// TODO remove: needed by @apollo/client/link/batch-http but not public
143+
selectHttpOptionsAndBodyInternal,
144+
selectURI,
145+
serializeFetchParameter,
146+
} from "../link/http/index.js";
147+
export type {
148+
ClientParseError,
149+
HttpOptions,
150+
UriFunction,
151+
} from "../link/http/index.js";
68152

69153
/* Masking */
70154
export type {

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
// eslint-disable-next-line no-restricted-syntax
12
export * from "@apollo/client/core";
23
export { Observable } from "rxjs";

src/link/batch-http/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from "./batchHttpLink.js";
1+
export { BatchHttpLink } from "./batchHttpLink.js";

src/link/batch/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
export * from "./batchLink.js";
1+
export type { BatchableRequest, BatchHandler } from "./batchLink.js";
2+
export { BatchLink, OperationBatcher } from "./batchLink.js";

0 commit comments

Comments
 (0)