-
-
Notifications
You must be signed in to change notification settings - Fork 110
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
Next major for the ecosystem #121
Comments
Are there discussion threads (any links to notable discussions are good enough!) where I can read more into the motivation to move formally to using ESM? Inquiring to stay up to date with the unified ecosystem, and also getting context in the broader JS ecosystem. |
micromark/micromark#27 and other PRs there, but that was both ESM and CJS. |
Great to see unified switching over as well! @wooorm Please don't archive |
I’m also going to try to add jsdoc based types to everything (starting with ±150 of my own projects). Another big one is to add support for plugins as ESM in |
@wooorm, (for my own learning), a few questions relating to his upcoming refactor:
The main benefits I'm inferring is decoupling the dependency and reliance on TS, so that if the ecosystem needs to be free of TS in the future, we at least have JSDocs with an easy path to decoupling in the future? I'm curious about the decision because I'm facing similar concerns with trying to keep source code as independent from tooling/dependencies as possible (
Would love to hear the perspectives and approaches of the team here, so I can also learn something from it! And my (personal and likely not-important) opinion on:
I think most authors avoid default exports and use named exports (explicit named export is useful as a static guard, also great for refactoring), although I think that if we have to consider how consumers would use an API, we should make the appropriate decision based on how this library is intended to be consumed. For myself, I use 1) named exports for internal implementation all the time and 2) decide the final public export based on what makes sense for the consumer. |
Didn't realize Github does not support comment threads, so it's kind of annoying keeping track of discussions and responses :P (this comment further adds to the problem) |
I strongly dislike having to compile things. I think the benefit of JS is that it just runs everywhere. If you’re going to compile, IMO there are much nicer languages. I don’t write these projects in JS because I like JS per se (although I do), I do it because it works everywhere. This is also why is dislike “modern” javascript. One such example of this is how the projects that’ve pushed ESM over the years, actually don’t support ESM. Webpack, snowpack configs, Jest: they all don’t get actual ESM. We (@ChristianMurphy and I) did run into a couple places where JSDoc based TS doesn’t cut it yet, though. So, you’re seeing some of the same things I’m seeing, but I hope the above explains a bit more about my current state of reasoning
Omgosh! It is! Of course, bundling would be needed in most professional settings. But it works. And it works nicely.
Using ESM from CJS is a bit hard, you have to use an
You can set
Can you expand on this? IMO, all projects that are “universal” (node + browser) should care about size.
I agree on not using default exports for libraries: while names are a bit superfluous in most of my projects (as they export one thing), default exports have downsides. |
Thanks for the detailed response, it helps affirm some of the dilemmas I've been having around 'modern' JS. I 100% agree with a lot of the statements you (for rest of the post, "you" refers to the On typing, TS does offer a much delightful developer experience, but I think the danger is the community being over-eager in thinking that TS guarantees type-safe code. TS doesn't protect against runtime invalid types, and in the end it just boils down to a simple question if consumers are using the APIs as-intended. I personally think TS improves the developer experience and exploration of code, but I think that is as far the value I can see with it, and I agree with your principles on avoiding rewriting libraries if On build tools, Anyway, the above is just myself chatting and responding to something that I've slowly come expose to and appreciate because of the discussions and journey in learning Question 1: Question 2:
import x from 'vendor-library';
x();
{
"module": "dist/index.module.js",
"main": "dist/index.js",
} Note that there is NO Running
In the above example, I cannot control setting |
I went on a bit of a tangent here, based on a misunderstanding of your second question, @chrisrzhou. Scroll down to see my attempt to answer that and the first one.I feel you and that's the one big thing I'm always unsure on how to solve it. I really like how the ecosystem and community in general is finally but slowly moving to the methodology you described, the somewhat naive philosophy to at least try to write "future-proof" code. To follow the standard, to do things that work everywhere. Well at least everywhere a developer expects it to work. But, yes, you are totally right, at some point, you also just have to accept that projects progress with wildly different velocities and manners to that desired pure ESM utopia. Some will even never get there, because they are either unmaintained, or the respective maintainer doesn't believe in that already mentioned philosophy. People have different backgrounds and expectations of how code should be interacted with, what software should do and what it shouldn't do, and that's fine. From a personal perspective, for example, I would never use Typescript in the context of coding modules and projects that are meant to be used by other fellow developers, and I don't support or share the philosophy behind the language at all. People can shout at me all they want about its "benefits", I know about them, I worked with Typescript professionally, but as long as it isn't (and shouldn't be) directly interpreted by browsers and runtimes and it still needs to be compiled, as long as it just follows a standard that's ultimately controlled by a single company instead of at least a couple of companies, important developers we kind of trust and a transparent well-thought-out process of introducing new features, it just makes no sense to me why I should use it in a community context. But without going to much into depth about all that, I don't think the majority of unifieds modules depend or have to depend on such CJS Question 1:Most of unifieds projects, correct me if I'm wrong, also aren't meant to be used directly in a browser, they are meant to be used by other developers and their projects. And I understand the accessibility concerncs, the aspiration of deploying your project in all imaginable formats to please the most amount of developers possible. But the answer to accessibility ends where the question of complacency starts. I think @wooorm ultimately decides which way unified will go, but I definitely think it, and - trying to answer your first question - anyone writing "ESM packages intended for ESM consumers", should "leave it to consumers to decide how to handle this". Question 2:Your second question has multiple layers though. If we are talking about Node.js and the general context of unified in its current state, no, there aren't any conflicts. Running If you are referring to the more general context of "real" ESM, independent of Node.js, then yes, there would be an error if you import the cjs file. Since ESM also doesn't allow you to just do import x from "vendor-library/dist/index.module.js"; Or actually, in this case: import x from "./node_modules/vendor-library/dist/index.module.js"; Do I personally believe unified (and similar projects for what it's worth) should be Node.js-independent and use the "real" ESM format of importing actual files, maybe even by using Deno and publishing to nest.land? Yes absolutely. Do I think it would be healthy to do this at the same time it switches to ESM syntax and output in general? Nope. I would suggest to focus on that first, to make migration easier and especially since "pure" ESM, Deno, nest.land and all that stuff is still pretty new territory for most people. |
I believe source code should be readable. I don’t see a lot of value in publishing minified bundles. There are cases where, based on the ecosystem (browser, node, react-native, etc), or based on other environmental things (dev vs. production), different code should run. These “conditions” are being added to Node. In my RSC demo I found that the React team was experimenting with them for server vs. client.
The I suggest for folks that maintain semi-inactive projects/apps to stick with what they have and not update dependencies moving to ESM. So, for “Does unified packages face this problem”: No, unified does not face such a problem, because switching over to ESM solves everything.
I do decide a lot through sheer activity and also some level of seniority in this ecosystem, but it’s a democratic process: https://github.com/unifiedjs/collective/blob/main/decisions.md And interesting for you both: in the future we’ll get import maps in browsers: https://github.com/WICG/import-maps. That allows these “bare” specifiers ( EDIT: And, the inverse is also being worked on (but experimental) in Node, with Node loaders. Here’s how to import |
Seems like a really disruptive/hectic period for JS developers, but hoping the equilibrium settles to a simpler and standard ESM with less build tools. Would be great if more JS code is just standard JS code! Thanks for all the detailed response and info! |
For the packages that have other dependencies, and there is no transpilation happening, we cannot use Pure ESM packages because:
|
The above is incorrect because:
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I want to chime in here and say that while I really love using Remark and appreciate the work put into it, getting the ESM modules to work TS is an absolute pain. I get wanting to move forward with an ES2015 feature that has had over six years now to catch on, but the simple fact is that the rest of the ecosystem still isn't ready. Until then, I really wish that Unified would change its mind about the decision not to include backward-compatible packages. I'm using remark in an app built with TS + webpack + electron. With this combination of tools, some of the unified packages (mostly, for tree manipulation) simply don't work. Instead, I ended up either copying the unified source files manually into my own tree and rewriting the imports, or rewriting the functionality myself in pure TS (the unified API currently likes to wrap everything up in all-but-the-kitchen-sink functions, which are difficult to write types for, as evidenced by the current JSDoc strings). On a positive note, I'm glad that unified is flexible enough that I can write my own solutions when needed. I just wish I didn't have to. |
Folks, it’s fine to talk about ESM. Either here or in other places. But this issue is about moving to ESM and other things in majors. And the discussion on whether to do it or not was had in Feb and March. @benrbray I don’t think dual ESM/CJS is viable for the JavaScript ecosystem: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c#gistcomment-3851022. Re TS: one part of the majors is also that everything is (strongly) typed, externally but also inside projects themselves. So that at least should help you a lot when you can move to ESM in TS. |
This comment has been minimized.
This comment has been minimized.
I'd second @wooorm's comment in #121 (comment) and would add:
It may be worth opening a discussion to talk through this (https://github.com/unifiedjs/.github/blob/main/support.md#questions).
In the latest version all utilities are pure TypeScript. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Done! Alright, folks, everything is now ESM and typed! The packages up for deprecation were deprecated. I’ve “soft deprecated” certain packages by first updating them and then marking them as legacy, like so, to prevent too much churn. They can be fully deprecated later but this makes it a bit easier to still land security fixes when needed. If you have questions about ESM, you might find answers in this Gist. |
Soon (April), it’s time to switch to ESM (without CJS backup) for all packages in the ecosystem.
That’s a lot of projects switching over, and a round of majors that bubbles from the bottom through to the top.
I’ve had some experience with that recently in a push in micromark (with CJS fallback, causing issues). My recent own projects dioscuri and xdm are fully ESM. It’s going to be a lot of fun for the ecosystem 😅
Otherwise, here are some changes slate for this next bubbling:
Big breaking changes:
remarkjs/remark-external-links
remarkjs/remark-unwrap-images
remarkjs/remark-highlight.js
remarkjs/remark-react
remarkjs/remark-autolink-headings
remark-html-katex
inremarkjs/remark-math
remarkjs/remark-midas
remarkjs/remark-defsplit
retextjs/retext-sentiment
vfile/vfile-reporter-folder-json
remarkjs/grunt-remark
syntax-tree/unist-builder-blueprint
syntax-tree/unist-builder-blueprint-cli
syntax-tree/hast-util-to-snabbdom
syntax-tree/mdast-util-from-quill-delta
remark-yaml-config
: updatejs-yaml
vfile-matter
: updatejs-yaml
unified-engine
: updatejs-yaml
vfile-message
: renamelocation
->position
(Renamelocation
field toposition
vfile/vfile-message#6)vfile
: renamecontents
tovalue
(Renamecontents
field tovalue
vfile/vfile#49)mdast-util-to-string
: do not usenode.title
(Removenode.title
support syntax-tree/mdast-util-to-string#8)mdast
: renamedepth
torank
(Renamedepth
torank
syntax-tree/mdast#31) (I feel the other issues there plus Rename node types syntax-tree/nlcst#6 are too much break for what they bring)hast
: change doctypes (Simplify doctypes syntax-tree/hast#19)Small breaking changes:
h
,s
as a JSX pragmas syntax-tree/hastscript#15unist-util-find-all-before
’s results should be reversed probably Results are reversed syntax-tree/unist-util-find-all-before#6For ES++ features (unifiedjs/rfcs#4), I’d say we can do that after we switch to ESM, because ESM will already be a lot of work, and it gives us a baseline of what ES features / engines to support.
The text was updated successfully, but these errors were encountered: