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-rest-pipeline] Add conditional exports #22804

Merged
merged 19 commits into from
Oct 20, 2022

Conversation

jeremymeng
Copy link
Member

@jeremymeng jeremymeng commented Aug 4, 2022

  • 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

- when bundle, output to index.cjs
- add conditional export for "require" and "import"
- rename karma.conf.js to karma.conf.cjs

- update npm scripts
@ghost ghost added Azure.Core dev-tool Issues related to the Azure SDK for JS dev-tool labels Aug 4, 2022
@check-enforcer
Copy link

check-enforcer bot commented Aug 4, 2022

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:
/check-enforcer evaluate
Typically evaulation only takes a few seconds. If you know that your pull request is not covered by a pipeline and this is expected you can override Check Enforcer using the following command:
/check-enforcer override
Note that using the override command triggers alerts so that follow-up investigations can occur (PRs still need to be approved as normal).

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:
/azp run prepare-pipelines
This will run a pipeline that analyzes the source tree and creates the pipelines necessary to build and validate your pull request. Once the pipeline has been created you can trigger the pipeline using the following comment:
/azp run js - [service] - ci

@azure-sdk
Copy link
Collaborator

API change check

API changes are not detected in this pull request.

@xirzec xirzec changed the title [core-rest-pipeline] [core-rest-pipeline] Add subpath exports Aug 4, 2022
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.

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" });
Copy link
Member

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?

Copy link
Member Author

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";
Copy link
Member

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?

Copy link
Member Author

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",
Copy link
Member

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

Suggested change
"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 ?

Copy link
Member Author

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.

Copy link
Member Author

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?

Copy link
Member

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.

Copy link
Member

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

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"
    }
  }
}

Copy link
Member

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. 👍

Copy link
Member Author

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?

Copy link
Member Author

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.

Copy link
Member Author

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.

@jeremymeng jeremymeng changed the title [core-rest-pipeline] Add subpath exports [core-rest-pipeline] Add conditional exports Aug 4, 2022
Copy link
Member

@witemple-msft witemple-msft left a 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"}`,
Copy link
Member

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?

Suggested change
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.

Copy link
Member Author

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.

Copy link
Member

@witemple-msft witemple-msft left a comment

Choose a reason for hiding this comment

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

Nice! LGTM.

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.

Thanks for tackling this!

@jeremymeng jeremymeng merged commit 02f6ad6 into Azure:main Oct 20, 2022
@jeremymeng jeremymeng deleted the core/cond-export branch October 20, 2022 17:45
mpodwysocki pushed a commit that referenced this pull request Nov 2, 2022
- 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
jeremymeng added a commit to jeremymeng/azure-sdk-for-js that referenced this pull request Nov 3, 2022
jeremymeng added a commit that referenced this pull request Nov 3, 2022
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.
mpodwysocki pushed a commit that referenced this pull request Nov 3, 2022
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Azure.Core dev-tool Issues related to the Azure SDK for JS dev-tool
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants