Skip to content

Commit

Permalink
Fix interop with bundled CJS dependencies (#199)
Browse files Browse the repository at this point in the history
* Refactor

* Add workaround for __filename and __dirname not being defined

We bundle several CJS deps but the top-level format is ESM. Unfortunately esbuild does not handle converting `__filename` and `__dirname` for us so we have to patch them after build.

* Update lockfile

* Add global require

* Simplify

Now that we define a top-level require constant we no longer need to patch the `__require` esbuild function to indirectly use it for dynamic requires

* Fix CS

* Rename plugin

* Update changelog
  • Loading branch information
thecrypticace committed Aug 10, 2023
1 parent 4b768f7 commit 985302f
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 26 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Expand Up @@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- Nothing yet!
### Fixed

- Fix intertop with bundled CJS dependencies ([#199](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/pull/199))

## [0.5.1] - 2023-08-10

Expand Down
40 changes: 16 additions & 24 deletions build.mjs
@@ -1,7 +1,7 @@
import esbuild from 'esbuild'
import path from 'path'
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
import esbuild from 'esbuild'

/**
* @returns {import('esbuild').Plugin}
Expand Down Expand Up @@ -33,30 +33,27 @@ function patchRecast() {
/**
* @returns {import('esbuild').Plugin}
*/
function patchDynamicRequires() {
return {
name: 'patch-dynamic-requires',
function patchCjsInterop() {
return {
name: 'patch-cjs-interop',
setup(build) {
build.onEnd(async () => {
let outfile = './dist/index.mjs'

let content = await fs.promises.readFile(outfile)

// Prepend `createRequire`
content = `import {createRequire} from 'module';\n${content}`
let code = [
`import {createRequire} from 'module'`,
`import {dirname as __global__dirname__} from 'path'`,

// Replace dynamic require error with createRequire
// unminified version
content = content.replace(
`throw Error('Dynamic require of "' + x + '" is not supported');`,
`return createRequire(import.meta.url).apply(this, arguments);`,
)
// CJS interop fixes
`const require=createRequire(import.meta.url)`,
`const __filename=new URL(import.meta.url).pathname`,
`const __dirname=__global__dirname__(__filename)`,
]

// minified version
content = content.replace(
`throw Error('Dynamic require of "'+e+'" is not supported')`,
`return createRequire(import.meta.url).apply(this,arguments)`,
)
content = `${code.join('\n')}\n${content}`

fs.promises.writeFile(outfile, content)
})
Expand All @@ -81,7 +78,6 @@ function copyTypes() {
}
}


const __dirname = path.dirname(fileURLToPath(import.meta.url))

let context = await esbuild.context({
Expand All @@ -92,12 +88,8 @@ let context = await esbuild.context({
minify: process.argv.includes('--minify'),
entryPoints: [path.resolve(__dirname, './src/index.js')],
outfile: path.resolve(__dirname, './dist/index.mjs'),
format: "esm",
plugins: [
patchRecast(),
patchDynamicRequires(),
copyTypes(),
],
format: 'esm',
plugins: [patchRecast(), patchCjsInterop(), copyTypes()],
})

await context.rebuild()
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 985302f

Please sign in to comment.