-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Add support for developers to replace the default esbuild configuration #9235
Conversation
3b4b976
to
4fa28c0
Compare
this would definitely work for the use case I mentioned in #8406 - though I wonder if there isn't also a simpler way to solve certain use-cases without the need for an escape hatch. I've got another separate project that doesn't involve a monorepo per se - but it does use the tsconfig paths configuration pretty heavily to avoid What we're doing in our workaround in both projects is effectively making the keystone esbuild options respect the typescript config's The ability to completely customize the esbuild configuration would be useful, but it seems like it would introduce several new ways for devs to trip themselves up, especially if the default esbuild configuration were to be changed in any way in the future (i.e. if the output path/format/etc changed at all). |
did some experimenting locally in our monorepo with // packages/core/src/lib/esbuild.ts
import { loadConfig } from "tsconfig-paths";
import { type BuildOptions } from 'esbuild'
function getPathsMatcher(cwd: string): RegExp | null {
try {
const pathsResult = loadConfig(cwd);
if (pathsResult.resultType !== 'success') return null;
const pathMatchers = Object.keys(tsConfigPaths.paths).map((path) => path.replace(/\*/, '.*'));
if (!pathMatchers.length) return null;
return new RegExp(`^(?:${pathMatchers.join('|')})$`);
} catch {
return null;
}
}
export function getEsbuildConfig (cwd: string): BuildOptions {
const pathMatcher = getPathMatcher(cwd);
return {
entryPoints: ['./keystone'],
// ...rest of fields
plugins: [
{
name: 'external-node_modules',
setup (build) {
build.onResolve(
{
// don't bundle anything that is NOT a relative import
// WARNING: we can't use a negative lookahead/lookbehind because esbuild uses Go
filter: /(?:^[^.])|(?:^\.[^/.])|(?:^\.\.[^/])/,
},
({ path }) => {
if (pathMatcher?.test(path)) return;
return { external: true, path }
}
)
},
},
],
}
} |
Does it help use path Aliases in custom admin pages as well?
if #9235 (comment) gets included, we may not even need the custom esbuild config, but we can still provide the support to load custom config |
since admin pages are compliled directly with next.js, I think path aliases in admin pages should work out of the box already since Next.js supports it. |
I tend to agree. However, apart from import paths, I would like to be able to change // esbuild.config.js
export default function (defaultValues) {
return {
...defaultValues,
entryPoints: ['./src/keystone'],
}
} The |
@marekryb that's a solid suggestion, I'll update |
4fa28c0
to
adcc534
Compare
@marekryb @acburdine @gautamsi I have added support based on @marekryb's suggestion, and additionally added support for Typescript, now you can use either of:
This was easy to add, and I couldn't foresee any reason why we shouldn't. |
@dcousens i think this function approach makes sense - can always make an example showing how to implement something like the tsconfig-paths utility using the custom options file 🙂 |
I'm happy for the scope of that example to be expanded on separately to this pull request, as the example already added shows how to use the functionality generally. |
I'm trying to get absolute paths working with Keystone. I came across this PR, and was hopeful it would work. I've tried setting up // esbuild.keystone.ts
import { loadConfig } from 'tsconfig-paths'
import { type BuildOptions } from 'esbuild'
function getPathsMatcher(cwd?: string): RegExp | null {
try {
const pathsResult = loadConfig(cwd)
if (pathsResult.resultType !== 'success') return null
const pathMatchers = Object.keys(pathsResult.paths).map(path => path.replace(/\*/, '.*'))
if (!pathMatchers.length) return null
return new RegExp(`^(?:${pathMatchers.join('|')})$`)
} catch {
return null
}
}
export default function (defaults: BuildOptions) {
const pathMatcher = getPathsMatcher(defaults.absWorkingDir)
return {
...defaults,
plugins: [
{
name: 'external-node_modules',
setup(build: any) {
build.onResolve(
{
// don't bundle anything that is NOT a relative import
// WARNING: we can't use a negative lookahead/lookbehind because esbuild uses Go
filter: /(?:^[^.])|(?:^\.[^/.])|(?:^\.\.[^/])/
},
({ path }: { path: string }) => {
if (pathMatcher?.test(path)) return
return { external: true, path }
}
)
}
}
]
}
} It does work for most of my code, but not for the custom Keystone admin pages, which seems explained by @gautamsi 's comment above. Given PR#9186 is not yet merged, is there any other known work around to get absolute paths working with custom Keystone admin pages? |
@asgeo1 I added info about temp package while we wait for merging the app router part. I am already using with a large project which also includes heavily customized pages, all works good. |
This pull request addresses the problem in #8406 where the default
esbuild
configuration simply cannot account for how developers are integratingkeystone-6
into their projects, and thus, rather than relying on patching a package, maybe we can provide an appropriate escape hatch.Feedback welcome before merge