-
-
Notifications
You must be signed in to change notification settings - Fork 109
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
[WIP] build: generate commonjs, es module, and umd versions of unified #76
[WIP] build: generate commonjs, es module, and umd versions of unified #76
Conversation
These changes were inspired by work on https://github.com/syntax-tree/mdast-util-from-quill-delta A few tweaks to the build to generate ESM, mark the package as side effect free, and drop some polyfills that can be applied by the build process cut the package size in half from v0.1.0 to v0.1.3. Whether or not this PR is merged, would be interested in taking some of the ideas/optimizations from there and applying them to unified itself. |
"test-api": "node test", | ||
"test-coverage": "nyc --reporter lcov tape test", | ||
"test-coverage": "c8 --reporter=lcov --check-coverage --lines 100 --functions 100 --branches 100 tape test", |
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.
also migrate coverage to c8
, which leverages V8's native coverage capabilities, since the builds now are done on Node 10+
https://github.com/bcoe/c8
May open a separate PR just for this.
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.
C8 seems to be pretty young, unstable (see pipelineParse
), and include bugs. What’s the benefit of switching?
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.
(oh and see: #76 (comment))
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.
C8 seems to be pretty young, unstable
Young-ish, 1.0 was released in Oct 25, 2017, over two years ago.
It is as stable as the coverage feature in v8.
and includes bugs
🤷♂️ so do Nyc and Istanbul
What’s the benefit of switching?
It is a native feature of Chrome/Node and should more accurately reflect runtime coverage, than the build-instrumentation based approach of Instanbul (some work may still be needed), as well has having the performance boost from running directly in the platform.
"source": "index.js", | ||
"main": "dist/unified.js", | ||
"module": "dist/unified.mjs", | ||
"unpkg": "dist/unified.umd.js", | ||
"types": "types/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.
These are the different build types recommended by microbundle
https://github.com/developit/microbundle#set-up-your-packagejson
The recommendations also line up pretty well with Babel's recommendations
https://babeljs.io/blog/2018/06/26/on-consuming-and-publishing-es2015+-packages
"types": "types/index.d.ts", | ||
"sideEffects": false, |
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.
this flag is specifically for bundlers, it signals that additional tree-shaking optimizations can be safely made.
https://webpack.js.org/guides/tree-shaking/
@@ -461,3 +457,6 @@ function assertDone(name, asyncName, complete) { | |||
) | |||
} | |||
} | |||
|
|||
// Expose a frozen processor. | |||
export default unified().freeze() |
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.
This was moved to the end due to bcoe/c8#66
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.
This is interesting and we should do this somewhere in the future, but now?
I can’t run this code without compiling it. This would probably be a major release and something that bubbles through 250 projects like TS definitions. ESM in Node is still unstable, but should be there soon, so I’m thinking it’ll be solid in Node 14, which I propose we wait for?
P.S. I think it’s different for apps: you can do whatever, but for libraries I prefer less frequent changes and not using beta features.
var pipeline = trough() | ||
.use(pipelineParse) | ||
.use(pipelineRun) | ||
.use(pipelineStringify) |
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 make every run
significantly slower?
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.
Maybe, benchmarking would give better insights on the potential impact.
import bail from 'bail' | ||
import vfile from 'vfile' | ||
import trough from 'trough' | ||
import plain from 'is-plain-obj' | ||
|
||
function pipelineParse(p, ctx) { |
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.
For some reason coverage doesn’t see this function as covered?
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.
This is likely also related to bcoe/c8#66
"test-api": "node test", | ||
"test-coverage": "nyc --reporter lcov tape test", | ||
"test-coverage": "c8 --reporter=lcov --check-coverage --lines 100 --functions 100 --branches 100 tape test", |
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.
C8 seems to be pretty young, unstable (see pipelineParse
), and include bugs. What’s the benefit of switching?
For Node, Modules will likely be marked as stable in the next minor release of 13. For browsers and bundlers: modules have been supported for a while. |
While browsers are important, and they do support ESM for a bit now, I would argue that currently ESM is written practically only for compilers, and only experimentally for browsers. People write for Webpack/Rollup, a “fake” ESM, not for the actual HTTP/2 benefits of ESM. From the Twitter thread, and clicking through on comments, reading GH issues, and watching the conversation, it seems there are still things undecided, or at least differences between this PR here (e.g, My reason for wanting to wait for 12 and 14, is that those are LTSs, that most users will be on then. At that time, ESM in Node will have figured out all the inevitable bugs that will show up for such a years long process. I don’t think it’s responsible to move a whole ecosystem/millions of users over now, in such a transitioning phase |
You mentioned that quill was halved in size, do you have the numbers of this change for unified? |
There may be some confusion here. The difference is adding more module options. |
Comparing the minified file produced by this build to the one from the previous release. The difference at this level isn't massive, just 7-9 KB. |
Your statement “The difference at this level isn't massive, just 7-9 KB” seems to imply that with ESM and microbundle, 7-9 KB is saved, but that is not the case: that number comes from dependencies that are included in the current bundle, and will have to be included in any bundle. The current bundle is 3.3kb minzipped, of which 37.2% is from unified itself (excluding dependencies), so unified without dependencies is currently With this PR, I get
I refute that, because a) I found that there is no real size difference, as shown above, b) tree shaking can be done on CJS pretty well too, and c) tree shaking is useful for monoliths, where branches can be ignored, whereas unified is modular, and packages act as contained branches |
This assumes users can/will use browserify.
webpack only tree shakes esm dependencies https://webpack.js.org/guides/tree-shaking we could add the additional alternative, to document browserify, rollup, and parcel to steer users in that direction (as part of unifiedjs/unifiedjs.github.io#7), and/or to document that webpack users should include https://github.com/indutny/webpack-common-shake
counter example, mdx. What this is still overlooking in the potential savings of a bundler-less setup, like pika pack. Where supporting ESM would allow for HTTP2 optimizations and keeping partial caches even when dependencies change. |
I meant to imply that it can be done, not that it can only be done with browserify. As you show, common-shake can be used in webpack as well.
Yes, good idea! 👍
Babel/MDX already have ESM! And the runtime is not really meant to be used: it’s super unsafe, and the size is documented.
I don’t think there are though?
Yeah that’s very interesting! |
|
Can open a PR just for that to discuss further. |
Where did you find that rollup supports CJS sideEffects? With a quick Google I couldn’t find that. Anyway, if it does, I think we should add it!
I think C8 would be useful, bcoe does good work so it’s probably worth it to switch to the successor of nyc! |
From reading between the lines a bit. To tree shake rollup converts CJS to ESM https://github.com/rollup/rollup-plugin-commonjs |
Goal
Generate several distribution versions for different environments, to allow minimizing downstream tooling to minimize the download/bundle/build size.
Approach
This leverages microbundle, to generate a common js build for Node, a UMD build for all browsers, and an ES Module build for modern browsers.
Microbundle also minifies the builds and includes a sourcemap for simpler debugging of minified build.
Alternatives