Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[core-http] Rework use of "lib": ["dom"] in core-http #7500

Merged
merged 6 commits into from
Feb 24, 2020

Conversation

willmtemple
Copy link
Contributor

This PR is an attempt to fix some long-standing weirdness in the repo related to the use of "lib": ["dom", ..].

Related issues:

How it works

core-http needs a full set of DOM definitions, otherwise we would have to shim everything we use in types like XmlHttpRequest and others. Including /// <reference lib="dom" /> in the new lib/dom.d.ts file causes the full set of DOM types to be ambiently declared for the compilation of core-http, but this file will not be emitted to the output directory during compilation. If we had simply added the reference to coreHttp.ts, then any consumer would also receive these definitions. By using the lib/dom.d.ts file and referencing the full DOM types there, we avoid re-exporting all of DOM to our customers.

In addition to this full declaration file, a new shim file dom-shim.d.ts in the package root provides shims for the commonly-used interfaces (Request, RequestInit, Response, and Headers --- cc @daviwil , is there anything else to add to these default shims?). lib/coreHttp.ts references these shims directly using /// <reference path="../dom-shim.d.ts" />. Typescript rewrites this reference path so that it is still valid from the emitted coreHttp.d.ts declaration file, and so all core-http consumers will receive this set of shims for free and will not have to re-shim.

However, only interfaces can be shimmed, so this creates a constraint on core-http, which is that we cannot export anything using a type that cannot be shimmed (see: RequestInfo). Fortunately, it isn't too difficult to just remove that type from our signatures.

What all of this means is that if a package does not, itself, need DOM types internally, it won't be forced to shim or import DOM just because it uses core-http. Shimming/using the full DOM types is now only required if the package actually needs to have browser-specific behavior.

Other packages that need to use DOM can follow this same pattern of having ambient declarations of the full DOM types while referencing only required shims in the emitted declarations.

This is not a breaking change. Dependents that previously opted for either the shims-based or lib:dom-based workarounds will continue to function as they did previously with no change required.

Changes:

  • Added core-http/lib/dom.d.ts with reference to full dom types
  • Added core-http/dom-shim.d.ts with shims for commonly-used interfaces and refereced from coreHttp.ts
  • Added dom-shim.d.ts to package files so that it will be included with package file
  • Removed uses of RequestInfo from fetch-based http clients (RequestInfo is a type -- not an interface, so it cannot be shimmed) and replaced them with a type CommonRequestInfo that captures the common subset of inputs that are valid for both node-fetch and browser-based global fetch
  • Removed shims.d.ts from template and ai-text-analytics (keyvault and storage actually have browser-specific code, so they should be handled separately --- appconfig has no lib entry cc: @richardpark-msft )

Copy link
Contributor

@daviwil daviwil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! Super simple and gets rid of a pain point folks have had after core-http moved to fetch.

@@ -81,7 +82,7 @@
"test": "npm run build:test && npm run unit-test && npm run integration-test",
"unit-test": "npm run unit-test:node && npm run unit-test:browser",
"unit-test:browser": "node ./node_modules/karma/bin/karma start karma.conf.ts --browsers ChromeNoSecurity --single-run",
"unit-test:node": "nyc mocha",
"unit-test:node": "cross-env TS_NODE_FILES=true nyc mocha",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, what does TS_NODE_FILES do?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@daviwil I had no idea until a few minutes ago. It affects the way ts-node reads tsconfig.json. It causes it to load the includes, excludes, and files (it apparently does not do so by default). I'm not 100% sure why it has this effect, but in this case it is required for ts-node to read the dom.d.ts file. Previously the unit-tests were getting DOM types from lib:dom, since compilerOptions is loaded by default.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I googled the same problem and came to the same conclusion some months ago, fwiw

Copy link
Member

@bterlson bterlson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1000, good stuff here. Also really appreciate the in-depth description.

Copy link
Member

@xirzec xirzec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A royally good PR, so here is your crown: 👑

import { HttpOperationResponse } from "./httpOperationResponse";
import { WebResource } from "./webResource";
import { createProxyAgent, ProxyAgent, isUrlHttps } from "./proxyAgent";

interface GlobalWithFetch extends NodeJS.Global {
fetch: (input: RequestInfo, init?: RequestInit) => Promise<Response>;
fetch: typeof import("node-fetch")["default"];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

huh, this is interesting, I don't think I've seen this style of typing off of imports before

@willmtemple willmtemple merged commit 9423b9b into Azure:master Feb 24, 2020
jeremymeng added a commit to jeremymeng/ms-rest-js that referenced this pull request Feb 3, 2021
Porting changes from @azure/core-http PR
Azure/azure-sdk-for-js#7500.

- Keep lib: ["dom"] for ./scripts/ as it depends on a dev common tool which
depends on v10 @azure/storage-blob which depends on an older version of
ms-rest-js. Attempting to remove it resulting in compile errors. This folder is
only used in dev/CI.  It's not part of the shipping library.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants