Configuration
Each module needs several things to work properly.
index.js
In the project directory we create an entry file called index.js
, needed to run the module.
It is required file.
index.js
is created according to the Nuxt Modules rules,- The default exported function must be asynchronous,
- We can add two additional functions:
beforeModule()
- asynchronous function run before the module is loaded,afterModule()
- asynchronous function started after the module is loaded,
export async function beforeModule() {
// run before loading module
}
export default async function () {
// module logic
}
export async function afterModule() {
// run after loading module
}
config
directory:
The greatest advantage of modules based on the VueMS library is their advanced expandability.
Each module contains a directory config
in which all configurations related to this module can be found.
The most important configuration file is index.js
, which contains everything you need to load the module correctly.
All other files are optional and depend on the purpose of the module.
Some of the files kept in the config
directory are just help files to keep order and structure in code.
Main configuration
The main configuration is placed in the config/index.js
file.
The file exports the properties needed to correctly configure the module.
It is required file.
Properties:
name
- Type:
String
- Required:
true
- Type:
Module name including scope, used for correct module loading. The file path is built on its base.
order
- Type:
Number
- Required:
false
- Default:
1000
- Type:
The sequence of loading modules in the application. This may be important when the modules have a relationship with each other.
If the default value is not set to 1000
, the modules will be loaded at the end.
order: 20
).
aliases
- Type:
Object
- Required:
true
- Type:
The main mechanism of communication between the modules.
By specifying the alias, we create a name by which we will referencing the resources of this module.
export default {
...
aliases: {
'@Core': '/',
'@CoreComponents': '/components',
},
};
import List from '@Core/components/List/List';
//or
import List from '@CoreComponents/List/List';
relations
- Type:
Array
- Required:
false
- Type:
If the modules are linked to each other, the names of the linked modules must be given here.
export default {
...
relations: [
'@ergonode/attributes',
'@ergonode/media',
],
};
replacements
- Type:
Object
- Required:
false
- Type:
It defines the elements of the module that will be replaced by others.
Simple mechanism of mapping elements to be replaced with a new element.
export default {
...
replacements: {
'@Core/components/coreComponent': '/components/myComponent',
},
};
plugins
- Type:
Array
- Required:
false
- Type:
It defines the plugins that are loaded globally into the application.
export default {
...
plugins: [
{
ssr: true,
src: './plugins/axios',
},
],
};
ssr
flag is set when you want the plugin to be loaded at server startup. ssr: false
===mode: 'client'
ssr: true
===mode: 'server'
css
- Type:
Array
- Required:
false
- Type:
Defines css styles that are defined globally for the entire application.
export default {
...
css: [
'./assets/scss/reset.scss',
'./assets/scss/font-inter-ui.scss',
],
};
Example:
export default {
name: '@test/core',
order: 10,
aliases: {
'@Core': '/',
},
relations: [
'@test/messages',
],
replacements: {
'@Test/components/coreComponent': '/components/myComponent',
},
plugins: [
{ ssr: true, src: './plugins/axios' },
],
css: [
'./assets/scss/reset.scss',
]
};
Routing
File required if the module has pages and wants to define its own routing.
If the routing exists, you must create a file named routes.js
and put all the routing rules in it.
Information from this file determines the routing passed to the @nuxtjs/router
library,
which overwrites the default Nuxt routing.
The array exported in the file is parsed and combined by the VueMS and passed
to the main configuration of new Router()
.
import {
Icons,
Pages,
Tabs,
} from './imports';
import Privileges from './privileges';
export const ROUTE_NAME = {
SETTINGS_UNITS: 'settings-units',
SETTINGS_UNIT_EDIT: 'unit-id',
SETTINGS_UNIT_EDIT_GENERAL: 'unit-id-general',
};
export default [
{
name: ROUTE_NAME.SETTINGS_UNIT_EDIT,
path: '/settings/units/unit/:id',
component: Pages.UnitEdit,
redirect: {
name: ROUTE_NAME.SETTINGS_UNIT_EDIT_GENERAL,
},
meta: {
isMenu: false,
},
children: [
{
name: ROUTE_NAME.SETTINGS_UNIT_EDIT_GENERAL,
path: 'general',
component: Tabs.UnitGeneralTab,
meta: {
title: 'Options',
breadcrumbs: [
{
title: 'System',
icon: Icons.Settings,
},
{
title: 'Units',
routeName: ROUTE_NAME.SETTINGS_UNITS,
},
],
privileges: [],
},
},
],
},
];
Extend
Creating new modules is not all we usually need. Sometimes you need to replace certain elements or add some to already existing solutions.
In order not to modify existing modules, VueMS library provides a solution to easily extend already existing mechanisms. Thanks to it we have a lot of possibilities to extend modules from other modules.
In order to add any extensions you need to create an extends.js
file
and use specific properties in it depending on what you want to achieve.
extends.js
file if you don't want to extend anything
Properties:
replaceRoutes
- Type:
Array
- Type:
This functionality allows you to replace a routing page by his name. The mechanism is based on routing and extends existing routing.
replaceRoutes
:
- name
- existing router name what we want replace,
- routes
- new routing to replace,
export default {
replaceRoutes: [
{
name: 'products',
routes: {
name: 'products-new',
path: '/new-products',
component: Tabs.Product,
meta: {
title: 'New Products',
visible: false,
breadcrumbs: [
{
title: 'New Products',
icon: Icons.Product,
},
],
privileges: [],
},
},
},
],
};
First the routing is replaced and then extended (
extendRoutesChildren
), so if a routing is added to the given name, it will be added correctly.
extendRoutesChildren
- Type:
Array
- Type:
This functionality allows you to add a new children to a routing page. The mechanism is based on routing and extends existing routing.
extendRoutesChildren
:
- name
- existing router name what we want extend,
- children
- array with router to extend,
export default {
extendRoutesChildren: [
{
name: 'product-id',
children: [
{
name: 'product-id-variants',
path: 'variants',
component: Tabs.ProductVariantsTab,
meta: {
title: 'Variants',
visible: false,
breadcrumbs: [
{
title: 'Products',
icon: Icons.Product,
},
{
title: 'Catalog',
routeName: 'catalog-products',
},
],
privileges: [],
},
},
],
},
],
};
children
property then it will be added.
extendStore
- Type:
Object
- Type:
A mechanism to expand existing Vuex store. If there is a need to extend an already existing Vuex store then you should use this property.
When using extendStore
, the key is the name of the existing Vuex store
and the value is the file that exports the content of the extended methods.
Vuex store runs on vuex modules mechanism.
export default {
extendStore: {
product: () => import('@Products/extends/store/product').then(m => m.default || m),
},
};
store
.
We recommend that you use the extends
directory.
store
directory on the module root and place a Vuex store with an existing name in it, it will be replaced (The order of loading the modules is important).
extendComponents
- Type:
Object
- Type:
One of the important mechanisms is the possibility of extending existing components from outside. The operation of the components allows them to be reusable and used anywhere, but the problem is when we want to extend an existing component in a specific business context. Therefore, we have prepared a mechanism that allows you to easily inject a component into a specific location.
The component expansion mechanism works similarly to the placeholder placed in the text, the placeholder is replaced by the data passed on to it. Our component expansion mechanism works the same way, with the appropriate placeholders scattered throughout the application, which can be referenced and passed on to the component.
There are predefined places ready for expansion throughout the application.
Example:
const Navigation: () => import('@Notifications/components/Navigation');
export default {
extendComponents: {
NAVIGATION_BAR: [
{
component: Navigation,
props: {
propsToSend: true,
},
},
],
},
};
<template v-for="(component, index) in extendedComponents">
<Component
:is="component.component"
:key="index"
v-bind="component.props" />
</template>
<script>
export default {
computed: {
extendedComponents() {
return this.$getExtendSlot('NAVIGATION_BAR');
},
},
};
</script>
(e.g
@Products/components/Forms/ProductForm
- extend product form component).
We recommend this approach because it is very clear.
$getExtendSlot
method in the application that takes all the components
passed for expansion and places them in a prepared place.
extendMethods
- Type:
Object
- Type:
The mechanism works the same as extendComponents
, but instead of the components the placeholders are filled with methods.
The methods can return information or just set up some data.
The methods can take any parameters, it depends on the information provided while creating the placeholder.
Example:
export default {
extendMethods: {
'@Test/store/test/action': ({
$this, data = [],
}) => {
console.log({$this, data});
return data;
}
},
}
export default {
create({ state }) {
...
this.$getExtendMethod('@Test/store/test/action');
...
}
}
$getExtendMethod
method in the application that takes all the methods
passed for expansion and places them in a prepared place.
Helpers
Support files are files that are not imposed by VueMS, they are to make your work easier.
privileges.js
A file storing all permissions imposed by the module. Used mainly in routing - routes.js
.
export default {
SETTINGS: {
namespace: 'SETTINGS',
create: 'SETTINGS_CREATE',
read: 'SETTINGS_READ',
update: 'SETTINGS_UPDATE',
delete: 'SETTINGS_DELETE',
},
};
imports.js
A file storing all imports needed in the configuration files.
export const Pages = {
Login: () => import('@Core/pages/login/index').then(m => m.default || m),
};
export const Tabs = {
MainSettingsTab: () => import('@Core/components/Tabs/MainSettingsTab').then(m => m.default || m),
};
config
directory is used for this.