0

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"
Yung Silva
  • 1,324
  • 4
  • 20
  • 40
  • Try tagging what javascript bundler you use, (I think Webpack is the default) because what you want to do can probably be accomplished in the bundler config. – Benjamin Davies Apr 25 '19 at 00:30
  • What do you mean by this? `but is not feasible, every component created or deleted the index.js needs to be changed` - what do you mean by 'changed'? I just tested this with the `index.js` solution, and it worked perfectly. – Matt Oestreich Apr 25 '19 at 02:10
  • @MattOestreich this way I'm importing statically, so with every created component I have to add it in index.js, if I delete a component, also need to delete from index.js, I need index.js to import all the components inside of the folder dynamically, sorry for my bad english – Yung Silva Apr 25 '19 at 02:46
  • So you want to auto import every single Vue file in your project in one swipe, regardless which directory they live in? I definitely don't recommend doing this, but why would you want to do this in the first place? – Matt Oestreich Apr 25 '19 at 16:40

2 Answers2

0

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.

Community
  • 1
  • 1
Paul
  • 326
  • 2
  • 6
  • I updated my question with as close as I got to the solution, take a look please and if I can help – Yung Silva Apr 25 '19 at 18:48
  • I cannot think of how it could be done since you cannot do dynamic "export const" in javascript as far as I know. As Matt mentioned, what you want to do is quite unusual so it might be a good idea to think about different approaches and if it is really necessary to import all the components like this. If you really, really, really need to do it like this, you could write a script outside your vue app that changes the code itself. – Paul Apr 25 '19 at 20:04
0

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

Community
  • 1
  • 1
Yung Silva
  • 1,324
  • 4
  • 20
  • 40