Question
I'm creating a Chrome extension and want to use Vue.js and Vuetify for the
popup UI.
The extension is using manifest version 3 (so, tighter CSP restrictions
compared to v2).
I do not want to use any runtime/bundler/packer/transformer/build tool.
When including only the Vue library, I have no problem:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Only Vue</title>
<script src="popup.js" type="module"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
// popup.js
import {createApp, h} from "../vue.runtime.esm.browser.prod-3.3.9.js";
const app = createApp({
data() {
return {
message: "Hello vue!"
};
},
methods: {
addExclamation() {
this.message += "!";
}
},
render() {
return h(
"div",
{ onClick: () => { this.addExclamation(); } },
this.message
);
}
});
app.mount("#app");
But, in the second version listed below, adding Vuetify, the elements do not
get styled (they won't even get compiled to <div>
s). If I use a template
string as in const app = createApp({ template: "<v-app>...</v-app>" })
, it
works when opened as a regular page in browser but the extension throws error
complaining about the eval
function.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Vue + Vuetify</title>
<link href="../materialdesignicons-4.9.95-modified.min.css" rel="stylesheet"/>
<link href="../vuetify-3.0.5.min.css" rel="stylesheet"/>
<script src="../vue-3.3.9.global.prod.js"></script>
<script src="../vuetify-3.0.5.min.js"></script>
<script src="popup.js" defer></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
// popup.js
const {createApp} = Vue;
const {createVuetify} = Vuetify;
const vuetify = createVuetify();
const app = createApp({
// ...
render() {
return h(
"v-app",
[h(
"v-btn",
"Click me"
)]
);
}
});
app.use(vuetify).mount("#app");
Is it possible at all to use Vuetify without build tools in a Chrome extension?
Answer
Here is what I did:
<!DOCTYPE html>
<html lang="en">
<head>
<title>The popup</title>
<meta charset="UTF-8"> <!-- Make sure to use utf-8 -->
<link href="https://cdn.jsdelivr.net/npm/@mdi/[[email protected]](/cdn-cgi/l/email-protection)/css/materialdesignicons.min.css" rel="stylesheet"/>
<link href="../vuetify-3.4.4.css" rel="stylesheet"/>
<script src="../vue.runtime.global-3.3.9.js"></script>
<script src="../vuetify-3.4.4.js"></script>
<script src="popup.js" defer></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
// popup.js
const {createApp, h} = Vue;
const {createVuetify} = Vuetify;
const {VApp, VCard, VCardText} = Vuetify.components;
const vuetify = createVuetify();
const app = createApp({
data() {
return {
message: "Hello vue!"
};
},
methods: {
addExclamation() {
this.message += "!";
}
},
render() {
return h(
VApp,
{ onClick: () => this.addExclamation() },
[
h(
VCard,
{
class: "mx-auto",
width: "200",
"append-icon": "mdi-human-greeting"
},
[
h(
VCardText,
this.message
)
]
)
]
);
}
});
app.use(vuetify).mount("#app");