-
Notifications
You must be signed in to change notification settings - Fork 144
-
Notifications
You must be signed in to change notification settings - Fork 144
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
A config for esbuild #8
Comments
Happy to leave the discussion open for now. I think the part that feels different to me is that esbuild's config is more like an actual program that uses esbuild as an API. Perhaps that's a subtle difference, but it feels distinct to me. When you literally have to parse your own ARGV, then it's clearly a different territory to rollup.config.js or webpack.config.js. |
Does If so, a possible compromise could be a file with only require("esbuild").build({
entryPoints: ["app/javascript/application.js"],
bundle: true,
outdir: "app/assets/builds",
plugins: [],
}).catch(() => process.exit(1)); This way, you have a clear place to know that (1) plugins exist, (2) where to put them, (3) a place to put other configuration for |
@t27duck It does not. You have to implement it yourself, like afomera did. |
what about write two files: // esbuild.config.js
const config = {
entryPoints: ["app/javascript/application.js"],
bundle: true,
outdir: "app/assets/builds",
plugins: [],
}
export const config // esbuild.node.js
import { config } from './esbuild.config.js'
// merge default plugins just like glob import for stimulusjs autoloader
require("esbuild").build(config).catch(() => process.exit(1)); |
Yeah, I'd like to use esbuild out of the box. We do support other bundlers. If esbuild decides to implement a way to pass in a config, great, we can use that. Otherwise, it'll be an exercise for the reader. |
We were facing a similar question and wanted to use the built in minifcation of esbuild. So we tried to make good use of the fact you can use the arguments
If you write the rake tasks by yourself the gem can be removed easily after the installation and setup phase.
const path = require('path')
const svgrPlugin = require('esbuild-plugin-svgr');
require("esbuild").build({
entryPoints: ["application.js"],
bundle: true,
outdir: path.join(process.cwd(), "app/assets/builds"),
absWorkingDir: path.join(process.cwd(), "app/javascript"),
watch: process.argv.includes("--watch"),
plugins: [svgrPlugin()],
minify: process.argv.includes("--minify")
}).catch(() => process.exit(1)) changed "scripts": {
"build": "node esbuild.config.js"
}
web: bin/rails server
js: yarn build --watch last we added namespace :javascript do
desc 'Build your JavaScript bundle'
task :build do
command = 'yarn install && yarn build'
command += ' --minify' if Rails.env.production?
raise 'Ensure yarn is installed and `yarn build` runs without errors' unless system command
end
end
Rake::Task["assets:precompile"].enhance(["javascript:build"]) Did the trick for us to watch in development and minify in production with one |
Hi, it seems that @krokodaxl 's config works great with esbuild 0.16.x. But if you upgrade to esbuild 0.17.x, compile fails because "watch" option is removed. See here: https://github.com/evanw/esbuild/blob/main/CHANGELOG.md#0170 "...This change removes the incremental and watch options as well as the serve() method, and introduces a new context() method..." |
I migrated my code to this: const path = require('path')
require("esbuild").context({
entryPoints: ["application.js"],
bundle: true,
sourcemap: true,
publicPath: 'assets',
outdir: path.join(process.cwd(), "app/assets/builds"),
absWorkingDir: path.join(process.cwd(), "app/javascript"),
plugins: [],
minify: process.argv.includes("--minify")
}).then(context => {
if (process.argv.includes("--watch")) {
// Enable watch mode
context.watch()
} else {
// Build once and exit if not in watch mode
context.rebuild().then(result => {
context.dispose()
})
}
}).catch(() => process.exit(1)) |
@salimhb Thx! |
Thnx! |
@salimhb This config works great, but I'm having issues with esbuild not watching newly created JS files. It seems to only watch the files that existed when it was first run. To pick up the new files |
@interphased I'm not having an issue with watch mode. I'm not using docker. I'm running node locally using
esbuild 0.17.17 has a fix for an edge case, where watch doesn't work. I don't know if this is the problem you are facing. Perhaps also upgrade to the latest version. I hope this helps. |
@salimhb Thanks for checking and providing a possible solution. I tried updating In the end, I implemented Example: if (process.argv.includes('--watch')) {
(async () => {
chokidar.watch('my-watch-directory').on('all', async (_, p) => {
console.log(`Changes were detected in: ${p}`);
console.log('Rebuilding...');
await ctx.rebuild();
});
})();
} else {
await ctx.rebuild().then(() => {
ctx.dispose();
});
} |
How are folks handling static files that just need to get copied over? For example, I'm midway through a move from webpacker to webpack to esbuild (had to go step-by-step to try and stay sane), and have this: const esbuild = require("esbuild");
import { sassPlugin } from "esbuild-sass-plugin";
import postcss from "postcss";
import autoprefixer from "autoprefixer";
const postcssPresetEnv = require("postcss-preset-env");
import tailwindcss from "tailwindcss";
const tailwindConfig = require("./tailwind.config.js");
const watch = process.argv.includes("--watch");
const args = {
entryPoints: [
// "./app/webpacker/packs/application.js",
"./app/webpacker/packs/stylesheets.scss",
// "./app/webpacker/packs/admin.js",
"./app/webpacker/packs/admin.scss",
],
outdir: "./app/assets/builds",
bundle: true,
metafile: true,
loader: {
".js": "jsx",
".png": "file",
".woff": "file",
".woff2": "file",
".eot": "file",
".ttf": "file",
".svg": "file",
".gif": "file",
".jpg": "file",
},
plugins: [
sassPlugin({
async transform(source, resolveDir) {
const { css } = await postcss([tailwindcss(tailwindConfig), autoprefixer, postcssPresetEnv]).process(source, {
from: undefined,
});
return css;
},
}),
],
};
let ctx;
if (watch) {
args.minify = false;
ctx = await esbuild.context(args);
await ctx.watch();
console.log("watching...");
} else {
args.minify = true;
ctx = await esbuild.build(args);
console.log("build successful");
} And one of the (several) issues I'm facing is porting over Apologies if this is not a great forum for this question, but finding good sources of info on these topics is fairly challenging. Hope this adds a data point to the kinds of struggles folks are experiencing trying to get migrated to the latest practices. |
We are doing it like this:
|
👋
After using esbuild for a few days via the esbuild-rails gem and now this gem, one thing I've found myself needing is to make an esbuild.config.js file across all of my applications.
I realize from the other gem issues one concern is that it'd turn into a mini webpacker, but config files are fairly common across JS packages and even the two other bundlers in this gem have config files so I found it super odd that esbuild does not have one generating out of the box.
Additionally, it helps ease the burden of where do I add a new config/plugin when I want to use it with esbuild, the end user then has to go create a config file and update their build script to use it, which doesn't feel quite well.
I've been enjoying having my esbuild.config.js file in the root level (Same as gemfile / rollup.config.js etc etc). I know in rails/esbuild-rails#2 you mentioned it may be better to do documentation with a link to learning where to make a config file, but that feels like a very poor developer UX when its fairly straightforward to support this basic of a config file... and it basically matches the level of configuration the rollup.config.js is.
This is of course basically what @jasoncharnes had in esbuild-rails#2. You could drop the watch function / arg down in the build but you loose the output and honestly having the build finished output is quite nice to know it... well finished.
From this point a developer can customize their esbuild system how they'd like, adding plugins to load whatever they need and so forth. It was a fair bit to explain how to make this file in a screencast I recorded, and feels like a point where someone will easily get stuck.
I hope you'll reconsider!
The text was updated successfully, but these errors were encountered: