diff --git a/packages/ts-invariant/process/main.js b/packages/ts-invariant/process/main.js new file mode 100644 index 0000000..c04e66c --- /dev/null +++ b/packages/ts-invariant/process/main.js @@ -0,0 +1,45 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +function maybe(thunk) { + try { return thunk() } catch (_) {} +} + +let needToRemove = false; + +function install() { + if (!maybe(() => process.env.NODE_ENV) && + !maybe(() => process)) { + Object.defineProperty(global, "process", { + value: { + env: { + // This default needs to be "production" instead of "development", to + // avoid the problem https://github.com/graphql/graphql-js/pull/2894 + // will eventually solve, once merged and released. + NODE_ENV: "production", + }, + }, + // Let anyone else change global.process as they see fit, but hide it from + // Object.keys(global) enumeration. + configurable: true, + enumerable: false, + writable: true, + }); + needToRemove = true; + } +} + +// Call install() at least once, when this module is imported. +install(); + +function remove() { + if (needToRemove) { + delete global.process; + needToRemove = false; + } +} + +exports.install = install; +exports.remove = remove; +//# sourceMappingURL=main.js.map diff --git a/packages/ts-invariant/process/main.js.map b/packages/ts-invariant/process/main.js.map new file mode 100644 index 0000000..8abb117 --- /dev/null +++ b/packages/ts-invariant/process/main.js.map @@ -0,0 +1 @@ +{"version":3,"file":"main.js","sources":["module.js"],"sourcesContent":["function maybe(thunk) {\n try { return thunk() } catch (_) {}\n}\n\nlet needToRemove = false;\n\nexport function install() {\n if (!maybe(() => process.env.NODE_ENV) &&\n !maybe(() => process)) {\n Object.defineProperty(global, \"process\", {\n value: {\n env: {\n // This default needs to be \"production\" instead of \"development\", to\n // avoid the problem https://github.com/graphql/graphql-js/pull/2894\n // will eventually solve, once merged and released.\n NODE_ENV: \"production\",\n },\n },\n // Let anyone else change global.process as they see fit, but hide it from\n // Object.keys(global) enumeration.\n configurable: true,\n enumerable: false,\n writable: true,\n });\n needToRemove = true;\n }\n}\n\n// Call install() at least once, when this module is imported.\ninstall();\n\nexport function remove() {\n if (needToRemove) {\n delete global.process;\n needToRemove = false;\n }\n}\n"],"names":[],"mappings":";;;;AAAA,SAAS,KAAK,CAAC,KAAK,EAAE;AACtB,EAAE,IAAI,EAAE,OAAO,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE;AACrC,CAAC;AACD;AACA,IAAI,YAAY,GAAG,KAAK,CAAC;AACzB;AACO,SAAS,OAAO,GAAG;AAC1B,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;AACxC,MAAM,CAAC,KAAK,CAAC,MAAM,OAAO,CAAC,EAAE;AAC7B,IAAI,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE;AAC7C,MAAM,KAAK,EAAE;AACb,QAAQ,GAAG,EAAE;AACb;AACA;AACA;AACA,UAAU,QAAQ,EAAE,YAAY;AAChC,SAAS;AACT,OAAO;AACP;AACA;AACA,MAAM,YAAY,EAAE,IAAI;AACxB,MAAM,UAAU,EAAE,KAAK;AACvB,MAAM,QAAQ,EAAE,IAAI;AACpB,KAAK,CAAC,CAAC;AACP,IAAI,YAAY,GAAG,IAAI,CAAC;AACxB,GAAG;AACH,CAAC;AACD;AACA;AACA,OAAO,EAAE,CAAC;AACV;AACO,SAAS,MAAM,GAAG;AACzB,EAAE,IAAI,YAAY,EAAE;AACpB,IAAI,OAAO,MAAM,CAAC,OAAO,CAAC;AAC1B,IAAI,YAAY,GAAG,KAAK,CAAC;AACzB,GAAG;AACH;;;;;"} \ No newline at end of file diff --git a/packages/ts-invariant/process/module.d.ts b/packages/ts-invariant/process/module.d.ts new file mode 100644 index 0000000..7693d8f --- /dev/null +++ b/packages/ts-invariant/process/module.d.ts @@ -0,0 +1,2 @@ +export declare function install(): void; +export declare function remove(): void; diff --git a/packages/ts-invariant/process/module.js b/packages/ts-invariant/process/module.js new file mode 100644 index 0000000..4f7c2c0 --- /dev/null +++ b/packages/ts-invariant/process/module.js @@ -0,0 +1,37 @@ +function maybe(thunk) { + try { return thunk() } catch (_) {} +} + +let needToRemove = false; + +export function install() { + if (!maybe(() => process.env.NODE_ENV) && + !maybe(() => process)) { + Object.defineProperty(global, "process", { + value: { + env: { + // This default needs to be "production" instead of "development", to + // avoid the problem https://github.com/graphql/graphql-js/pull/2894 + // will eventually solve, once merged and released. + NODE_ENV: "production", + }, + }, + // Let anyone else change global.process as they see fit, but hide it from + // Object.keys(global) enumeration. + configurable: true, + enumerable: false, + writable: true, + }); + needToRemove = true; + } +} + +// Call install() at least once, when this module is imported. +install(); + +export function remove() { + if (needToRemove) { + delete global.process; + needToRemove = false; + } +} diff --git a/packages/ts-invariant/process/package.json b/packages/ts-invariant/process/package.json new file mode 100644 index 0000000..0d53ca5 --- /dev/null +++ b/packages/ts-invariant/process/package.json @@ -0,0 +1,10 @@ +{ + "name": "ts-invariant/process", + "main": "./main.js", + "module": "./module.js", + "types": "./module.d.ts", + "sideEffects": [ + "./module.js", + "./index.js" + ] +} diff --git a/packages/ts-invariant/rollup.config.js b/packages/ts-invariant/rollup.config.js index 615a256..5b3fd2d 100644 --- a/packages/ts-invariant/rollup.config.js +++ b/packages/ts-invariant/rollup.config.js @@ -11,7 +11,10 @@ function external(id) { return id in globals; } -export default [{ +const jobs = []; +export default jobs; + +jobs.push({ input: "src/invariant.ts", external, output: { @@ -26,7 +29,9 @@ export default [{ tsconfig: "./tsconfig.rollup.json", }), ], -}, { +}); + +jobs.push({ input: "lib/invariant.esm.js", external, output: { @@ -38,4 +43,17 @@ export default [{ name: "ts-invariant", globals, }, -}]; +}); + +jobs.push({ + input: "process/module.js", + external, + output: { + file: "process/main.js", + format: "cjs", + exports: "named", + sourcemap: true, + name: "ts-invariant/process", + globals, + }, +}); diff --git a/packages/ts-invariant/src/invariant.ts b/packages/ts-invariant/src/invariant.ts index b780332..2bd6502 100644 --- a/packages/ts-invariant/src/invariant.ts +++ b/packages/ts-invariant/src/invariant.ts @@ -53,20 +53,4 @@ export function setVerbosity(level: VerbosityLevel): VerbosityLevel { return old; } -// Code that uses ts-invariant with rollup-plugin-invariant may want to -// import this process stub to avoid errors evaluating process.env.NODE_ENV. -// However, because most ESM-to-CJS compilers will rewrite the process import -// as tsInvariant.process, which prevents proper replacement by minifiers, we -// also export processStub, so you can import { invariant, processStub } from -// "ts-invariant" and assign processStub to a local variable named process. -export const processStub: { - env: Record; - [key: string]: any; -} = ( - typeof process === "object" && - typeof process.env === "object" -) ? process : { env: {} }; - -export { processStub as process }; - export default invariant; diff --git a/packages/ts-invariant/src/tests.ts b/packages/ts-invariant/src/tests.ts index 13e4c8e..62cc6aa 100644 --- a/packages/ts-invariant/src/tests.ts +++ b/packages/ts-invariant/src/tests.ts @@ -3,11 +3,11 @@ import defaultExport, { invariant, InvariantError, setVerbosity, - process, - processStub, } from "./invariant"; import reactInvariant from "invariant"; +import { install, remove } from "../process"; + describe("ts-invariant", function () { it("should support both named and default exports", function () { assert.strictEqual(defaultExport, invariant); @@ -145,23 +145,6 @@ describe("ts-invariant", function () { checkConsoleMethod("error", true); }); - it("should export a usable process polyfill", function () { - assert.strictEqual(typeof process, "object"); - assert.strictEqual(typeof process.env, "object"); - if (process.versions) { - assert.strictEqual(typeof process.versions.node, "string"); - } - }); - - it("should export a usable processStub", function () { - const process = processStub; - assert.strictEqual(typeof process, "object"); - assert.strictEqual(typeof process.env, "object"); - if (process.versions) { - assert.strictEqual(typeof process.versions.node, "string"); - } - }); - it("should let TypeScript know about the assertion made", function () { const value: { foo?: { bar?: string } } = {foo: {bar: "bar"}}; invariant(value.foo, 'fail'); @@ -169,4 +152,26 @@ describe("ts-invariant", function () { // On compile time this should not raise "TS2532: Object is possibly 'undefined'." assert.strictEqual(value.foo.bar, "bar"); }); + + describe("ts-invariant/process", function () { + it("install and remove", function () { + const origDesc = Object.getOwnPropertyDescriptor(global, "process"); + Object.defineProperty(global, "process", { + value: void 0, + configurable: true, + }); + assert.strictEqual(process, void 0); + install(); + assert.deepStrictEqual(process, { + env: { + NODE_ENV: "production", + }, + }); + remove(); + assert.strictEqual(typeof process, "undefined"); + if (origDesc) { + Object.defineProperty(global, "process", origDesc); + } + }); + }); }); diff --git a/tsconfig.json b/tsconfig.json index eebabad..0049493 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,7 @@ "importHelpers": true, "declaration": true, "sourceMap": true, - "lib": ["es2015"], + "lib": ["es2015", "DOM"], "types": ["node", "mocha"], "strict": true, "noImplicitAny": true,