A Basic Custom esbuild Copy Plugin
Recently, in a project using esbuild, I found myself wanting to copy a single static file from my working folder into my dist folder with each build.
In searching online, I found a few plugins that supported copying files (namely esbuild-plugin-copy and esbuild-copy-static-files), but the problem I ran into was making them work with only one file in a directory of multiple files. Perhaps it was a lack of knowledge on my part, but I could only figure out how to tell it to copy all files in a folder, not just one single file.
So, I wrote a plugin myself. It’s super basic and specific to my needs, but it should be easily adaptable if you have a similar requirement.
The plugin code
Below is all of the plugin’s code, which is hardcoded to simply copy the file manifest.json from my projects root directory.
This was a requirement for me because the project is a plugin for Obsidian, and in that ecosystem, plugins require a manifest file in the final output. However, as part of the plugin submission process, the manifest file also needs to be in the root of your project directory, which means I couldn’t just put it into another folder and copy it from there.
import fs from 'fs';
const copyManifestPlugin = () => ({
name: 'copy-manifest-plugin',
setup(build) {
build.onEnd(async () => {
try {
fs.cpSync('./manifest.json', './dist/manifest.json');
} catch (e) {
console.error('Failed to copy file:', e);
}
});
},
});
Note: When I initially published this post I had used fs.copyFileSync above, but since then I’ve found that fs.copyFileSync doesn’t work in GitHub actions (Well, mine anyway), but fs.cpSync does. So use that.
Using the plugin
To use the above code, I wrote it directly in my esbuild.config.mjs, however, you could also put it in a separate file and import it in.
To call the plugin on build, it’s just like calling any other plugin – but since it’s functionality is hard coded, it has no settings.
esbuild.build({
...
plugins: [
...
copyManifestPlugin(),
],
})
That’s it!
In many instances the existing copy plugins that are out there will do just fine, however, if you find yourself with a specific use case that doesn’t quite fit, hopefully this article showed you that esbuild plugins can be pretty easy.
Thanks…
I also dissect and speculate on design and development.
Digging into subtle details and implications, and exploring broad perspectives and potential paradigm shifts.
Check out my conceptual articles on Substack or find my latest below.
You can also find me on Threads, Bluesky, Mastodon, or X for more diverse posts about ongoing projects.
Leave a Reply