-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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-rest-pipeline] Add conditional exports #22804
Conversation
- when bundle, output to index.cjs - add conditional export for "require" and "import"
- rename karma.conf.js to karma.conf.cjs - update npm scripts
This pull request is protected by Check Enforcer. What is Check Enforcer?Check Enforcer helps ensure all pull requests are covered by at least one check-run (typically an Azure Pipeline). When all check-runs associated with this pull request pass then Check Enforcer itself will pass. Why am I getting this message?You are getting this message because Check Enforcer did not detect any check-runs being associated with this pull request within five minutes. This may indicate that your pull request is not covered by any pipelines and so Check Enforcer is correctly blocking the pull request being merged. What should I do now?If the check-enforcer check-run is not passing and all other check-runs associated with this PR are passing (excluding license-cla) then you could try telling Check Enforcer to evaluate your pull request again. You can do this by adding a comment to this pull request as follows: What if I am onboarding a new service?Often, new services do not have validation pipelines associated with them, in order to bootstrap pipelines for a new service, you can issue the following command as a pull request comment: |
API change check API changes are not detected in this pull request. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very exciting stuff! I am eager to get this landed.
A couple minor comments/questions.
@@ -71,7 +71,7 @@ describe("NodeHttpClient", function () { | |||
const client = createDefaultHttpClient(); | |||
const clientRequest = createRequest(); | |||
stubbedHttpsRequest.returns(clientRequest); | |||
const request = createPipelineRequest({ url: "https://example.com" }); | |||
const request = createPipelineRequest({ url: "https://whateverhahaha.com" }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lol is example.com
banned or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
haha, will revert. I was debugging some issue and the request went to the wire and gave me 200, so I changed temporarily but forgot to restore.
@@ -1,19 +1,20 @@ | |||
// Copyright (c) Microsoft Corporation. | |||
// Licensed under the MIT license. | |||
|
|||
import * as http from "https"; | |||
import * as https from "https"; | |||
import http from "https"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the * as foo
syntax just not required anymore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure about the root cause yet, but sinon
cannot mock import * as
and gave this error: "ES Modules cannot be stubbed". I had to change the import in the src files as well, otherwise, sinon is not able to modify http.request.
"type": "module", | ||
"export": { | ||
".": { | ||
"types": "./types/src/index.js", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wouldn't this still be something like
"types": "./types/src/index.js", | |
"types": "./types/latest/src/index.d.ts", |
Though really shouldn't this match the main types entry so core-rest-pipeline.shims.d.ts
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copied from Matt's PR. Will fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mpodwysocki the "types" export in notification hub package.json seem incorrect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They resolve just fine in TypeScript as is. I got the advice from @DanielRosenwasser and it works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mpodwysocki does TS not need this to resolve to a d.ts then? I guess I'm confused how the resolution works, lmk if you can point me at some docs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can actually nest conditions arbitrarily deep, and use arrays of fallbacks, rather than just simple strings! They're quite complicated! Anyways, it would look something like
"exports": {
".": {
"import": {
"types": "./types/index.d.ts",
"default": "./dist/index.js"
},
"require": {
"types": "./types/index.d.cts",
"default": "./dist/index.cjs"
}
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIL! 😮
Thanks for taking the time to explain, hopefully once we find the right config we can tool it such that humans don't have to think too hard about this stuff. 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be two .d.ts files. One for the esm module, one for the cjs module. The esm module can (and probably should) just re-export stuff from the cjs one if it helps.
@weswigham thanks for the detail information! For our packages we used a rollup d.ts for the default types
field. From my testing it worked when both require
and import
use the same d.ts file. Is it necessary to have two separate files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay, from the linked discussion microsoft/TypeScript#50466 we would need two separate files so that the correct mode is applied.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated this PR to have two copies of the same shim type file, d.ts
for import, and d.cts
for require. I tested the package on two projects, an ESM one with "type": "module", and a CJS one without "type": "module". Result of VS Code IntelliSense/Go to Definition work the same as before so I assume this should be good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a tiny change to request for dev-tool but I think it's important.
@@ -72,7 +77,7 @@ export default leafCommand(commandInfo, async (options) => { | |||
const bundle = await rollup.rollup(baseConfig); | |||
|
|||
await bundle.write({ | |||
file: "dist/index.js", | |||
file: `dist/index.${options["output-cjs-ext"] ? "cjs" : "js"}`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of using an option, could we just read the main path from package.json?
file: `dist/index.${options["output-cjs-ext"] ? "cjs" : "js"}`, | |
file: info.packageJson.main |
It may be best to defensively check that this field is set and starts with dist
just to make sure we don't blow up someone's machine from a nasty config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great point! I changed to use the main path. We already have the linter to ensure the main path so I just did a minimal check for non-falsy values.
and use the `main` entry value in package.json instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! LGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for tackling this!
- Add conditional exports for core-rest-pipeline - Add .js extension to imported source module name - Bump dev dependency Mocha version to v10 - Add `ts-node/esm` loader in mocha config - Update npm scripts - Update linter rule to allow dist/index.cjs - Add a copy of our typing files for cjs - Bump minor version ### Packages impacted by this PR `@azure/core-rest-pipeline` ### Issues associated with this PR #22172
This reverts commit 02f6ad6.
This reverts commit 02f6ad6. ### Packages impacted by this PR `@azure/core-rest-pipeline` ### Describe the problem that is addressed by this PR Making core-rest-pipeline ESM with conditional exports broke notification-hubs. Reverting the change while investigating.
This reverts commit 02f6ad6. ### Packages impacted by this PR `@azure/core-rest-pipeline` ### Describe the problem that is addressed by this PR Making core-rest-pipeline ESM with conditional exports broke notification-hubs. Reverting the change while investigating.
ts-node/esm
loader in mocha configPackages impacted by this PR
@azure/core-rest-pipeline
Issues associated with this PR
#22172