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

build(client-tree): exports with ESM as primary #19141

Merged
merged 22 commits into from
Feb 10, 2024

Conversation

jason-ha
Copy link
Contributor

@jason-ha jason-ha commented Jan 8, 2024

  • Configure full ESM build and declaration for tree
  • Set exports (only "public" and internal as there are no others)
    • "@internal" uses of tree updated to import "/internal"
  • Build CommonJS secondarily with injected CommonJS package.json at build

A module package.json is also injected into ESM build for symmetry.

ESM api-extractor tsconfig is overwritten to use Bundler resolution as Node16 does not appear to be robustly handled.

@github-actions github-actions bot added area: build Build related issues area: dds Issues related to distributed data structures area: dds: tree base: main PRs targeted against main branch labels Jan 8, 2024
@msfluid-bot
Copy link
Collaborator

msfluid-bot commented Jan 8, 2024

Baseline CI build failed, cannot generate bundle analysis at this time


Baseline commit: 4c94050

Generated by 🚫 dangerJS against ccd598b

@github-actions github-actions bot added the public api change Changes to a public API label Jan 8, 2024
make sure cjs rollup uses cjs config
override moduleResolution for esm as api-extractor doesn't handle node16 robustly. It will generate with imports to invalid paths.
use Bundler for moduleResolution with ESNext
@jason-ha jason-ha marked this pull request as ready for review January 8, 2024 21:19
@jason-ha jason-ha requested review from msfluid-bot and a team as code owners January 8, 2024 21:19
common/build/build-common/tsc-multi.cjs.json Outdated Show resolved Hide resolved
packages/dds/tree/package.json Show resolved Hide resolved
packages/dds/tree/tsconfig.base.json Show resolved Hide resolved
@github-actions github-actions bot removed the area: build Build related issues label Jan 8, 2024
@jason-ha jason-ha requested a review from alexvy86 January 8, 2024 22:02
@github-actions github-actions bot added area: build Build related issues dependencies Pull requests that update a dependency file labels Jan 16, 2024
echo quote emit syntax is different per shell.
Instead copy a file.
Add comments for module/moduleResolution settings
and make moduleResolution explicit.
Also inject package.json for ESM for symmetry.
@jason-ha jason-ha force-pushed the tree-exports-with-esm-as-primary branch from 6870b1a to 0bcd137 Compare January 17, 2024 00:54
@tylerbutler
Copy link
Member

I dug up the comment that describes some drawbacks to this approach:

microsoft/TypeScript#54593 (comment)

I don't think this is an immediate blocker for us, but it makes me think this is a design that we'll still have to revisit later. Maybe just something we note in the readme or dev notes and revisit when it becomes a practical blocker.

@jason-ha
Copy link
Contributor Author

I dug up the comment that describes some drawbacks to this approach:

microsoft/TypeScript#54593 (comment)

I don't think this is an immediate blocker for us, but it makes me think this is a design that we'll still have to revisit later. Maybe just something we note in the readme or dev notes and revisit when it becomes a practical blocker.

I was emitting lib/package.json for complete symmetry and we can do that or not. I think nice to have for now to help catch any issues from this structure. We don't use "imports" feature and I don't see the need to; so, we can add a policy to block. As noted in the referenced thread it is possible to enhance those injected package.json file with other information if needed.

I am hoping that we are really working toward an ESM only future and would then be able to drop secondary CJS build. If we can't before there is issue with lib/package.json then we will have option to drop it with current configuration.

Those seem more tractable than using tools that we can't rely on as much as tsc.

Last weekend I was playing around with addition to tsc-multi to hook package.json reads and override type. Using it for just that feature seems safe to me. (No extension or file rewrites.)

Comment on lines +4 to +9
"compiler": {
"tsconfigFilePath": "<projectFolder>/tsconfig.cjs.json"
},
"apiReport": {
"enabled": false
}
Copy link
Member

Choose a reason for hiding this comment

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

Should these be defined in the base config? If not, add some comments to this file with some explanation.

Copy link
Contributor 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 what the question is.

  • Should tsconfigFilePath be set in build-common/api-extractor-base.cjs*.json? No each package may have its own tsconfig setup at the moment.
  • Should apiReport be disabled in build-common/api-extractor-base.json? I think it should probably be off in there. The -base.*.primary.json files however would want it on. This config wants the extension neutral (.ts) settings from .primary.json but not the apiReport.

Comment on lines +4 to +13
"compiler": {
"overrideTsconfig": {
"$schema": "http://json.schemastore.org/tsconfig",
"extends": "./tsconfig.esnext.json",
"compilerOptions": {
"module": "esnext",
"moduleResolution": "Bundler"
}
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Same question here.

@@ -1,4 +1,15 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
"extends": "../../../common/build/build-common/api-extractor-base.json"
"extends": "../../../common/build/build-common/api-extractor-base.json",
Copy link
Member

Choose a reason for hiding this comment

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

Why does this extend from api-extractor-base while the others use different bases?

Copy link
Member

Choose a reason for hiding this comment

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

Is this needed? Seems like the package.json scripts explicitly pass a config file.

Copy link
Contributor Author

@jason-ha jason-ha Feb 3, 2024

Choose a reason for hiding this comment

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

  • Everything eventually extends from api-extractor-base. The other build-common files extend api-extractor-base, set entry point, set rollup files, and if not primary disable apiReport.
  • build:docs and ci:build:docs use this file implicitly.

packages/dds/tree/package.json Show resolved Hide resolved
packages/dds/tree/package.json Show resolved Hide resolved
@@ -11,18 +11,42 @@
"license": "MIT",
"author": "Microsoft and contributors",
"sideEffects": false,
"type": "module",
Copy link
Member

Choose a reason for hiding this comment

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

Isn't this a bit dangerous?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't know that this is dangerous. Why might it be dangerous?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(I haven't requested the tsc-multi feature that I think it needs. Without tsc seeing "type": "module" it doesn't go into full ESM mode. This is a must for now to ensure proper ESM transpilation.)

@@ -46,7 +70,7 @@
"test:snapshots:regen": "npm run test:mocha -- --snapshot",
"test:stress": "cross-env FUZZ_TEST_COUNT=20 FUZZ_STRESS_RUN=true mocha --ignore \"dist/test/memory/**/*\" --recursive \"dist/test/**/*.spec.js\" -r @fluidframework/mocha-test-setup",
"ts2esm": "ts2esm ./tsconfig.json ./src/test/tsconfig.json",
"tsc": "tsc",
"tsc": "tsc --project ./tsconfig.cjs.json && copyfiles -f ../../../common/build/build-common/src/cjs/package.json ./dist",
Copy link
Member

Choose a reason for hiding this comment

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

I think this is fine for now since fluid-build understands tsc and copyfiles and should decompose this into two dependent tasks (one for tsc and the other for copyfiles). However, longer-term I think the pattern we should use is to have explicit separate tasks for the copying and make those dependencies explicit in the fluid-build config as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did enjoy fluid-build being smart about this. I am not sure the long-term desired breakup. I guess tsc would kick off the two tasks b/c we want to keep the main build command simple and common. So, we have tsc that does tsc:transpile and tsc:setcjs later?

packages/dds/tree/tsconfig.cjs.json Show resolved Hide resolved
@jason-ha jason-ha requested a review from a team as a code owner February 7, 2024 19:37
@jason-ha
Copy link
Contributor Author

jason-ha commented Feb 9, 2024

Ah timing. Looks like some non-public use of tree snuck in. exports will need adjusted (if not removed).

Copy link
Contributor

@alexvy86 alexvy86 left a comment

Choose a reason for hiding this comment

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

Just looked at the Devtools change in detail. Can't vouch for the rest :)

Comment on lines +16 to +17
import type { ISharedTree } from "@fluidframework/tree/internal";
import { SharedTree, encodeTreeSchema } from "@fluidframework/tree/internal";
Copy link
Contributor

Choose a reason for hiding this comment

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

Just surprised to see these are all internal now. Are we sure not even ISharedTree should be public?

@jason-ha jason-ha merged commit fddd68b into microsoft:main Feb 10, 2024
47 checks passed
kian-thompson pushed a commit to kian-thompson/FluidFramework that referenced this pull request Feb 13, 2024
- Configure full ESM build and declaration for tree
- Set exports (only "public" and `internal` as there are no others) 
  - "@internal" uses of tree updated to import "/internal"
- Build CommonJS secondarily with injected CommonJS package.json at
build

A module package.json is also injected into ESM build for symmetry.

ESM api-extractor tsconfig is overwritten to use `Bundler` resolution as
`Node16` does not appear to be robustly handled.
@jason-ha jason-ha deleted the tree-exports-with-esm-as-primary branch February 21, 2024 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: build Build related issues area: dds: propertydds area: dds: tree area: dds Issues related to distributed data structures base: main PRs targeted against main branch dependencies Pull requests that update a dependency file
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants