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(nuxt): allow fallback production content in <DevOnly> #20817

Merged
merged 4 commits into from May 13, 2023

Conversation

ineshbose
Copy link
Member

@ineshbose ineshbose commented May 12, 2023

πŸ”— Linked issue

❓ Type of change

  • πŸ“– Documentation (updates to the documentation, readme or JSdoc annotations)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • πŸ‘Œ Enhancement (improving an existing functionality like performance)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

πŸ“š Description

This is a (silly little) PR that's motivated by some use-cases/scenarios where usage of the handy DevOnly causes some design changes in my app during build and so usage requires extra consideration. For example,

<div class="flex justify-between">
  <span>1</span>
  <span>2</span>

  <!-- here I *could* wrap DevOnly in span but it may affect what I put inside the component -->
  <span><DevOnly></DevOnly></span>
  <!-- and where do I put 3 if I don't want both fighting for space in span during dev -->

</div>

<!-- more realistic example -->
<div class="flex justify-between">
  <span>Search</span>
  <span>Branding</span>

  <Menu />
  <DevOnly>
    <DevMenu /> <!-- custom component as superset of Menu -->
  </DevOnly>
</div>

In such cases, especially where I have flex class, when DevOnly is removed, it causes block of three to change into two across the screen. This could allow fallback usage if ever required by devs.

<div class="flex justify-between">
  <span>1</span>
  <span>2</span>
  <DevOnly>
    <Button />
    <template #fallback><span>3</span></template>
  </DevOnly>
</div>

<div class="flex justify-between">
  <span>Search</span>
  <span>Branding</span>
  <DevOnly>
    <DevMenu />
    <template #fallback><Menu /></template>
  </DevOnly>
</div>

Could test it out in the repository playground:

playground/app.vue

<script setup lang="ts">
</script>

<template>
  <!-- Edit this file to play around with Nuxt but never commit changes! -->
  <div>
    Nuxt 3 Playground
    <DevOnly>Some dev-only info</DevOnly>
    <div><DevOnly>Some dev-only info</DevOnly></div>
    <div>
      <DevOnly>
        Some dev-only info
        <template #fallback>
          Some prod-only info
        </template>
      </DevOnly>
    </div>
  </div>
</template>

<style scoped>

</style>

and run pnpm play:build && pnpm play:preview

πŸ“ Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

@nuxt-studio
Copy link

nuxt-studio bot commented May 12, 2023

βœ… Live Preview ready!

Name Edit Preview Latest Commit
Nuxt Docs Edit on Studio β†—οΈŽ View Live Preview 76fbd00

@ineshbose
Copy link
Member Author

Sorry I'm unable to figure out why tests are failing (webpack in my testing works, and the vite test on empty.ts is odd) - any help/guidance please? πŸ˜…

@florian-lefebvre
Copy link
Contributor

What if instead we applied display: contents to the DevOnly component? so that is doesn't affect layout at all

@ineshbose
Copy link
Member Author

If I'm not wrong, styles can't be applied to DevOnly, and regardless of whatever the contents, it gets removed from the SFC

@florian-lefebvre
Copy link
Contributor

Yes I read the component code after commenting πŸ™„. But I'm wondering if providing a production fallback doesn't defeat the whole purpose of the component πŸ€”. I don't know, I guess we'll wait for a maintainer's comment

@ineshbose
Copy link
Member Author

ineshbose commented May 13, 2023

Very fair point - I do think it won't change functionality but rather provide the feature if ever required (like in the above examples)

Can't see it hurt - it's nice to have! πŸ™‚

@danielroe danielroe changed the title feat(dev-only): allow fallback feat(nuxt): allow fallback (production) content in <DevOnly> component May 13, 2023
Copy link
Member

@danielroe danielroe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a nice feature - thank you! ❀️

I think it makes sense to keep fallback as similar to <ClientOnly>.

@danielroe danielroe changed the title feat(nuxt): allow fallback (production) content in <DevOnly> component feat(nuxt): allow fallback production content in <DevOnly> May 13, 2023
@danielroe danielroe merged commit d077c10 into nuxt:main May 13, 2023
19 checks passed
@github-actions github-actions bot mentioned this pull request May 13, 2023
@@ -9,7 +9,7 @@ interface DevOnlyPluginOptions {
}

export const DevOnlyPlugin = createUnplugin((options: DevOnlyPluginOptions) => {
const DEVONLY_COMP_RE = /<(dev-only|DevOnly)>[\s\S]*?<\/(dev-only|DevOnly)>/g
const DEVONLY_COMP_RE = /<(?:dev-only|DevOnly)>[^<]*(?:<template\s+#fallback>(?<fallback>[\s\S]*?)<\/template>)?[\s\S]*?<\/(?:dev-only|DevOnly)>/g
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this regex won't work with the example in the updated doc and the following html due to [^<]*:

<DevOnly>
        <p>Some dev-only info</p>
        <template #fallback>
          Some prod-only info
        </template>
      </DevOnly>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm.... i forgot to submit the review

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for looking at this. we should probably add the handling to TreeShakeTemplatePlugin ...

Copy link
Member Author

@ineshbose ineshbose May 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for sharing! I was chaining the two regex/matches earlier (inefficient imo) but I think putting it into one (needing [^<]) caused it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about using ultrahtml instead of the regex and keep the dev-only plugin ? TreeShakeTemplatePlugin won't remove ssrRender(DevOnly...) but only remove its slots that are not fallback or placeholder.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completely up for using parsers over regex for safer template handling! Should it wait for #20284 as it adds ultrahtml to Nuxt dependencies first?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can do it now, it won't cause any complex merge conflict πŸ™‚

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently gone for splitting regex (in #20840) as ultrahtml could cause trade-off with performance (through safety).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants