-
Notifications
You must be signed in to change notification settings - Fork 819
number-formatters: build dual CJS and ESM versions #43106
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
base: trunk
Are you sure you want to change the base?
Conversation
Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.
Interested in more tips and information?
|
Thank you for your PR! When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:
This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖 Follow this PR Review Process:
If you have questions about anything, reach out in #jetpack-developers for guidance! |
Code Coverage SummaryThis PR did not change code coverage! That could be good or bad, depending on the situation. Everything covered before, and still is? Great! Nothing was covered before? Not so great. 🤷 |
d47044b
to
7c36e1d
Compare
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'd really rather we don't add more use of rollup. The configs we have tend to be unmaintained, and to depend on unmaintained plugins, and throw warnings which are ignored. This one, for example, issues this warning:
(!) Plugin typescript: @rollup/plugin-typescript TS5110: Option 'module' must be set to 'NodeNext' when option 'moduleResolution' is set to 'NodeNext'.
Is anyone committing to maintaining the rollup configuration here, including replacing outdated plugins and such?
For a library we probably shouldn't need a bundler at all, just tsc to convert the TypeScript to JavaScript.
I also find that the resulting files in dist/cjs/
are not correct. The package.json has "type": "module"
, indicating that files such as dist/cjs/index.js
are supposed to be in ESM rather than CommonJS format. While some tooling may ignore this mismatch, other tooling will fail. To work correctly, these files need to be named like dist/cjs/index.cjs
instead.
"target": "ES2024" | ||
}, | ||
// List all sources and source-containing subdirs. | ||
"include": [ "./src" ], |
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 find that blanket-listing directories (rather than listing the specific entry point files such as src/index.ts
) in a tsconfig that's used for compilation tends to give odd results.
In this case we seem to be ok because everything is reachable from the entry point, but in other packages I've seen this pointlessly compile .test.js
and .stories.js
files.
"import": "./dist/mjs/index.js", | ||
"require": "./dist/cjs/index.js", | ||
"types": "./dist/index.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.
Typescript calls for "types" to come before "import" and "require".
"import": "./dist/mjs/index.js", | |
"require": "./dist/cjs/index.js", | |
"types": "./dist/index.d.ts" | |
"types": "./dist/index.d.ts", | |
"import": "./dist/mjs/index.js", | |
"require": "./dist/cjs/index.js" |
Thanks for your feedback @anomiex 👍 I'm getting rid of Rollup and building the dual package with TypeScript instead. There is one The only thing that doesn't work yet are The little issues reported (order of the |
15d0d6c
to
978c9d4
Compare
"typeRoots": [ "./node_modules/@types/", "src/*" ], | ||
"target": "ES2024", | ||
"importHelpers": true, // Import helpers from `tslib` instead of inlining them | ||
"customConditions": null // CommonJS build fails when customConditions are defined and this package doesn't need them anyway |
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'm wary of this. the customConditions
are what makes
"jetpack:src": "./src/index.ts", |
At the moment, disabling it here is probably ok, since this package doesn't depend on anything else within the monorepo. And maybe this package never will. OTOH, it may be a bad pattern since this may get copied into other packages and break things there.
"clean": "rm -rf dist/", | ||
"build": "pnpm run clean && pnpm run build:esm && pnpm run build:cjs", | ||
"build:esm": "tsc --declarationDir dist/types --outDir dist/mjs", | ||
"build:cjs": "tsc --module CommonJS --moduleResolution node10 --declaration false --outDir dist/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.
I'm pretty wary of this too. https://www.typescriptlang.org/docs/handbook/modules/reference.html#commonjs, for example, says "You probably shouldn’t use this."
It seems the more modern way to do something like this, in the absence of offical support in tsc, is to somehow munge the "type" in package.json just before the build to have tsc with "nodenext" build the cjs version, then restore it after. For example, it looks like @knighted/duel does that directly, while tshy assumes sources are in src/
and creating a temporary stub src/package.json
will manage to DTRT. (of those two, BTW, duel seems more of the "do one specific thing" philosophy while tshy seems more "try to do all the things".)
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 think I addressed both concerns by creating a special src/package.json
during the CommonJS build, with type: 'commonjs'
. Just like tshy
does. It's easy to do, just a cp
and rm
command.
We don't need to remove customConditions
any more, because module
and moduleResolution
are always nodenext
. It's the type
field that triggers the CommonJS build.
Ensuring that files inside @anomiex What do you think about using And the
|
I think, if we really do want a dual package, that using |
efa52de
to
688bb92
Compare
This PR adds a Rollup build to the
number-formatters
package and makes it produce both CJS and ESM versions of the module. Also adds the "legacy"main
,module
andtypes
fields topackage.json
in addition to the modernexports
field.This makes the package consumable both by modern and legacy tooling setups.
The Rollup workflow is modelled after what we already have in the
@automattic/charts
package. I basically copied the config and then simplified it a lot. We don't need any CSS support innumber-formatters
for example. And also I think that Terser minification doesn't need to be done. It's up to the final consumer to do all the minification at once.When I use the resulting package in Automattic/wp-calypso#102475, all the errors reported there disappear: Jest is able to require the CJS version, and also TypeScript is able to consume the package without problems.
Testing instructions:
pnpm run build
in thedist
directory is valid and makes sense.@automattic/number-formatters
– use in section stats > insights wp-calypso#102475 (I just copied overpackage.json
anddist
) and verify that it fixes theyarn test-client
andyarn typecheck
errors.Does this pull request change what data or activity we track or use?
No.