Skip to content
This repository has been archived by the owner on Apr 6, 2023. It is now read-only.

feat(nuxt): imports.autoImport option to disable auto-imports #6768

Merged
merged 1 commit into from Aug 24, 2022

Conversation

antfu
Copy link
Member

@antfu antfu commented Aug 19, 2022

…import

πŸ”— Linked issue

fix nuxt/nuxt#14505

❓ Type of change

  • πŸ“– Documentation (updates to the documentation or readme)
  • 🐞 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)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

πŸ“š Description

Since Nuxt uses #imports internally and modules would also need it, we shouldn't completely disable the transform, but instead, we could make implicit imports possible to opt-out.

πŸ“ Checklist

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

@netlify
Copy link

netlify bot commented Aug 19, 2022

βœ… Deploy Preview for nuxt3-docs ready!

Name Link
πŸ”¨ Latest commit 124de92
πŸ” Latest deploy log https://app.netlify.com/sites/nuxt3-docs/deploys/630580e9a3e1fb0008537419
😎 Deploy Preview https://deploy-preview-6768--nuxt3-docs.netlify.app
πŸ“± Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@antfu antfu changed the title feat(nuxt): introduce autoImports.enabled allowing to disable auto-… feat(nuxt): introduce autoImports.enabled allowing to disable auto-import Aug 19, 2022
```ts [nuxt.config.ts]
export default defineNuxtConfig({
autoImports: {
enabled: false
Copy link
Member

Choose a reason for hiding this comment

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

What do you think of calling option implicit: false or global: false (since we still have auto imports integration with #imports.

Copy link
Member Author

@antfu antfu Aug 19, 2022

Choose a reason for hiding this comment

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

Yeah I kinda thought about that. My idea was:

  • implicit might be a bit less intuitive as not everyone needs to know the existence of the explicit imports. Most of the time I feel the "Auto import" should refer to implicit auto import.
  • We picked the scope name of autoImports (with we went a bit beyond that tbh πŸ˜„), autoImports.enabled = false sounds just like we are disabled the "auto" part. While the explicit import technically is not that "Auto" 🀣

For more semantic meaning maybe we could reconsider the autoImports scope naming.

But that said, I think implicit: false could also be a good name.

Copy link
Member

Choose a reason for hiding this comment

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

What about mode: 'inject' | 'import'?

Copy link
Member

Choose a reason for hiding this comment

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

I like it but inject mode also allows import (ie: it is not switch between them but switch auto)

Copy link
Member

Choose a reason for hiding this comment

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

Then what about something like: 'auto' | 'explicit' ?

Copy link
Member

Choose a reason for hiding this comment

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

Still auto means (auto + explicit). More i'm thinking, we could rename option to imports, and then support imports.autoImport: false.

@darthf1
Copy link

darthf1 commented Aug 19, 2022

Wow, thanks for looking into this, and so soon :)

So, If i understand everything correctly, when the implicit auto import is disabled, #import keeps working, because it is used in modules, e.g. like Pinia?

With implicit auto import disabled, can I still use #imports in my own app? Or is that alias removed from the ./.nuxt/tsconfig.json? My preference would be that I cannot use #imports in my own app, and force users to use import { ref } from 'vue' instead of import { ref } from '#imports'. But I'm not sure if this would be possible with the previous point.

With implicit auto import disabled, what happens with imports from nuxt/dist/app? Do I use import { defineNuxtPlugin } from 'nuxt/dist/app', or is this what the #app alias is used for? Is #app being kept, or can I do import { defineNuxtPlugin } from 'nuxt' after this PR?

readonly defineNuxtComponent: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app')['defineNuxtComponent']>
readonly defineNuxtLink: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app')['defineNuxtLink']>
readonly defineNuxtPlugin: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app')['defineNuxtPlugin']>
readonly defineNuxtRouteMiddleware: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app')['defineNuxtRouteMiddleware']>

Again, thanks for looking into this. Looking forward to use Nuxt 3, and even more with this feature.

@antfu
Copy link
Member Author

antfu commented Aug 19, 2022

With implicit auto import disabled, can I still use #imports in my own app?

Yes

My preference would be that I cannot use #imports in my own app

I would suggest setting an ESLint rule for that if you strictly want that.

force users to use import { ref } from 'vue' instead of import { ref } from '#imports'

They are equivalent in the bundle. #imports will be transformed into the actual import.

Do I use import { defineNuxtPlugin } from 'nuxt/dist/app', or is this what the #app alias is used for? Is #app being kept, or can I do import { defineNuxtPlugin } from 'nuxt' after this PR?

It's recommended to use #app (or #imports) whenever you can. #app refers to the runtime utilities that Nuxt generates. It's different from importing nuxt, which is the tool itself. Ideally, I would never import from nuxt except in config and programmatic usage IIUC.

@rvanlaak
Copy link

Found this PR while doing package selection for choosing Nuxt as possible framework for a future project. What I'm focussing on; finding a framework that adopts common coding best practices related to SOLID principles. In what situation would the concept of #imports match with SOLID principles?

The great news is that auto-imports seem to make it drastically easier for beginning developers to build stuff, but also can be considered as a direct violation to the dependency inversion priniciple. Having a huge #imports pool of unclear and opinionated classes will lead to tight coupling to the framework. Auto imports seem to introduce black compiler magic that make it unclear what code you actually are relying on, and will in turn make debugging harder. How can a developer do dependency inversion or guarantee LSP on one of the framework's services?

The feature in this PR thereby possibly could be considered as a must-have before the major release? Has it been considered in what way the introduction of auto-imports would (also negatively) impact the framework future? An interesting topic to read about is how in the land of PHP the Laravel framework Facades do opinionate development and thereby made two camps.

So, although the topic obviously might be out of scope of this PR, the question to ask is in what way Nuxt can on the one hand simplify development by supporting features like auto-imports, while on the other hand drive adoption of commonly accepted development principles like decent dependency injection. It is not strange that DI containers like InversifyJS do so well on Github with 9.2k stars. PSR-11 is a great example of what Nuxt could also do.

What about, instead of silently enabling auto-imports and forcing engineers to use auto-imports, as a framework giving the developer freedom of choice? Nuxt coud support the embedding of a DI container in Nuxt, while also giving them the other option to enable auto-imports? It could be as simple as a container interface or facade, and a toggle in the Nuxt config.

@antfu
Copy link
Member Author

antfu commented Aug 23, 2022

Update: This PR is now on top of #6864, and renamed to imports.autoImport

@antfu antfu changed the title feat(nuxt): introduce autoImports.enabled allowing to disable auto-import feat(nuxt): introduce import.autoImport allowing to disable auto-import Aug 23, 2022
@antfu antfu changed the title feat(nuxt): introduce import.autoImport allowing to disable auto-import feat(nuxt): introduce imports.autoImport allowing to disable auto-import Aug 23, 2022
@rvanlaak
Copy link

You probably wanted to reference to another PR here, given your comment mentions this same PR.

@DaniFoldi
Copy link

Probably #6864 is the correct one

@antfu
Copy link
Member Author

antfu commented Aug 23, 2022

@rvanlaak Thanks for the DI idea, but I guess it might a bit off-topic here. It would be great if you could open up a new discussion with a more detailed example/approach that you think would be useful. So we could discuss there.

@pi0
Copy link
Member

pi0 commented Aug 23, 2022

@antfu Do you mind to rebase PR?

@antfu
Copy link
Member Author

antfu commented Aug 24, 2022

Done!

@pi0 pi0 changed the title feat(nuxt): introduce imports.autoImport allowing to disable auto-import feat(nuxt): imports.autoImport option to disable auto-imports Aug 24, 2022
@pi0 pi0 merged commit 856c2a6 into main Aug 24, 2022
@pi0 pi0 deleted the feat/auto-imports-enabled branch August 24, 2022 08:44
@pi0 pi0 mentioned this pull request Aug 26, 2022
@danielroe danielroe added the 3.x label Jan 19, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

allow disabling auto imports
6 participants