Use Vite with multiple entry points.
This case-study is based on a real life case years ago when we implemented Javascript modules and Vue 2
into a PHP based system. The PHP system was responsible for example routing and in those views we could use modern vanillajs
or vue
apps. So not your usual SPA
project.
Webpack was used to import code from multiple sources, babelify
it to accommondate Internet Explorer
and then creating multiple bundles. Then the script
files would be included into the PHP views with script
tags as you would traditionally do.
So I thought that it's time to get rid of that old Webpack and progressively move on to the future with Vite 3! This article will follow those old requirements and do not follow the modern standards in everything. This is not a tutorial, take away what you will!
Create a Vite project
Start by creating a vanillajs
Vite project following the official instructions and try to run npm run dev
just to see it working.
You'll notice that all the example files are in the root
folder so create a src
folder and inside of that a counter
folder. Move counter.js
, main.js
, whatever svg and css it might have but leave the index.html
. We'll use the npm run dev
command in the future but it doesn't work the same way as default, and it's fine because the aim is to load the script
files with the PHP or whatever back-end system you might have.
From your index.html
edit the default script
src like:
<div id="app"></div>
<script type="module" src="/dist/counter-vanilla.js"></script>
Configuring Vite for multiple sources
Next create a new file in the root
folder called vite.config.js
and paste the following inside:
import path from 'path'
import sources from './sources.js'
const input = {}
Object.keys(sources)
.forEach(name => {
const src = sources[name];
input[name] = path.resolve(__dirname, `src/${ src }`)
})
export default {
build: {
rollupOptions: {
input,
output: {
entryFileNames: () => '[name].js',
dir: './dist'
}
}
},
}
And then create a sources.js
file that is imported in the vite.config.js
. This could be a file outside of the Vite project like in another git
project. You could use .env
file to determine the location of the sources file when using on a git hook
at a server or locally on your machine.
Example sources.js
:
export default {
'counter-vanilla': 'counter/main.js',
}
Now try running first npm run build
and then npm run dev
. It should load the js
but personnally didn't get the css
working. After all, css
with vanillajs
doesn't fit the scope here. We'll use Vue to package those.
Including Vue 2
We'll add Vue 2.7 for now. To use the latest Vue 3 is less work, but you are in the same situtation that jumping from 2 to 3 is not yet possible, I got you covered!
You'll need to install these packages as dev depedency: npm install -D @vitejs/plugin-vue vite-plugin-vue2 vue-template-compiler
.
And then the Vue itself as a normal depedency: npm install vue@^2.7.7
.
Then in the vite.config.js
include the vue2 plugin:
import path from 'path'
import { createVuePlugin } from 'vite-plugin-vue2'
import sources from './sources.js'
const input = {}
Object.keys(sources)
.forEach(name => {
const src = sources[name];
input[name] = path.resolve(__dirname, `src/${ src }`)
})
export default {
build: {
rollupOptions: {
input,
output: {
entryFileNames: () => '[name].js',
dir: './dist'
}
}
},
plugins: [
createVuePlugin(/* options */)
],
}
Now we can create Vue 2 projects!
Vue project
Create a new folder vue-test
inside of the src
folder. Then create main.js
and App.vue
files inside of that.
Example main.js
:
import Vue from 'vue'
import App from './App.vue'
new Vue({
render: h => h(App),
}).$mount('#appVue')
Example App.vue
:
<template>
<div id="appVue">
<h1>{{ message }}</h1>
</div>
</template>
<script>
export default {
data: () => ({
message: 'Hello Vue 2.7!'
}),
}
</script>
Then add it to your sources file:
export default {
'counter-vanilla': 'counter/main.js',
'vue-test': 'vue-test/main.js',
}
Then edit into your index.html
:
<div id="app"></div>
<div id="appVue"></div>
<script type="module" src="/dist/counter-vanilla.js"></script>
<script type="module" src="/dist/vue-test.js"></script>
Now run npm run build
and npm run dev
and you'll should see both apps working at the same time! This could also be an example of micro frontends
.
Moving forwards
Doing this we can progressively move from Vue 2 to 3 and it is also even possible to use React too thanks to Vite's flexibility.
See full code at Github: @opiispanen/vite3-multiple-entries-example