Open dalechyn opened 11 months ago
This is the workaround I'm currently using:
// banner: {
// js: '"use client";',
// },
// Hack to avoid multiple `use client` directives in single file instead of using banner.
// Delete when implemented https://github.com/evanw/esbuild/issues/3517
async onSuccess() {
// recursively go through each js file in dist and add "use client" to the top
const distDir = path.join(__dirname, 'dist')
const files = await fs.readdir(distDir)
async function processFilesRecursively(dir: string) {
// Read dirents of the current folder
const dirents = await fs.readdir(dir, { withFileTypes: true })
const promises = dirents.map(async (dirent) => {
const filePath = dirent.path + '/' + dirent.name
if (dirent.isDirectory()) return processFilesRecursively(filePath)
if (dirent.name.endsWith('.js')) {
const fileContents = await fs.readFile(filePath, 'utf8')
const newFileContents = `'use client'\n${fileContents
.replaceAll('"use client"', '')
.replaceAll("'use client'", '')}`
await fs.writeFile(filePath, newFileContents)
}
})
return Promise.all(promises.flat())
}
await processFilesRecursively(distDir)
},
As of now,
esbuild
inserts a banner before every built file even if it's bundled within a single chunk.In my case, I insert the
use client
directive, and it's being inserted multiple times within a single chunk, which leads to the next error when my package is used in nextjs:My proposal is to extend the
BannerOrFooter
to accept a new optionsingle: boolean
which would default tofalse
to ensure backwards compatibility, yet that would insert a banner or a footer only once in a compiled file.