Skip to content
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

[question]: how to effeciently merge sourcemap #847

Closed
hardfist opened this issue Feb 19, 2021 · 8 comments
Closed

[question]: how to effeciently merge sourcemap #847

hardfist opened this issue Feb 19, 2021 · 8 comments

Comments

@hardfist
Copy link
Contributor

It seems that esbuild's sourcemap merging operation is so fast, I need the same functionality to manual merge sourcemap using https://www.npmjs.com/package/merge-source-map, but it's too slow to put into production(server side bundle),I wonder whether esbuild could export its merge sourcemap method or exports something like rollup's renderChunk hooks, which could automatic effeiciently merge-source for our code.

@evanw
Copy link
Owner

evanw commented Feb 19, 2021

I'm not planning on exporting esbuild's internal libraries for external use. I'm not sure what you mean by merging exactly, but one way of joining multiple JavaScript files together with esbuild is to bundle an entry point file with a list of imports:

import "./file1.js"
import "./file2.js"
import "./file3.js"

If you do that and these files have associated source maps, the source maps will all be merged into one during bundling.

@hardfist
Copy link
Contributor Author

hardfist commented Feb 22, 2021

what i mean is that i need to do some post transform using tsc to transform esbuild bundled code to es5, then I need to combine the sourcemap generated by esbuild and sourcemap generated by tsc manually, when I use rollup, I just need to return code&mapping generated by tsc in renderChunk hook in rollup ,which combines sourcemap automatically by rollup itself. but esbuild doesn't provide renderChunk currently, and the js tools(like https://www.npmjs.com/package/merge-source-map) to merge source-map is kind of slow.

@evanw
Copy link
Owner

evanw commented Feb 22, 2021

If an input file into esbuild references a source map, it should automatically be combined into the final output source map. This should already be the case for files processed by the TypeScript compiler.

You need to use a //# sourceMappingURL= comment in the input file to trigger this behavior, and it can either be a file name or a base64-encoded data URL. If you are generating the source map by manually calling the TypeScript compiler API in a plugin or just before esbuild runs somehow, you can append it to the JavaScript code by generating a base64-encoded data URL source map comment. The Svelte example plugin is an example of how to do this.

@hardfist
Copy link
Contributor Author

hardfist commented Feb 22, 2021

i need to do transform after esbuild bundle not before bundle,so plugin not work for this case,but maybe i can do another bundle just to handle sourcemap merging using esbuild, if esbuild could support something like renderChunk, it would be much easier to do this.

@evanw
Copy link
Owner

evanw commented Feb 22, 2021

I'm planning to support something like renderChunk eventually. I don't think that will help though. If you're running TypeScript on esbuild's output then it would be TypeScript's job to update the source map if it modifies the code, not esbuild's. It looks like that isn't implemented yet: microsoft/TypeScript#13944. You could potentially try running TypeScript before running esbuild instead of running it afterward.

@hardfist
Copy link
Contributor Author

running typescript before esbuild will much slower than after bundle, because it needs to transform all files even thou the files are not used in the final bundle.

@ggoodman
Copy link

I'm not sure if this will help for your use-case @hardfist, but there are some helpers in SourceMapTree that are designed to represent a hierarchy of source-mapped files.

A Source is a leaf node in such a system and a Link is the result of a transformation of one or more Source files or Links. The LazyLink is designed to allow you to defer the expensive source map flattening operation until you actually need it.

@evanw
Copy link
Owner

evanw commented Feb 25, 2021

I'm going to close this since this is out of scope for esbuild. I assume it should be pretty straightforward to make a faster library that does this, either in JavaScript with techniques like this or in WebAssembly with C/Rust. In either case you probably don't want to base it on the Go code in this repo because Go's runtime library is really bulky and is overkill for such a simple task (you would probably end up with a multi-megabyte library). Doing this in JavaScript or in C/Rust would be a better fit for a small utility library like that IMO.

Edit: JavaScript libraries for manipulating source maps don't have to be slow. The link above explains this in more detail. I also have an independently-implemented high-performance source map parser in my source map visualization tool if you need some inspiration. It's not separated out into its own library but it's more proof that these JavaScript libraries can be fast. It reads mappings using charCodeAt and stores them in an Int32Array for performance.

@evanw evanw closed this as completed Feb 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants