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.

Bluesky
Threads
Twitter / X
Mastodon
Instagram

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.

My latest articles

Focal point blocking for XR media

Planning out a linear VR experience requires thinking about where the viewers attention might be. Thinking about the focal points…

Designing immersive experiences

In traditional cinema, TV, or even the more modern phone screen, there’s limited screen real-estate. But removing that limitation creates a design problem…

The future is not prompt engineered

Let’s not pretend the importance of prompt engineering is ubiquitous. The most prevalent power of generative AI is in the way it adapts to us, not the other way around…

Author:

Date:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.