evanw / esbuild

An extremely fast bundler for the web
https://esbuild.github.io/
MIT License
37.62k stars 1.11k forks source link

Control module bundle dividers #3627

Open jmldavis opened 5 months ago

jmldavis commented 5 months ago

I'm trying to use ESBuild to bundle JS files and to take the output and manipulate it.

Bundling gives me something like this:

// filea.js
console.log('code from file A')

// fileb.js
console.log('code from file B')

What I want is to be able to get the processed contents of these 2 files out of the bundle file.

I understand from https://github.com/evanw/esbuild/issues/2751 that this comment format is likely to stay as-is, but still I have a perhaps superstitious fear of basing a crucial bit of logic on a comment format that I don't control. I wonder whether there is or could be a way to customise the format myself so that I can be confident I can write a regex for it. Or is there a way to hook into ESBuild's process just before it does this concatenation of files?

Thank you!

hyrious commented 5 months ago

If you want to get all source files that are referenced in the bundle, you can enable metafile and read the Object.keys(metafile.inputs) without using a regex. Or enable sourcemap and parse the mappings.

If your second purpose is to get 'compiled' contents in the bundle by slicing code between these comments, it is not always correct because esbuild may re-order contents in the same file during the scope hoisting process. Which is to say, sources in the same file may not finally become continuous contents in the bundle.

jmldavis commented 5 months ago

Thanks for the quick reply @hyrious My purpose lies with extracting the compiled code.

Just so I can be sure that I understand your second paragraph... Are you saying that given e.g. the following input files

fileA.js

var message = "Hello"
console.log(message)

fileB.js

var a = true
var b = false
if (a)
{
console.log("A is true")
}

you could end up with a bundle like this:

var message = "Hello"
var a = true

// fileA.js
console.log(message)

// fileB.js
var b = false
if (a)
{
console.log("A is true")
}

If this is correct (i.e. the principle, not the exact code example) then could you explain under what conditions this would happen? If I've misunderstood could you illustrate what you mean with a code example?

Thanks again.