Aleksandar Bencun
Aleksandar Bencun

Reputation: 357

Dynamic import paths in Vue and Webpack

I'm creating a frontend project in VueJS 2 (and Vue-CLI 3) that will be used by different clients and I would like to be able to import basically everything I need (JS files like mixins and component code and CSS/LESS files) during the webpack build process parametrically based on the CID that would be stored in: 1) the Vue .env file or 2) somewhere in the webpack config file or 3) passed as a parameter to npm run watch and npm run build.

I've searched about many solutions (Webpack plugins etc.) but none of them are simple or elegant nor am I really able to understand the inner workings of the Webpack to implement those solutions and most are related to the dynamic loading not the dynamic build process.

Different clients require different code and styling so for example:

<template>...</template>
<script src="./component-code.js"></script>
<style src="@/styles/component-style.less"></style>

These paths would need to turn into something along these lines:

<template>...</template>
<script src="./CLIENTID/component-code.js"></script>
<style src="@/styles/CLIENTID/component-style.less"></style>

...so that the Webpack can replace these CLIENTID references when compiling with real folder names whatever those may be. This would also have to work for any other file paths (e.g. when using statements like import something from "./path/CLIENTID/to/file";).

What would be the easiest solution to injecting such a variable into the build process? Thanks!

Upvotes: 5

Views: 7186

Answers (1)

aBiscuit
aBiscuit

Reputation: 4732

As one option, it is possible to use combination of aliases and architectural rules in order to achieve requested functionality.

1) Pass CLIENTID through an environmental variable or export it from any custom config file. Since CI is mentioned, let's suggest process.env is used.

2) Create aliases for all relevant paths that should be available for imports. It can be done in vue.config.js (in case of @vue/cli 3.0+) or inside a webpack config file.

Example for paths mentioned above:

'~styles': `src/styles/${process.env.CLIENTID}`
'~components': `src/components/${process.env.CLIENTID}`
'~something': `src/something/${process.env.CLIENTID}`

3) Change project structure to contain client specific component's into separate folders, while keeping shared code available via default paths.

4) Use aliases, that will resolve correct paths:

import CustomButton from '~components/custom-button.vue'

If you have a plan to bring many versions for different clients, it may be useful to refactor project architecture to something that will split all relevant assets for each CLIENTID, e.g.:

project |
        |-- common     |
        |              |--styles
        |              |--components
        |               
        |--CLIENTID_1  |
        |              |--styles
        |              |--components
        |
        |--CLIENTID_2  |
                       |--styles
                       |--components

This way aliases will be event more convenient to declare and use:

'~common': `src/common`
'~client': `src/${process.env.CLIENTID}`  

import CommonButton from '~common/components/common-button.vue'
import CustomButton from '~client/components/custom-button.vue'

Upvotes: 6

Related Questions