import multiple components into a single line (Atomic Design + Vue.JS)

2.1k Views Asked by At

I am developing a project with Vue.js and would like to apply atomic design methodology, but I would like to import the components in a clustered and smarter way

currently

import GridLayout from '@/components/bosons/GridLayout.vue'
import LocalStorage from '@/components/bosons/LocalStorage.vue'

import ButtonStyled from '@/components/atoms/ButtonStyled.vue'
import TextLead from '@/components/atoms/TextLead.vue'
import InputSearch from '@/components/atoms/InputSearch.vue'

import SearchForm from '@/components/molecules/SearchForm.vue'

how I wish

import {
    GridLayout,
    LocalStorage
} from '@/components/bosons'

import {
    ButtonStyled,
    TextLead,
    InputSearch
} from '@/components/atoms'

import {
    SearchForm
} from '@/components/molecules' 

Sulution? I thought in on putting an index.js inside folders

/bosons/index.js
/atoms/index.js
/molecules/index.js

and index.js would import all components and export, so it would be something like

import ButtonStyled from './ButtonStyled.vue'

export default {
  ButtonStyled
}

or

export { default as ButtonStyled } from './ButtonStyled.vue'

works fine, but in this way is still static, every time you create a new component, need to add it index.js, each time you delete a component, you also need to delete it from index.js

I need to import all components of the folder dynamically

the closer I got was that,

const req = require.context('./', true, /\.vue$/)

const modules = {}

req.keys().forEach(fileName => {
  const componentName = fileName.replace(/^.+\/([^/]+)\.vue/, '$1')
  modules[componentName] = req(fileName).default
})

export const { ButtonStyled, TextLead } = modules

but I'm still defining the export variable names statically, I need to define dynamics based on the components inside the folder

NOTE: I can not use

export default modules

if I use the above code snippet I will not be able to import the way I need it, which is:

import { ButtonStyled } from "@/components/atoms"
2

There are 2 best solutions below

0
Yung Silva On BEST ANSWER

I created a Plugin Webpack, a library that is perfect for those who work with the methodology of Atomic Design, basically it makes exports named from a directory, maybe this helps other people

Weback Plugin - named-exports

2
Paul On

Here is a solution that imports all components in a folder dynamically although the import statement is two instead of one line.

Another drawback of this solution is that you would have to import the entire components folder every time, because the destructuring happens in the second line. This might lead to performance issues if you do not actually need all the components.


Step 1

I also used index files in the component folder so e.g. in your bosons folder, add an index.js file with the following content:

const req = require.context(".", false, /\.vue$/);

const components = {};

req.keys().forEach(fileName => {
  if (fileName === "./index.js") return;
  const componentName = fileName.replace(/(\.\/|\.vue)/g, "");
  components[componentName] = req(fileName).default;
});

export default components;

This adds the .vue files to the components object that you can then export. It excludes the index.js file (itself).


Step2

In your file where you want to import the boson components:

import bosons from "@/components/bosons";
const { GridLayout, LocalStorage } = bosons;

This imports the components and saves them in variables so you can use them.


Note that in my solution you cannot do

import { GridLayout, LocalStorage } from "@/components/bosons";

because the import {component} syntax looks like destructuring but isn't. It refers to the exports that look like "export const" but this is an "export default" export.