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

[Feature] Config file #39

Closed
renanbatel opened this issue Feb 26, 2020 · 11 comments
Closed

[Feature] Config file #39

renanbatel opened this issue Feb 26, 2020 · 11 comments

Comments

@renanbatel
Copy link

Just an obvious request, it would be nice if we could use a config file for defining the bundler options/parameters, like we have in other JavaScript bundlers (webpack.config.js, rollup.config.js, etc).

And nice work man, I'm looking forward for this project!

Regards.

@evanw
Copy link
Owner

evanw commented May 3, 2020

What's the reason for having a config file? I'm asking because at face value it seems like just a request for an alternate syntax other than command-line flags, but you might have another reason. I want to make sure I understand what problem you wanted to solve.

For example, a feature of other JavaScript bundlers is that the config file is JavaScript code, and can use computation to generate the configuration. However esbuild is written in Go and it wouldn't be natural for it to execute JavaScript code. The natural form of a config file for esbuild would be more like JSON, which would make it essentially an alternate syntax for the command-line flags esbuild currently uses. That might not be what you're looking for.

If this is what you're trying to do, one way to get around this limitation is to write some JavaScript code that invokes esbuild instead of trying to get esbuild to invoke your config file. Doing this was recently made easier by the JavaScript API that was added in #77.

Say for example that you wanted a config file where the minify setting depends on an environment variable. A possible config file for esbuild could then look like this:

const { build } = require('esbuild')

const options = {
  entryPoints: ['./example.ts'],
  minify: process.env.NODE_ENV === 'production',
  bundle: true,
  outfile: './example.min.js',
}

build(options).catch(err => {
  process.stderr.write(err.stderr)
  process.exit(1)
})

You would then just invoke this script directly to do the build. Could that fit what you're looking for?

@renanbatel
Copy link
Author

renanbatel commented May 4, 2020

Yes, I wasn't request anything more than an alternate syntax for it, it's more convenient to have a configuration file rather than managing command-line flags. A lot of command-line programs offer this option, like TypeScript compiler. I don't know how you'd manage your compilation commands in a JS project, but the common way is to have it as scripts in package.json, It's not very friendly to manage command-line flags in package.json, especially if this tool starts to get more complex and to offer more and more options (like tsc itself). So it would be more convenient to have a specif configuration file (.esbuildrc for example) to manage these options.

But as you showed, the new API can already solve this problem, and you can even do it in a programmatic way. So in my case, this alternate syntax isn't necessary anymore as I can manage the compiler parameters in a proper file.

@evanw evanw closed this as completed in e7584dc May 5, 2020
@bpierre
Copy link

bpierre commented Aug 29, 2020

I made a small utility that addresses this separately, feedback is welcome! https://github.com/bpierre/esbuild-config

@evanw Do you think it is fair to assume the parameters syntax will stay the same, even as new ones get added?

@evanw
Copy link
Owner

evanw commented Aug 29, 2020

I made a small utility that addresses this separately, feedback is welcome! https://github.com/bpierre/esbuild-config

FYI the design of esbuild is to have config files be done using the JavaScript API, like this:

const { build } = require('esbuild')

build({
  entryPoints: ['./src/main.ts'],
  outfile: './dist/main.js',
  minify: true,
  bundle: true,
}).catch(() => process.exit(1))

So no external package is needed. It's fine if you want to make an external package, I'm just pointing out that one isn't necessary because support for config files is already built in.

@evanw Do you think it is fair to assume the parameters syntax will stay the same, even as new ones get added?

My intent is to version everything in esbuild under semver. I'm still working up to the MVP I have in mind so haven't hit 1.0 yet, but I'm using patch version bumps for backwards-compatible changes and minor version bumps for backwards-incompatible changes. All aspects of the API (the CLI, the JavaScript API, and the Go API) follow semver like this. So within the same major and minor versions, all command-line flag changes should be backwards-compatible (i.e. only new flags will be added).

@bpierre
Copy link

bpierre commented Aug 29, 2020

So no external package is needed. It's fine if you want to make an external package, I'm just pointing out that one isn't necessary because support for config files is already built in.

That’s a good point, I completely agree and I think the project README was not explicit enough in that regard. I updated it to clarify that esbuild alone does support config files: https://github.com/bpierre/esbuild-config#why

My intent is to version everything in esbuild under semver. I'm still working up to the MVP I have in mind so haven't hit 1.0 yet, but I'm using patch version bumps for backwards-compatible changes and minor version bumps for backwards-incompatible changes. All aspects of the API (the CLI, the JavaScript API, and the Go API) follow semver like this. So within the same major and minor versions, all command-line flag changes should be backwards-compatible (i.e. only new flags will be added).

Awesome, thanks!

PS: This is mostly a fun little project I made while learning Rust, I am conscious that it is not extremely useful since the Node API exists. Please let me know if using this name is a problem, now or at any point the future, and I’ll change it to something else.

@mhart
Copy link

mhart commented Sep 18, 2020

This would be useful for using esbuild outside a pure bundling context.

For example, I'm looking to replace ts-node in my stack, but packages like https://github.com/egoist/esbuild-register need to infer how esbuild will be run (they end up trying to parse tsconfig to get some of these values, but that can fail because esbuild's targets aren't the same as typescript's). See:

https://github.com/egoist/esbuild-register/blob/14a6288f09df8f08b415fe5b8ec24577cf371c41/src/node.ts#L30-L38

I'm considering forking and using env vars (or possibly an esbuild section in .tsconfig, which is what ts-node does), but ideally there'd be a sanctioned way of doing this 🙏

@emigre
Copy link

emigre commented Sep 27, 2021

I have not benchmarked this but I've noticed that a Node.js script running esbuild, as proposed, seems slightly slower than running esbuild via the CLI. But running the CLI via package.json command has the drawback of having to keep there a long list of command-line flags, which is less convenient. A JSON config file might perhaps provide the best of both options.

EDIT: To be honest, I checked this while running a really small project, which is probably not a good metric. The difference for bigger ones might be completely unnoticeable. And in this small project I'm talking just about a few hundred milliseconds more. So not a big deal I imagine.

@scottmas
Copy link

scottmas commented Nov 25, 2021

FWIW, here's a snippet (with yargs-parser dependency) that lets you pass arbitrary options to your custom build file:

import esbuild from "esbuild";
import yargs from "yargs-parser";
const { _, ...argv } = yargs(process.argv.slice(2)) || {};

esbuild.build({
  entryPoints: ["./src/index.ts"],
  outfile: "dist/index.js",
  bundle: true,
  ...argv,
});

@bpierre
Copy link

bpierre commented Nov 25, 2021

@emigre the Node startup latency is precisely why I used Rust rather than JS to write esbuild-config 🙂

@emigre
Copy link

emigre commented Nov 25, 2021

Oh! Nice!

@jeremychone
Copy link

@bpierre Thanks you for the great work on esbuild-config. Config file driven command line can greatly simplify big application build systems.

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

7 participants