Skip to content

Commit

Permalink
Enforce checkDEV() called by every entry point that uses __DEV__.
Browse files Browse the repository at this point in the history
  • Loading branch information
benjamn committed Aug 23, 2021
1 parent 623fab5 commit 2aee938
Show file tree
Hide file tree
Showing 19 changed files with 108 additions and 27 deletions.
54 changes: 54 additions & 0 deletions config/checkDEV.ts
@@ -0,0 +1,54 @@
import * as path from "path";
import { readFileSync, promises as fs } from "fs";
import { eachFile, distDir } from "./helpers";

const entryPoints = require("./entryPoints.js");

const filesWithDEV = new Set<string>();

eachFile(distDir, async file => {
const source = await fs.readFile(file, "utf8");
if (/\b__DEV__\b/.test(source)) {
filesWithDEV.add(file);
}
}).then(() => {
const filesByEntryPoint = new Map<string, {
indexPath: string;
source: string;
files: Set<string>;
}>();

entryPoints.forEach(({ dirs }: { dirs: string[] }) => {
const relIndexPath = path.join(...dirs, "index.js");
const absIndexPath = path.join(distDir, relIndexPath);
filesByEntryPoint.set(dirs.join("/"), {
indexPath: relIndexPath,
source: readFileSync(absIndexPath, "utf8"),
files: new Set<string>(),
});
});

filesWithDEV.forEach(file => {
const entryPointDir = entryPoints.getEntryPointDirectory(file);
const info = filesByEntryPoint.get(entryPointDir);
const absEntryPointDir = path.join(distDir, entryPointDir);
const relPath = "./" + path.relative(absEntryPointDir, file);
if (info) {
info.files.add(relPath);
}
});

filesByEntryPoint.forEach(({ indexPath, source, files }, entryPointDir) => {
if (!files.size || source.indexOf("checkDEV()") >= 0) {
return;
}
const entryPointId = `@apollo/client/${entryPointDir}`;
throw new Error(`Entry point ${
entryPointId
}/index.js does not call checkDEV(), but ${
entryPointId
} contains the following files that use __DEV__: ${
Array.from(files).join(", ")
}`);
});
});
10 changes: 8 additions & 2 deletions config/entryPoints.js
@@ -1,3 +1,5 @@
const path = require("path").posix;

const entryPoints = [
{ dirs: [], bundleName: "main" },
{ dirs: ['cache'] },
Expand Down Expand Up @@ -47,8 +49,6 @@ exports.map = function map(callback, context) {
return entryPoints.map(callback, context);
};

const path = require("path").posix;

exports.check = function (id, parentId) {
const resolved = path.resolve(path.dirname(parentId), id);
const importedParts = partsAfterDist(resolved);
Expand Down Expand Up @@ -92,6 +92,12 @@ function partsAfterDist(id) {
}
}

exports.getEntryPointDirectory = function (file) {
const parts = partsAfterDist(file) || file.split(path.sep);
const len = lengthOfLongestEntryPoint(parts);
if (len >= 0) return parts.slice(0, len).join(path.sep);
};

function lengthOfLongestEntryPoint(parts) {
let node = lookupTrie;
let longest = -1;
Expand Down
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -31,14 +31,15 @@
"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 resolve && npm run check-DEV && 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",
"check-DEV": "ts-node-script config/checkDEV.ts",
"clean": "rimraf -r dist coverage lib",
"test": "jest --config ./config/jest.config.js",
"test:debug": "BABEL_ENV=server node --inspect-brk node_modules/.bin/jest --config ./config/jest.config.js --runInBand",
Expand Down
5 changes: 2 additions & 3 deletions src/cache/index.ts
@@ -1,6 +1,5 @@
import { invariant } from "ts-invariant";
import { DEV } from "../utilities";
invariant("boolean" === typeof DEV, DEV);
import { checkDEV } from "../utilities";
checkDEV();

export { Transaction, ApolloCache } from './core/cache';
export { Cache } from './core/types/Cache';
Expand Down
3 changes: 2 additions & 1 deletion src/core/index.ts
@@ -1,6 +1,7 @@
/* Core */

import { DEV } from "../utilities";
import { DEV, checkDEV } from "../utilities";
checkDEV();

export {
ApolloClient,
Expand Down
5 changes: 2 additions & 3 deletions src/errors/index.ts
@@ -1,6 +1,5 @@
import { invariant } from "ts-invariant";
import { DEV } from "../utilities";
invariant("boolean" === typeof DEV, DEV);
import { checkDEV } from "../utilities";
checkDEV();

import { GraphQLError } from 'graphql';

Expand Down
5 changes: 2 additions & 3 deletions src/link/core/index.ts
@@ -1,6 +1,5 @@
import { invariant } from "ts-invariant";
import { DEV } from "../../utilities";
invariant("boolean" === typeof DEV, DEV);
import { checkDEV } from "../../utilities";
checkDEV();

export { empty } from './empty';
export { from } from './from';
Expand Down
6 changes: 2 additions & 4 deletions src/link/http/index.ts
@@ -1,7 +1,5 @@
import { invariant } from "ts-invariant";
import { DEV } from "../../utilities";
// Since createHttpLink uses __DEV__, we must be sure to polyfill it.
invariant("boolean" === typeof DEV, DEV);
import { checkDEV } from "../../utilities";
checkDEV();

export {
parseAndCheckHttpResponse,
Expand Down
3 changes: 3 additions & 0 deletions src/link/persisted-queries/index.ts
@@ -1,3 +1,6 @@
import { checkDEV } from "../../utilities";
checkDEV();

import { print } from 'graphql';
import {
DocumentNode,
Expand Down
3 changes: 3 additions & 0 deletions src/link/utils/index.ts
@@ -1,3 +1,6 @@
import { checkDEV } from "../../utilities";
checkDEV();

export { fromError } from './fromError';
export { toPromise } from './toPromise';
export { fromPromise } from './fromPromise';
Expand Down
3 changes: 3 additions & 0 deletions src/react/context/index.ts
@@ -1,3 +1,6 @@
import { checkDEV } from "../../utilities";
checkDEV();

export * from './ApolloConsumer';
export * from './ApolloContext';
export * from './ApolloProvider';
3 changes: 3 additions & 0 deletions src/react/data/index.ts
@@ -1,3 +1,6 @@
import { checkDEV } from "../../utilities";
checkDEV();

export { SubscriptionData } from './SubscriptionData';
export { OperationData } from './OperationData';
export { MutationData } from './MutationData';
Expand Down
3 changes: 3 additions & 0 deletions src/react/hoc/index.ts
@@ -1,3 +1,6 @@
import { checkDEV } from "../../utilities";
checkDEV();

export { graphql } from './graphql';

export { withQuery } from './query-hoc';
Expand Down
3 changes: 3 additions & 0 deletions src/react/hooks/index.ts
@@ -1,3 +1,6 @@
import { checkDEV } from "../../utilities";
checkDEV();

export * from './useApolloClient';
export * from './useLazyQuery';
export * from './useMutation';
Expand Down
5 changes: 2 additions & 3 deletions src/react/index.ts
@@ -1,6 +1,5 @@
import { invariant } from "ts-invariant";
import { DEV } from "../utilities";
invariant("boolean" === typeof DEV, DEV);
import { checkDEV } from "../utilities";
checkDEV();

export {
ApolloProvider,
Expand Down
3 changes: 3 additions & 0 deletions src/react/parser/index.ts
@@ -1,3 +1,6 @@
import { checkDEV } from "../../utilities";
checkDEV();

import {
DocumentNode,
DefinitionNode,
Expand Down
6 changes: 3 additions & 3 deletions src/testing/index.ts
@@ -1,4 +1,4 @@
import { invariant } from "ts-invariant";
import { DEV } from "../utilities";
invariant("boolean" === typeof DEV, DEV);
import { checkDEV } from "../utilities";
checkDEV();

export * from '../utilities/testing';
5 changes: 5 additions & 0 deletions src/utilities/globals/index.ts
@@ -1,7 +1,12 @@
import { invariant } from "ts-invariant";

// Just in case the graphql package switches from process.env.NODE_ENV to
// __DEV__, make sure __DEV__ is polyfilled before importing graphql.
import DEV from "./DEV";
export { DEV }
export function checkDEV() {
invariant("boolean" === typeof DEV, DEV);
}

// Import graphql/jsutils/instanceOf safely, working around its unchecked usage
// of process.env.NODE_ENV and https://github.com/graphql/graphql-js/pull/2894.
Expand Down
7 changes: 3 additions & 4 deletions src/utilities/index.ts
@@ -1,7 +1,6 @@
import { invariant } from "ts-invariant";
import { DEV } from "./globals";
invariant("boolean" === typeof DEV, DEV);
export { DEV }
import { DEV, checkDEV } from "./globals";
export { DEV, checkDEV }
checkDEV();

export {
DirectiveInfo,
Expand Down

0 comments on commit 2aee938

Please sign in to comment.