-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Add support for ES6 import syntax #1186
Comments
I've been waiting for this feature to land in node first so browserify can match the semantics properly. I'm also concerned that if browserify implements a default es6 import mechanism while node doesn't have one, it will needlessly fragment browser and server ecosystems. |
Yes, my approach to writing modules is currently to write them in ES6 but only expose ES5-compliant I get your concerns, and they are indeed important ones. How feasible would you say it is to expose this as a plugin for browserify (I'm currently looking into |
I've created a small gist with a proof of concept for a plugin. I'll start working on it! |
@romeovs |
@nmn but do these imports with babelify have the complete ES6 semantics? The problem is really the way browserify concatenates the imported files. esperanto does this correctly, but lacks other features that make browserify a much better choice. |
@nmn after some testing I can see that it does! |
I think @substack is right in waiting for proper node support. browserify brings node to the browser; if node doesn't support If babelify doesn't follow the right semantics, raise the issue with them or ask for an |
How about now? |
It appears a good deal of fragmentation will start occurring because of I know that Node doesn't support ES6 imports quite yet, but arguably The reason why I think we should consider options is because if other loaders become popular because of only a single feature, it might signal there's a need for it. I'm not quite sure what the correct resolution is; for the package I'm writing that consumes For now I'm posting this here to signal that changes are happening, and we'll probably need to think of a solution for this 😕 edit July 2016: nope nope, we shouldn't move ahead on |
@yoshuawuyts Implying that |
Browserify's greatest feature is the transform pipeline (heck the parts that actually break require into a dependency tree and combine that tree into a bundle aren't even in this repo, they're the module-deps and browser-pack packages) and the collection of transforms we have that make . IMHO rollup's greatest feature is not ES6 imports, but the static analysis and tree shaking it does. So even if browserify rushes to hastily implement non-babel ES6 import support before any JS engine natively supports it, I doubt that'll stop may people from using rollup. There are already a pile of other packages using ES6 import; but they all do it alongside the use of other ES2015 features. So I expect packages like d3 that only use ES6 import is going to be a rarity. And the moment you use any other feature, you need Babel, whether you're using rollup or browserify. So I doubt "rollup lets me use packages that only use ES6 import without needing Babel" will be the reason people use rollup. I think the problem browserify is going to have is rollup's plugins. That functionality is what turns rollup from just a tool to pack up ES6 exports/imports into something that can pass as a standalone loader. Rather than trying to hack ES6 import in with require schematics, just as a way to bypass babel in a few cases (because if you use Babel this is already entirely possible). I think it would be better to accept the area that rollup is better at (tree shaking ES6 imports) and find a way to break up rollup and create a It's a different topic. But I think browserify's other undoing may be how easy it I've seen it is to make a simple transform but hard it is to make one that correctly preserves source maps. I don't see any easy tools for source-map aware string manipulation. And while I'd love to transform using an AST, that's not viable when each transform has to |
FYI: there's an enhancement proposal for Node.js being discussed here regarding ES2015 modules: |
Coming in to say I'm actively getting issues because d3's latest version is only using ES6 syntax. I can't use my browserify tooling now. The time seems ripe for this change as the ecosystem has already begun the move, otherwise I think browserify will have lost its relevance in this increasingly competitive bundling space. |
Hello @TatumCreative. D3's README says their releases support CommonJS. Is that not the case? Even so, there are multiple tools for compiling ES6 module syntax to CJS -- can you not use one of those? |
Hmm... Yeah my bad. It looks like user error on my part. Sorry about that. My opinion still stands though. Three.js just landed a big patch to go the ES6 route as well. Personally I'm in a weird position as I tend to primarily target one browser and I want what Browserify does with bundling without the side-effect of mangling my ES6 code and turning it into ES5 code. I can probably come up with a solution if I do more research, but regardless I still feel it is important to support ES6 imports sooner rather than later, as the community is already adopting it in projects. I feel like fragmentation is happening as people have moved on to other bundling solutions, which I would really not have to do, as I really love the browserify tooling ecosystem. All that said, I probably don't have the time to contribute to this project to make it happen, and I appreciate the work everyone does here! |
@TatumCreative I'm glad that you were able to correct this issue. The contributors to Browserify, including myself, understand your frustration. Browserify has always been a way to use Node.js-compatible modules in the browser. As a result, Browserify has always looked to Node.js for how to implement the module resolution and loader. Right now Node.js doesn't support ES6 imports; there are blockers in other parts of the stack. We don't yet know the final algorithms or behaviors. While slower than we would all like, these efforts are moving ahead. I'm excited for the day! Once Node.js has implemented ES6 imports and exports, we can add support to Browserify. You may wish to opt-in to a possible future, and Browserify's plugin system allows you to do so. But it's not the place for us to make that decision for everyone. As an aside, there's probably still a few improvements to Browserify to make using standardized ES6 a little more comfortable, even without imports and exports. I'm happy to take a look at those issues. 💖 |
@TatumCreative Ok, no problem, thanks for the feedback.
I understand. That's not that weird of a position, as people increasingly want to selectively transpile parts of ES6. For example, only transpile the parts not natively supported by recent versions of Node. ES6 has no native module bundling story anyway, so even if a browser supported ES6 100% you might still want to bundle them via transpiling just module syntax to ES5. I think there's probably a solution for you. If I'm not mistaken some people run Rollup to convert module syntax before carrying on with bundling with Browserify, or you could run Babel (Babelify) with just the module transform enabled. With Rollup you could get the benefit of tree shaking as well.
Like other people have mentioned, the community is adopting the syntax and speculating about what behavior will be standardized. So it's not necessarily all smooth sailing to implement it now. For example, from version 5 to 6 the core Babel CommonJS module transform made a big change in its output. If you look at the issue linked in the comment before yours up above you'll see that the discussion about how to implement ES modules in Node is epic and very complex.
I think that has more to do with other factors than this.
Thanks! |
Thanks @jmm and @terinjokes! I think that is very well reasoned, and I agree with where you all are coming from. I'll probably end up adding another tool to help me deal with this until all of this gets sorted out on the node end. I can deal with a little bit more tooling complexity on my end :) I'm almost afraid to read that node module discussion, lol. Keep on rocking it! 😀 |
For anyone coming into this thread, the browserify transform rollupify will take all of your ES6 import statements and hoist them all into a single module scope. |
I am assuming I can't use ES6 style imports with browserify and babelify still? |
You can use babelify and things will work - it's still not recommended
though, given that Node has no support for it
…On Wed, 4 Jan 2017, 15:33 George Katsanos, ***@***.***> wrote:
I am assuming I can't use ES6 style imports with browserify and babelify
still?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1186 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACWleq1joqUYnVh2Zr91XLw-dGrSngm4ks5rO62pgaJpZM4D4Vtf>
.
|
I use browserify in Gulp.. does this change things?:) |
Nope
…On Wed, 4 Jan 2017, 15:45 George Katsanos, ***@***.***> wrote:
I use browserify in Gulp.. does this change things?:)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1186 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACWlem6m1eKTQn1jgG2Br7bqWwhgBbCFks5rO7BtgaJpZM4D4Vtf>
.
|
What does "not recommended" mean? The end result seems to work? |
I mean that Node doesn't have support for import and last I checked parts
of the spec are still not done and might change even. If you want things to
work everywhere, today and in the future, require is a more stable choice.
I don't want to debate anyone on this, I'm sure other people have other
views on this.
…On Wed, 4 Jan 2017, 16:01 George Katsanos, ***@***.***> wrote:
What does "not recommended" mean? The end result *seems* to work?
Should I just drop gulp/browserify and use webpack instead?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1186 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACWlelQGOr3-AA2Jzh9voscMTuuBjzK8ks5rO7RagaJpZM4D4Vtf>
.
|
Alright. From reading around it seems to me that's the basic syntax is pretty finalized and is the future but I could be wrong of course. |
@gkatsanos the syntax is stable, but the mechanics of how to do imports (and specifically, how Node.js will do imports) are still being figured out. Browserify is a set of tools that together bring Node.js's module resolution and loading to the browser. Since Node.js doesn't support importing ES6 modules, we have nothing to implement. |
@terinjokes alright, it's clear. How does browserify compare to webpack in that respect? |
@gkatsanos Being module bundlers, Webpack and Browserify are similar. They take input, resolve a tree of dependencies, and generate a bundle (or bundles) as output. As described above, Browserify supports only Neither project knows how Node.js will handle ES6 resolution and loading. There have been discussions of using separate file extensions or looking up a key in the module's package.json. We'll have to wait and see gets implemented. Webpack's plugin system would likely allow them to pivot and allow developers to configure which behavior they want. Browserify prefers waiting for Node.js to decide and not have the need for configuration or the fears of breaking user applications. |
I don't agree; until node supports it unflagged, browserify shouldn't support it. Browsers only currently support URLs with |
This comment has been minimized.
This comment has been minimized.
@ljharb Makes sense. Another option: what about allowing In the mean time I am considering writing a small transform to handle this transparently so users don't need to deal with babel/config/etc. EDIT: I just realized browserify actually supports dynamic |
(dynamic |
It wouldn't be safe to treat a Module as if it was a Script - modules are in auto-strict mode, for examples, and there's a number of things that could behave differently. |
For the mean time, I've created a browserify plugin that:
See here: |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Since now its in experimental state in node? What is the state of this? |
Experimental means it’s too soon for it to be used. Browserify should not support ESM until it’s supported unflagged in node; and once it is, imo browserify must support it. |
ES Modules are no longer experimental in Node 13.2 and are supported natively. nodejs/node@796f3d0 |
They remain experimental, they’re just unflagged. However, it means the clock has started, so it would be good to begin working on the necessary changes - although best to leave them unmerged/unreleased for now. |
It looks to me like the discussion here is directly related to the problem I'm experiencing as outlined on my question here at StackOverflow: Browserify --standalone with ES6 modules and multiple source files and exports In short, Browserify does not support ES6-style modules using the import syntax with the --standalone option. Is that correct? If so, it's going to require some big-ish changes to either my code or my build pipeline, and I would like to make sure I'm understanding this properly before I do. |
I would expect that currently browserify, with every option, requires a code transform first to convert from ESM to CJS before being able to continue. In other words, use Babel. |
I am already using babel via the babelify transformation. Should that work? I have a minimal example to reproduce my problem on my StackOverflow question. What I'm seeing is, browserify creates the expected API module in its output, but it includes exports from only one of the input source files. See pastebin here (Chrome pretty-printed version of the same thing here); source files are a.js and b.js, each of which export a single function. When running in the browser, the TestModule created by Browserify includes exports from all the source files in its definitions. But for some reason, the TestModule only gets the very last module that was included in those definitions. So in my example, TestModule only includes the fromB() function exported in b.js. TestModule does not end up with the fromA() function exported in a.js. I thought the issue discussed here might be related to my problem, since I'm defining the exports using the ES6 syntax. But maybe since I am already using babelify, this is different? From the gulpfile:
|
Here is a complete example of the problem I am having. Unzip the file into its own folder. I use yarn, so 'yarn install' followed by 'yarn build' creates output files in the dist/ folder. Open test.html in a browser, then go to the console to see the output. Let me know if this helps, or if there is a better way of sending this. |
If you have multiple entry points, all of them are executed, but browserify doesn't merge modules, which could cause bad unexpected behaviour. Usually multiple entry points are used primarily for things like polyfills, where you have one or more modules that do not export anything, and then one module that does: entries: [
'./polyfills.js', // no exports
'./app.js', // yes exports
] or with browserify plugins that then split each entry point's dependency tree into separate bundles at a later stage, so each bundle only ends up with a single entry point in the end. If you want to expose multiple modules as one object, you need to combine them in a separate module: // main.js
export * from './a.js'
export * from './b.js' and then use that as the entry point. |
This might be a long shot but I'd like to see this in browserify.
The ES6 module syntax has a few nice features compared to commonJS
require
method,namely bindings and cyclic dependencies.
Since these things are in the ES6 standard it seems reasonable to work them into browserify too!
Note that just using a ES6 to ES5 transpiler wouldn't work in this case because these are cross module concerns.
For instance,
babelify
is only able to transpileimport foo from 'foo'
tovar foo = require('foo')
at file-level, but this does not allow cyclic dependencies.The Esperanto project has a nice way of handling things but lacks too many features to be a valid replacement for browserify.
Is there any possibility to see support for ES6
import
syntax come to browserify?The text was updated successfully, but these errors were encountered: