Hey @evanw,
thank you for your package! ❤️
Is the Vue.js support still not planed #27? (in case of the react support)
If you use Vue with JSX you could probably use custom jsx-factory
and jsx-fragment
settings.
Sadly i do not use Vue with JSX :/
Evan mentioned in #27:
Since Vue has a custom syntax and compiler specific to their project, I consider replicating it inside esbuild to be out of scope for the goals of this project. This is the same reason that esbuild won't support Svelte
Even though I use svelte and want to use esbuild, it makes sense to me that Evan wants to create a bundler focused on a smaller scope - it's exactly what I would be doing too. I've been thinking a lot about bundlers lately and we really do need a fresh take like this. Rewriting the vue or svelte compiler really just doesn't belong in this project.
Though, if esbuild has plugin support one day (or at least file pipelining hooks), I can see someone being able to call the vue cli or a svelte cli compiler on each file before esbuild starts the bundling process. And it's possible there's members of the community that will try to recreate the vue/svelte compilers in golang, rust, whatever to improve performance even further :)
I created svelvet and once esbuild supports generating esm bundle outputs (#48) I might even pivot svelvet to use esbuild instead of snowpack.
if esbuild has plugin support one day (or at least file pipelining hooks)
Couldn't it be used as a library by a Vue/Svelte compiler?
Exactly! That's my point here:
I might even pivot svelvet to use esbuild instead of snowpack.
Though, file pipelining hooks in esbuild could be a really cool way to do plugin support without requiring plugins to be written in a certain language. Just calling other cli tools at certain steps in the bundling process would allow precompilation of js and other assets possibly, before esbuild finishes the bundle.
Vue SFC/Template to JavaScript compilation is a completely different process from TS/ES syntax conversions or minifications. Vue's template syntax and SFC formats are framework proprietary and subject to version changes - unlike ES syntax which is a standard and a much slower moving target (TS changes happen mostly at the type checker level and syntax is also relatively stable).
More importantly, the way Vue templates are compiled need coordination with Vue's runtime to ensure correct runtime behavior, so it really doesn't make sense for esbuild to cover that.
What I do think esbuild
can benefit Vue, and other JS projects in general, is exposing a way to consume esbuild from JavaScript without the overhead of starting a child process and reading/writing to disk for every file transform. An API that starts a long-living child process that can receive/send data from the Node.js main process. This allows other bundlers or dev systems (e.g. vite) to leverage esbuild
as the underlying sub bundler / TS/JSX transformer / minifier much more efficiently.
The reason for this is because while esbuild
is amazing, it's a black box that cannot interop with the JS ecosystem, and the bundling process doesn't allow pluggable transforms which is indispensable for building actual applications. My ideal system would be using Rollup as the bundler but esbuild
for actual TS transforms and final minification.
Well said!
without the overhead of starting a child process and reading/writing to disk for every file transform
I'm intending for esbuild to be a batch process of sorts. That's why it allows you to pass more than one file on the command line, so that many files can all be processed in one go. Is this not something that works for other bundlers or dev systems such as vite?
An API that starts a long-living child process that can receive/send data from the Node.js main process.
I've been thinking a lot about a streaming protocol over stdin/stdout that would let you feed esbuild commands, and then esbuild would send the results back to you without touching disk. Would that be sufficient for this?
I'm intending for esbuild to be a batch process of sorts. That's why it allows you to pass more than one file on the command line, so that many files can all be processed in one go. Is this not something that works for other bundlers or dev systems such as vite?
vite is a dev server, and it compiles source files on-demand when the browser sends in HTTP request for native ES module imports. So by nature it compiles every file in isolation without the possibility for batching.
I've been thinking a lot about a streaming protocol over stdin/stdout that would let you feed esbuild commands, and then esbuild would send the results back to you without touching disk. Would that be sufficient for this?
The limitation of that is you have to feed the esbuild
process everything in one go - and as mentioned above, vite
's model is by nature at odds with that. Even in the context of a bundler like Rollup, the transform for each source file is also isolated (every transform call can be async). So I imagine it would still incur the cost of a new child process on every transform.
This is the API I imagine would be useful:
const { startCompilerProcess } = require('esbuild')
;(async () => {
const compiler = await startCompilerProcess()
// under the hood, sends the buffer to esbuild for processing and sends back processed buffer
// this can be called as many times as necessary without starting new child processes
const compiled = await compiler.compile(srcBuffer, options).toString()
compiler.dispose() // explicitly stop the child process (or auto exit on main process exit)
})()
I'm not very familiar with Go, but I imagine it should be a thin extra layer that doesn't affect how esbuild
core works.
Can child_process.spawn
and stdin
\`stdoutsupport resolve that issue without an additional API surface on
esbuildside? Would it create a new
esbuild` process on every call in that case?
@CyberAP I think the current binary just terminates itself when the processing is complete.
What I do think esbuild can benefit Vue, and other JS projects in general, is exposing a way to consume esbuild from JavaScript without the overhead of starting a child process and reading/writing to disk for every file transform. An API that starts a long-living child process that can receive/send data from the Node.js main process. This allows other bundlers or dev systems (e.g. vite) to leverage esbuild as the underlying sub bundler / TS/JSX transformer / minifier much more efficiently.
This, to me, sounds like having an RPC server on the esbuild side and having js clients open a persistent connection to it. To do that, esbuild should first implement an API-based approach which I guess is not how it is designed right now.
@yyx990803 I just added an API similar to what you proposed:
(async () => {
const jsx = `
import * as React from 'react'
import * as ReactDOM from 'react-dom'
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
`
// Start the esbuild child process once
const esbuild = require('esbuild')
const service = await esbuild.startService()
// This can be called many times without the overhead of starting a service
const { js } = await service.transform(jsx, { loader: 'jsx' })
console.log(js)
// The child process can be explicitly killed when it's no longer needed
service.stop()
})()
It should now be possible to make use of esbuild's single-file transform ability from JavaScript as a library without the overhead of process creation. The complete API is documented in the TypeScript type definitions.
@evanw fantastic! Thank you so much for the fast implementation.
Was this API sufficient to address this issue on the esbuild side? I assume there's still more work to fully integrate this API into the Vue ecosystem, but I don't think this issue is the appropriate place to track that work.
Yes, already integrated in vite. I think this can be closed - Thanks again!
On Thu, May 7, 2020 at 6:46 AM Evan Wallace notifications@github.com
wrote:
Was this API sufficient to address this issue on the esbuild side? I
assume there's still more work to fully integrate this API into the Vue
ecosystem, but I don't think this issue is the appropriate place to track
that work.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/evanw/esbuild/issues/75#issuecomment-625177433, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/AADZ6XWD6HMJRDIOHFZQXQDRQKGPDANCNFSM4MNGFIUA
.
Most helpful comment
@yyx990803 I just added an API similar to what you proposed:
It should now be possible to make use of esbuild's single-file transform ability from JavaScript as a library without the overhead of process creation. The complete API is documented in the TypeScript type definitions.