-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
feat: injectDts and codegenDir #9952
feat: injectDts and codegenDir #9952
Conversation
🦋 Changeset detectedLatest commit: faa8f43 The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
) { | ||
logger.warn( | ||
null, | ||
`The integration ${integration.name} is overriding a core dts: ${dts.filename}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was perfectly ok with the name until I read this error. Should we call them "ambient declarations", which is what they are, instead of "dts", which is a simplification of their extension?
I imagine a user would not know what a "core dts" is. Searching for "core dts" or "dts file" also doesn't help since there is a .dts
extension. Searching for "ambient declarations" on the other hand immediately directs to TypeScript.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm open to any naming! All the messages are really WIP and can be improved a lot for sure! (i'll focus on that in a 2nd phase, with documentation) For reference, @nuxt/kit
has a addTypeTemplate
utility
"astro:config:setup": ({ codegenDir }) => { | ||
const filePath = new URL("./data.json", codegenDir) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason that we expose codegenDir
here? I think we'd want to "own" this, so not allowing or encouraging integrations to put files here. In the future if Astro wants to write a new file/folder here it could conflict with other integrations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I just realized that injectDts
writes an exact <name>.d.ts
file inside .astro
, so this would already be an issue 🤔 I thought the types are all concat into a single .astro/types.d.ts
. I'm not sure if that's also possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About the codegenDir
being exposed to integrations: I think it's useful to have it because integrations are going to use it anyway (eg. @astrojs/db
or @keystatic/astro
). If we want to avoid conflicts, I think we can define some conventions to make all of this safe. For example, we could have this structure:
.astro
astro.d.ts // reference any other registered types
astro
content.d.ts
env.d.ts // for example for the types rfc
integrations
whatever
some-types.d.ts
If we go that way, that would make things safer by ensuring each integration has its own space, not conflicting with core. In that case, codegenDir
would be different for any integration, basically ${root}/.astro/integrations/${integrationName}
and injectDts
would then inject in this folder.
About injectDts
and exact .d.ts files, this is actually on purpose. I think it's better mainly for debuggability. Like, I wouldn't want to debug my injected types, lost somewhere after 2k lines of astro content and before 5 other integrations. Also, it can be unsafe to have them all in one file if there are some name conflicts, eg.
// injected by integration a
type Test = 'a'
declare module 'virtual:a' {
export const a: Test;
}
// injected by integration b
type Test = 'b'
declare module 'virtual:b' {
export const b: Test;
}
Test
would conflict here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the late reply, I think if we want to have codegenDir
be .astro
, then perhaps we should rename it to tempDir
/astroDir
/tempAstroDir
/dotAstroDir
/cacheDir
since it has multiple uses. Otherwise I think reading config.root
would also work.
I don't think we need to take measures to avoid name conflicts for now, but perhaps putting all of the types from injectDts
inside .astro/types/*
should be enough, and document that integrations should use a name unique to its integration.
Good point about the injectDts
conflict, I didn't thought of that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cacheDir
is already taken (see docs). tbh I feel like internally we could call this dotAstroDir
and for integrations still codegenDir
because if we head into the direction of my proposal, such URL will not technically point to .astro
. I am going to post a new comment with the updated proposal based on all the reviews
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just putting a "Docs Block" here because there still seems to be a lot of discussion going on in the changeset, which means I'm not sure that stuff has been resolved here yet. Ping me when this content is agreed-upon and finalized by everyone, then I'll review this with the docs PR together to make sure they align!
Thanks everyone for the amazing feedback! Based on all those, here is a proposal that I think addresses your concerns and reviews.
|
I'm closing this PR in favor of a proper RFC (future, once |
Changes
codegenDir
injectDts
codegenDir
injectDts
tsconfck
This PR initially meant to tackle withastro/roadmap#826 but it proved too difficult for me. I decided to reduce the PR content so it does not handle the autogenerated tsconfig. We'll have to discuss this later on, because it's really tricky!
Codegen seems to become a quite common usecase for integrations (for example:
@astrojs/db
,astro-env
,@keystatic/astro
,astro-typed-api
...). Let's look at 2 cases:Adding files to the
.astro
dirBefore this PR, integrations had to make sure themselves that the
.astro
dir existed before adding files to it, and also had to compute the path from the root. Now, the.astro
directory is always created before and its path can conveniently be accessed ascodegenDir
(URL). This change is also convenient for Astro core as it allows any core feature to access thecodegenDir
(through settings), not onlycontent
related code.Adding types
Before this PR, integrations authors had to create a
.d.ts
file inside the.astro
directory, then updatesrc/env.d.ts
to add a relative reference to this file. Now,.astro/types.d.ts
is always created and creates references to other .d.ts files so that there can only be one reference insrc/env.d.ts
. For now, this file is calledtypes.d.ts
for backward compatibility reasons (that's the former filename of.astro/content.d.ts
) butastro.d.ts
is reserved as it seems to be a nicer convention. That can be an Astro 5 breaking change. Also worth noting that in Astro 5, this allows us to remove theastro/client
reference inenv.d.ts
as it's already present in.astro/types.d.ts
.Testing
Docs