Skip to content
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(prepare): allow prepare for layers #309

Closed
wants to merge 5 commits into from
Closed

feat(prepare): allow prepare for layers #309

wants to merge 5 commits into from

Conversation

ineshbose
Copy link
Member

A layer may make use of a module and then use imports from it through alias. The main project that uses this layer should also install this module, but even when that's the case, these imports aren't resolved unless it is in a corresponding tsconfig.json, but that may not be the case (in a monorepo especially, where your Nuxt app is in packages/app, and a layer may be in ../node_modules). We need to ship layers with tsconfig.json most likely, but will still need to generate paths resolved accordingly.

Refer https://github.com/nuxt/ui-pro/issues/118

@pi0
Copy link
Member

pi0 commented Dec 24, 2023

Thanks for PR but i think it seems a very costly operation to run prepare on every layer as a workaround...

If finally we need this, we can introduce a new meta for layers that needs prepare.

It also seems an undesired behavior that layers are not in ./node_modules but outside which we might fix.

@ineshbose
Copy link
Member Author

I see your point, but I can't say that this would be significantly costly for a simple Nuxt project, it would only be costlier in more complex projects with a lot of layers and rightfully so (in my opinion) as the bug is also critical.

Since layers is a Nuxt concept, I don't think this will be a @vue/compiler-sfc issue; or using SFCs in layers in such contexts may need to be discouraged (so @nuxt/ui-pro would look for a migration) - no other solution comes to mind but I'm open to hearing any others! 🙂

@pi0
Copy link
Member

pi0 commented Dec 24, 2023

Layers being cloned outside of current dir can be solvalabe by simply ensuring there is an empty node_modules dir within rootDir. This way giget will clone to it instead of higher up.

@ineshbose
Copy link
Member Author

Sorry, I'm not sure I understand! giget would clone a layer, but we're adding the layer as a dependency using pnpm, aren't we? Should we avoid listing an external layer as a dependency? 😅

@ineshbose
Copy link
Member Author

I believe that would be for layers with prefix github:, while the repository is private, but we have a NPM package!

@pi0
Copy link
Member

pi0 commented Dec 24, 2023

Ah, I see what you mean. Yes for package manager-managed layers it is different. (still strange tough as far I remember pmpm workspaces also makes a symlink in subdir)

Anyway, I think running prepare as an opt-in feature for layers makes sense still. What we can do is to set something like $nuxt: { prepare: true } (1) in layers and only run prepare for layers that have it. Wyt?

(1) (I guess we need to finally discuss about convention for key name internally but this is general approach I am thinking about)

@ineshbose
Copy link
Member Author

Opt-in makes sense but not the most easy in my thinking - layer maintainers may need to add this in and they may forget (but someone will definitely point out).

Or I'm thinking if we add a --layers flag to prepare command?

@ineshbose
Copy link
Member Author

still strange tough as far I remember pmpm workspaces also makes a symlink in subdir

Here I understand that despite the symlink, the resolved tsconfig.json still resolves to the tsconfig.json outside node_modules. Should've linked this before - https://github.com/nuxt/ui-pro/issues/118#issuecomment-1868519865

@ineshbose ineshbose changed the title fix(prepare): run prepare for extends/_layers feat(prepare): allow prepare for layers Dec 24, 2023
@ineshbose
Copy link
Member Author

Added in the layers argument (and this can change to a feat PR 😄); please feel free to review on how this could work; happy to chalk other solutions.

@ineshbose
Copy link
Member Author

ineshbose commented Jan 4, 2024

@pi0 what do you think? Hoping for this to be addressed in the next minor release.

(tailwind module docs deployments are also blocked by this)

@atinux
Copy link
Member

atinux commented Jan 9, 2024

So far we have the issue as soon as we use pnpm workspace + a layer that uses types, the Tailwind Docs is a good example to reproduce (try to run npm run docs:dev on https://github.com/nuxt-modules/tailwindcss)

Oneworkaround I found was to update the root tsconfig.json to:

{
  "extends": "./docs/.nuxt/tsconfig.json"
}

But this is not a correct solution as we break the module typings.

Other workaround is to disable pnpm workspaces.

I do find the solution quite nice since it only prepare the layer if the rootDir is different.

@pi0
Copy link
Member

pi0 commented Jan 9, 2024

We had been talking with @danielroe about possibly doing this directly in Nuxt core to smartly generate types for layers as well (when not published or available) also this logic is mostly relevant to the Nuxt core to control (this way we don't need to progressively discover layers like we do in this PR)

@atinux
Copy link
Member

atinux commented Jan 9, 2024

That would be awesome indeed.

Do you think of a kind of way to publish the types if possible?

I was also thinking that the $nuxt: { prepare: true } is a nice opt-in feature for complex layers that needs prepare.

But I will let you with @danielroe think about the best integration 😊

@pi0
Copy link
Member

pi0 commented Jan 9, 2024

Do you think of a kind of way to publish the types if possible?

In case of using npm publish or git tags, we might directly run nuxi prepare in layers and publish the generated .nuxt/types (however I have not tested but in theory should do the trick same as what we do here and be extendable). Within core, we might be able to also expose an option specific to generate types for published layers (and shake unnecessary things)

I was also thinking that the $nuxt: { prepare: true } is a nice opt-in feature for complex layers that needs prepare

Probably this should also directly go to the Nuxt core to have full control but I fully agree. We should try to adopt layer meta for the future it can come in handy.

@ineshbose
Copy link
Member Author

In case of using npm publish or git tags, we might directly run nuxi prepare in layers and publish the generated .nuxt/types (however I have not tested but in theory should do the trick same as what we do here and be extendable).

If I'm not wrong, .nuxt/tsconfig.json is local repo specific, so paths may not resolve over npm install (I'd also think to keep .nuxt excluded from package.json files)

@pi0
Copy link
Member

pi0 commented Jan 9, 2024

yes indeed, we need to specifically generate types that can be portable. For local utils and auto-imports, it should be doable I guess at least.

I guess the next step would be to support generating types for layers in core writeTypes util feel free to make a draft PR @ineshbose

@ineshbose
Copy link
Member Author

Do you think of a kind of way to publish the types if possible?

Publishing types separately is ideal imo, and unbuild does that for us, but this issue arises from usage of TS in Vue components that uses @vue/compiler-sfc; we can't separate types out from the script block there unless we use functional VNodes.

@ineshbose
Copy link
Member Author

I guess the next step would be to support generating types for layers in core writeTypes util feel free to make a draft PR

If I'm right in understanding, https://github.com/nuxt/nuxt/blob/main/packages/kit/src/template.ts#L255

here we can add

await Promise.all(
  nuxt.options._layers.map(
    layer => fsp.writeFile(resolve(layer.cwd, 'tsconfig.json'), GeneratedBy + `\n` + JSON.stringify({ extends: tsConfigPath }, null, 2))
  )
)

I'm thinking that this being added to core will still make this expensive, won't it? Of course, layer metadata options is another check that can narrow this a fair bit.

@pi0
Copy link
Member

pi0 commented Jan 9, 2024

We actually have to recursively call writeTypes in kit or rename current one to _writeTypes and make a loop (which is better as loop preserves layer order and allow meta data filtering). It is less expensive than adding to CLI and much more maintainable in the future. CLI should not deal with Nuxt's core logic such as how to write types but provide means to making Nuxt core easier.

@pi0 pi0 added the pending label Feb 14, 2024
@pi0
Copy link
Member

pi0 commented Mar 18, 2024

Hi dear @ineshbose coming back to this issue, i think we can move it to nuxt core. My understanding is that repro (https://github.com/nuxt/ui-pro/issues/118) is already resolved somehow else.

@pi0 pi0 closed this Mar 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants