Nuxt.js: add ability to auto import components per page

Created on 6 Feb 2018  路  13Comments  路  Source: nuxt/nuxt.js

There is currently no possibility to auto import components per page without writing boilerplate:
import myComp from '~/components/my-comp.vue'
I suggest adding the ability to group components by page name. Example:
pages/index.vue
pages/level1.vue
pages/level1/level2.vue

components/my-component.vue
components/level1/text-component.vue
components/level1/level2/image-component.vue

my-component will be auto imported by index.vue page.
text-component - by level1.vue
image-component - by level2.vue

This feature request is available on Nuxt.js community (#c2410)

Most helpful comment

Can't say I'm a fan of this magic. importing a component/class/namespace should always be explicit, otherwise we'll have a hard time reasoning their whereabouts. I'd prefer autocomplete support at IDE level instead.

All 13 comments

I love this idea. Another use case would be in big component libraries (Like Vuetify, Framework7-Vue, BootstrapVue, ...) to auto import only needed components only on page chunks where needed without any extra boilerplate.

My proposal is writing a webpack loader / babel transform (probably in front of vue-loader) to statically analyze and detect used tags. But it may need more works for JSX, render function and dynamic tags (Probably some of them won't supported forever)

component name <--> source mapping

For resolve, we can add a new option in nuxt.config.js / (Or package.json for vue-cli) to declare library resolve options.

autoImport: [
  'vuetify'
]

Each package can also self-define itself with a vue keyword in package.json:

Example of foo/package.json:

vue: {
 autoImport: {
    prefix: 'foo-',
    source: 'foo/es/components/{name}'
 }

If package provides named exports: (import { alert } from '...')

vue: {
 autoImport: {
    prefix: 'foo-',
    source: 'foo/dist/foo.mjs'
 }
}

This will instruct our loader to transform this:

<template>
 <foo-alert />
</template>

Into this:

<template>
 <foo-alert />
</template>

<script> 
export default {
 import fooAlert from 'foo/es/components/alert'

 export default {
   components: { fooAlert }
 }
}

For local components we also add a default resolve config that is probably enabled by default:

{ 
 prefix: 'component-',
 source: '~/components/{name}' 
}

Also for namespacing, we can use nested directories so <component-admin-alert> will be imported from ~/components/admin/alert.

Can't say I'm a fan of this magic. importing a component/class/namespace should always be explicit, otherwise we'll have a hard time reasoning their whereabouts. I'd prefer autocomplete support at IDE level instead.

And one more. All root components in ~/components will be imported globally.

That would make all the tree shaking useless and would waste user's resources.

This ability can be optional and configured via nuxt.config.js.

It should not be a feature in the first place.

Off by default and turned on only if need.

@asv1, would this be similar to nextjs's dynamic imports feature?

Because this issue seems to be inactive for quite some time, I'll close it now. If you feel like it deserves some attention because it's not fixed, feel free to ping me and I'll reopen it.

An easy and working way would be a fs.readdirSync which scans a specific directory, which contains all components which should be imported automatically, in the nuxt.config.js file...

nuxt.config.js example:

import fs from 'fs'

let components = fs.readdirSync('./components')
components = components.join(',') // since the env should just contain strings

module.exports {
    env: {
        components: components
    }
}

and then make a plugin, and include it in the nuxt.config.js file. This plugin loads all the components:

```
import Vue from 'vue'

let components = process.env.components.split(',')

components.forEach((componentFileName) => {
const component = require('~/components/' + componentFileName).default
Vue.component(component.name, component)
})

````

That way all Components located in the ~/components folder are loaded automatically.

Note, that each component must have a name parameter

This doesn't really solve it though @daspete. Have a look at nextjs' dynamic imports. A use case for which I've used dynamic imports is you're building components for content blocks in a cms. A page in the cms may contain any number of components, so you'd want to only require those components used in the content blocks of the page.

This doesn't really solve it though @daspete. Have a look at nextjs' dynamic imports. A use case for which I've used dynamic imports is you're building components for content blocks in a cms. A page in the cms may contain any number of components, so you'd want to only require those components used in the content blocks of the page.

hmm... i thought, that only that components, which are just in the current page are imported for that specific page. Of course, the vendor file, or app file will be a little bit bigger, but that way, the user has to wait just one time to load it all and then there is no more loading time (or much less) then to load a new custom app or vendor file for each page...

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bimohxh picture bimohxh  路  3Comments

vadimsg picture vadimsg  路  3Comments

mattdharmon picture mattdharmon  路  3Comments

uptownhr picture uptownhr  路  3Comments

lazycrazy picture lazycrazy  路  3Comments