From 05b7a85dd509e1a1e7b870c15d46d73a8fa145fb Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Wed, 9 Feb 2022 12:21:07 -0500 Subject: [PATCH 1/3] Avoid `__DEV__` declaration conflict with React Native (#9386) This commit back-ports PR #9386 from the release-3.6 branch, since the same changes make sense on main. --- config/distSpotFixes.ts | 25 +++++++++++++++++++ ...resolveModuleIds.ts => postprocessDist.ts} | 3 +++ package.json | 4 +-- src/utilities/globals/global.ts | 16 ++++++++++++ 4 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 config/distSpotFixes.ts rename config/{resolveModuleIds.ts => postprocessDist.ts} (98%) diff --git a/config/distSpotFixes.ts b/config/distSpotFixes.ts new file mode 100644 index 00000000000..564d0bc0893 --- /dev/null +++ b/config/distSpotFixes.ts @@ -0,0 +1,25 @@ +import * as fs from "fs"; +import { EOL } from "os"; +import { distDir } from './helpers'; + +export function applyDistSpotFixes() { + sanitizeDEV(); +} + +function sanitizeDEV() { + const globalDTsPath = `${distDir}/utilities/globals/global.d.ts`; + const globalDTs = fs.readFileSync(globalDTsPath, "utf8"); + // The global.d.ts types are useful within the @apollo/client codebase to + // provide a type for the global __DEV__ constant, but actually shipping that + // declaration as a globally-declared type runs too much risk of conflict with + // other __DEV__ declarations attempting to do achieve the same thing, most + // notably the one in @types/react-native/index.d.ts. We preserve the default + // export so that index.d.ts doesn't need to change, but otherwise we remove + // all traces of __DEV__ from global.d.ts. + if (/__DEV__/.test(globalDTs)) { + fs.writeFileSync(globalDTsPath, [ + "declare const _default: typeof globalThis;", + "export default _default;", + ].join(EOL)); + } +} diff --git a/config/resolveModuleIds.ts b/config/postprocessDist.ts similarity index 98% rename from config/resolveModuleIds.ts rename to config/postprocessDist.ts index f8798c654d1..cddb75ff7e2 100644 --- a/config/resolveModuleIds.ts +++ b/config/postprocessDist.ts @@ -3,6 +3,9 @@ import * as path from "path"; import resolve from "resolve"; import { distDir, eachFile, reparse, reprint } from './helpers'; +import { applyDistSpotFixes } from "./distSpotFixes"; +applyDistSpotFixes(); + // The primary goal of the 'npm run resolve' script is to make ECMAScript // modules exposed by Apollo Client easier to consume natively in web browsers, // without bundling, and without help from package.json files. It accomplishes diff --git a/package.json b/package.json index 6d53c4902a6..bc07bc2c653 100644 --- a/package.json +++ b/package.json @@ -31,14 +31,14 @@ "scripts": { "prebuild": "npm run clean", "build": "tsc", - "postbuild": "npm run update-version && npm run invariants && npm run sourcemaps && npm run rollup && npm run prepdist && npm run resolve && npm run verify-version", + "postbuild": "npm run update-version && npm run invariants && npm run sourcemaps && npm run rollup && npm run prepdist && npm run postprocess-dist && npm run verify-version", "update-version": "node config/version.js update", "verify-version": "node config/version.js verify", "invariants": "ts-node-script config/processInvariants.ts", "sourcemaps": "ts-node-script config/rewriteSourceMaps.ts", "rollup": "rollup -c ./config/rollup.config.js", "prepdist": "node ./config/prepareDist.js", - "resolve": "ts-node-script config/resolveModuleIds.ts", + "postprocess-dist": "ts-node-script config/postprocessDist.ts", "clean": "rimraf -r dist coverage lib temp", "ci:precheck": "node config/precheck.js", "test": "jest --config ./config/jest.config.js", diff --git a/src/utilities/globals/global.ts b/src/utilities/globals/global.ts index c776fdda335..375689eb62c 100644 --- a/src/utilities/globals/global.ts +++ b/src/utilities/globals/global.ts @@ -1,6 +1,22 @@ import { maybe } from "./maybe"; declare global { + // Despite our attempts to reuse the React Native __DEV__ constant instead of + // inventing something new and Apollo-specific, declaring a useful type for + // __DEV__ unfortunately conflicts (TS2451) with the global declaration in + // @types/react-native/index.d.ts. + // + // To hide that harmless conflict, we @ts-ignore this line, which should + // continue to provide a type for __DEV__ elsewhere in the Apollo Client + // codebase, even when @types/react-native is not in use. + // + // However, because TypeScript drops @ts-ignore comments when generating .d.ts + // files (https://github.com/microsoft/TypeScript/issues/38628), we also + // sanitize the dist/utilities/globals/global.d.ts file to avoid declaring + // __DEV__ globally altogether when @apollo/client is installed in the + // node_modules directory of an application. + // + // @ts-ignore const __DEV__: boolean | undefined; } From dcea68d7a44d32ac3afd0c5ea674fe682a3cf04a Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Tue, 15 Feb 2022 09:59:34 -0500 Subject: [PATCH 2/3] Mention PR #9386 in CHANGELOG.md. --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27027cbfb3c..09cdf2104cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ - Interpret `keyFields: [...]` and `keyArgs: [...]` configurations in `InMemoryCache` type/field policies as `ReadonlyArray`s, since they are never mutated internally.
[@julienfouilhe](https://github.com/julienfouilhe) in [#9339](https://github.com/apollographql/apollo-client/pull/9339) +- Avoid declaring a global type for the `__DEV__` constant, to avoid conflict with other such global declarations.
+ [@benjamn](https://github.com/benjamn) in [#9386](https://github.com/apollographql/apollo-client/pull/9386) + ### Bug Fixes - Fix `useSubscription` executing `skip`ped subscription when input changes.
From ac6aa4c06699c77fae381d34d3017fa2ddbc3b1d Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Tue, 15 Feb 2022 10:08:23 -0500 Subject: [PATCH 3/3] Improve comment wording. --- config/distSpotFixes.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/distSpotFixes.ts b/config/distSpotFixes.ts index 564d0bc0893..41b8afebd79 100644 --- a/config/distSpotFixes.ts +++ b/config/distSpotFixes.ts @@ -12,10 +12,10 @@ function sanitizeDEV() { // The global.d.ts types are useful within the @apollo/client codebase to // provide a type for the global __DEV__ constant, but actually shipping that // declaration as a globally-declared type runs too much risk of conflict with - // other __DEV__ declarations attempting to do achieve the same thing, most + // other __DEV__ declarations attempting to achieve the same thing, most // notably the one in @types/react-native/index.d.ts. We preserve the default - // export so that index.d.ts doesn't need to change, but otherwise we remove - // all traces of __DEV__ from global.d.ts. + // export so that index.d.ts can remain unchanged, but otherwise we remove all + // traces of __DEV__ from global.d.ts. if (/__DEV__/.test(globalDTs)) { fs.writeFileSync(globalDTsPath, [ "declare const _default: typeof globalThis;",