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
would you be open to a pure es module? #457
Comments
Sorry, there's not enough info here for us to be able to evaluate what you're suggesting. What is the change you want to make? What value does making the change bring to the project? What problems might be experienced with making the change? |
Sorry for being overly brief; Happy to add more details. :)
I would like to have an es module version of espree, so that I can more easily import it directly from a web browser without the need for a build step. This is currently possible via skypack. e.g., I can do: import espree from "https://cdn.skypack.dev/espree"; However this relies on some magic built into skypack's cdn which takes the commonjs module published on npm and does some transformation on it to expose an
I think from my perspective it brings a few things:
I think the biggest question to anticipate is "will this impact people using espree from npm/node?". I don't think it should impact those use cases at all. There are 2 strategies that seem obvious to me as possibly viable:
Maybe this is something that is more easily demonstrable with a PR. If you'd like to see what I mean I'm happy to submit one. btw, thanks for a great module! |
Thanks, that’s helpful. If we can ensure backwards compatibility, then I’m in favor. Note: this would need to be in a major version bump. @mdjermanovic @btmills thoughts? |
This looks like a big change for consumers. How would, for example, ESLint load espree after this change? |
eslint could either: a) do the same thing, making the next major version of eslint node 12.17+ only |
c) do nothing; if |
I don't think That goes for all other dependents and their dependents, they would all have to switch to ES modules if they want to use espree and/or eslint. We can't make such a breakage even in a major version.
ESLint can't stay on a fixed version of espree, so we'd have to maintain two espree versions. Seems much easier to provide a dual package? |
in order to achieve Personally given that node is about to stabilize the module interface, and also given that node v10 will move to unmaintained in less than 6 months (April 21') I don't think it's really drastic to do That said, I realize this is my own personal opinion, and it is less conservative than having dual package support for however long one sees fit. The most inclusive approach (node version wise) is to publish dual packages for both espree and eslint. Either way though, will be a nice step forward! |
Actually, dependents could use
That would be possible, but I think it isn't a common practice for Node tools/libs to bundle dependencies. |
yeahhhh it's a bit icky. making both of them dual package or both of them pure es modules are going to be the 2 most straightforward options. |
I think dual package is really the only viable choice here. |
If I got the #458 proof of concept right, the published es modules are source code:
Does this make it possible to |
I've been using skypack's cdn, which basically produces a pure es module for every package in npm. They essentially do 2 things:
This works today for espree in a browser: If you open up that link directly in the address bar you can follow the urls and you'll see the modified version of So the stuff in #458 would basically eliminate 1 of the things skypack needs to do (the es module creation.) |
Hi @mreinstein 👋 we agreed in yesterday's TSC meeting to go ahead with this! As a next step, can you put together an RFC? That will outline help the team understand the tradeoffs and impacts of the change. Thanks for working on this! |
@mreinstein we generally hold off on merging breaking changes until we can do them as a batch, just in case we need to do a minor release in the meantime. So the goal for #456 should be to get the PR approved with no further changes needed rather than getting it merged. |
Thanks for the heads-up re: process. Is #456 essentially approved now? Shall I switch over to the RFC? |
Yup, looks like #456 is all set to go. |
@ljharb you mentioned an interest in providing the initial |
@mreinstein sure! it depends on the desired entry points tho - do you have paths in mind? |
Here's where we left off:
And then your comment about possibly using an so |
@mdjermanovic followed up with this comment, which has an updated snippet for |
The “module” field is not a thing, so it should be omitted. One or two bundlers use it, but espree isn’t really used in web browsers afaict. package.json is included so tooling doesn’t break; and type:module should not be used, so i fixed the file extensions (which is also needed for full back compat). The array fallback is needed for a few node versions that had an incomplete exports implementation, as is “default” instead of “require”. "main": "dist/espree.js",
"exports": {
".": [
{
"import": "espree.mjs",
"default": "./dist/espree.js"
},
"dist/espree.js"
],
"./package.json": "./package.json"
} |
why is |
So that tooling can access it, since otherwise there’s no reliable way to get to it from outside. |
JSON modules are stage 3, but the exports field restricts require as well, so any tooling using require to get at package.json breaks without that line. |
While working through the tests, I've run into a snag. Unfortunately, Some thoughts on other workarounds:
Would be interested in hearing people's thoughts |
for example, this works out of the box: import * as espree from "../../espree.js";
import tap from "tap";
async function parseTest () {
const a = await import("./tester.js");
const tester = a.default;
tap.equals(typeof tester.getRaw, "function");
}
parseTest() |
I've done some more exploration, and import tap from "tap";
tap.mochaGlobals();
it(`should parse correctly when ${feature} is ${isPermissive}`, async () => {
config.ecmaFeatures[feature] = isPermissive;
const expected = await import(`${path.resolve(__dirname, "../../", FIXTURES_DIR, filename)}.result.js`);
tester.assertMatches(code, config, expected.default);
}); |
ok, the 2nd PR is ready. It is a monster. :o |
I'd be happy to send a PR, maybe something along the lines of https://nodejs.org/api/packages.html#packages_approach_1_use_an_es_module_wrapper
thoughts?
The text was updated successfully, but these errors were encountered: