nuxt-modules / i18n

I18n module for Nuxt
https://i18n.nuxtjs.org
MIT License
1.71k stars 478 forks source link

feat: experimental auto declare/import translation functions #2858

Closed BobbieGoede closed 6 months ago

BobbieGoede commented 6 months ago

πŸ”— Linked issue

❓ Type of change

πŸ“š Description

Resolves #1644

This is can still be considered a work in progress as its an exploration of the implementation suggested in https://github.com/nuxt-modules/i18n/pull/2847#issuecomment-2004274280.

Honestly my implementation feels very fragile as I don't have a lot of experience/knowledge about this approach, I adapted what I could from various vite plugins in the suggested repos as well as those in Nuxt. I can probably remove some functionality (that I essentially copied, without fully understanding it) for performance/maintainability. Please let me know what can be improved or changed, happy to learn more about this!

In this implementation the option experimental.autoImportTranslationFunctions, when enabled, inserts code to declare/initialize $t, $rt, $d, $n, $tm and $te at the start of <script setup> (when needed). It works by going through Vue files and checking if translation functions are being used without having been declared.

Demo

<script setup>
const myText = computed(() => $t('hello'))
</script>

<!-- transforms to -->

<script setup>
const { t: $t } = useI18n()

const myText = computed(() => $t('hello'))
</script>

Demo - detect usage

This should work as expected since only functions which have not been declared are inserted.

<script setup>
const { t: $t } = useI18n({ useScope: 'local' })

const myText = computed(() => $t('hello'))
const myDate = computed(() => $d('2024-01-01'))
const myNumber = computed(() => $n(123))
</script>

<!-- transforms to -->

<script setup>
const { d: $d, n: $n } = useI18n()
const { t: $t } = useI18n({ useScope: 'local' })

const myText = computed(() => $t('hello'))
const myDate = computed(() => $d('2024-01-01'))
const myNumber = computed(() => $n(123))
</script>

Drawbacks of this approach is, it relies on autoImports to work and only works in <script setup> as I don't know how to insert code inside setup() {}.

I suppose if this implementation is not too hacky, and the reliance on Nuxt's autoImports can be removed, maybe this should be a separate package? This can also be changed to scan the <template> for usage as well, not sure if there would be benefits of using this approach over setting these functions on app.config.globalProperties or if performance would be degraded.

πŸ“ Checklist

nuxt-studio[bot] commented 6 months ago

Live Preview ready!

Name Edit Preview Latest Commit
i18n Edit on Studio β†—οΈŽ View Live Preview 3bc77da14c52fef5b5380dd6543fcab5e0102894
BobbieGoede commented 6 months ago

The tests can probably be expanded to cover more scenarios and I will remove or at least cleanup my playground testing changes (as well as those in basic_usage nuxt.config etc.).

kazupon commented 6 months ago

Drawbacks of this approach is, it relies on autoImports to work and only works in <script setup> as I don't know how to insert code inside setup() {}.

I suppose if this implementation is not too hacky, and the reliance on Nuxt's autoImports can be removed, maybe this should be a separate package? This can also be changed to scan the <template> for usage as well, not sure if there would be benefits of using this approach over setting these functions on app.config.globalProperties or if performance would be degraded.

Wow, This PR is so amazing! πŸš€

About Drawbacks, It would be good to note in the nuxt i18n documentation! ✍️

My understanding from reading the code earlier is that nuxt auto import uses unplugin-auto-imporot internally. So, in combination with unplugin-auto-import, I think this could be a good solution not only for nuxt, but also for the community that simply uses vue + vite.

After we will release for nuxt i18n, it would be nice to provide it in @intlify/vue-i18n-auto-import in intliy organaization! And if you are interested in it, I can new repo on intlfy oranaization and invite to you at there. :)

BobbieGoede commented 6 months ago

Wow, This PR is so amazing! πŸš€

Thank you πŸ™

About Drawbacks, It would be good to note in the nuxt i18n documentation! ✍️

Ah yes, I will expand the docs, users should know that autoImports cannot be disabled if they want to use this.

After we will release for nuxt i18n, it would be nice to provide it in @intlify/vue-i18n-auto-import in intliy organaization! And if you are interested in it, I can new repo on intlfy oranaization and invite to you at there. :)

It would be great to make this available to projects that don't use Nuxt, sounds good! πŸ’ͺ

BobbieGoede commented 6 months ago

I have cleaned up the PR a bit and added a warning in the docs to mention that auto-imports needs to be enabled for this to work.

The documentation is still very minimal for this feature, but we can always expand on it later, I'm curious to hear from users if this works in their projects without issues while it is still experimental.

Also, I think this functionality can be expanded upon later (not in this PR) to support $i18n, $getRouteBaseName, $localePath, $localeRoute, and $switchLocalePath as well (not sure about $localePath as it's inconsistent with useLocaleHead). But only after the functionality in this PR has proven to be useful and with minimal or no issues.

kazupon commented 6 months ago

Well done! I'll merge this PR!