I have a Vue.js app that I created with Vite. This app successfully runs when I use npm run dev
and visit the app in the browser. Now, I'm trying to bundle the app as a single code file so that I can use it as a plugin for Figma.
I know that the index.html
page loads because I can edit the HTML and see the changes. However, the page isn't loading/running the Vue.js app itself. I can see the following warning in the console log:
<link rel=modulepreload> has no 'href' value
My project is structured like this:
/
/dist
/assets
index.a386f87b.css
index.dc441194.js
vendor.fbe8b50a.js
index.html
manifest.json
plugin.js
/src
/views
Index.vue
Items.vue
Calendar.vue
/res
/css
theme.css
/images
loading.gif
splash.jpeg
App.vue
main.js
index.html
When I look at the index.html file in the dist
directory, I see:
<script type="module" crossorigin src="/assets/index.dc441194.js"></script>
<link rel="modulepreload" href="/assets/vendor.fbe8b50a.js">
<link rel="stylesheet" href="/assets/index.a386f87b.css">
<div id="app" class="position-absolute top-0 left-0 vh-100 vw-100"></div>
The references look correct. However, clearly something is wrong as the app is not loading as a plugin in Figma. Once again, I know I'm successfully loading the index.html
file because if I manually edit it, the changes appear in the plugin. This leads me to bundling the app as a single code file. At this point, I'm stuck though. I don't see a way to accomplish this via Vite's built-in capabilities. I tried including the vite-plugin-singlefile
plugin. Unfortunately that didn't work for me either. Currently, my vite.config.js
file looks like this:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue';
export default defineConfig(({command, mode }) => {
return {
assetsDir: 'res',
plugins: [
vue(),
],
root: 'src',
build: {
emptyOutDir: true,
outDir: '../dist'
}
}
});
What am I doing wrong?
Figma ignores <script>.src
and <link>.href
, which aligns with the docs you linked, stating "all the code must be in one file".
Using vite-plugin-singlefile
(as you mentioned) to inline all scripts and styles in index.html
indeed seems to workaround the problem:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { viteSingleFile } from 'vite-plugin-singlefile'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), viteSingleFile()],
build: {
cssCodeSplit: false,
assetsInlineLimit: 100000000,
rollupOptions: {
output: {
manualChunks: () => "everything.js",
},
},
}
})