I am making an embeddable Vue widget via @vue/cli. Goal is to have user place a snippet into their website:
<script src="https://test.com/embed.unique.js"></script>
This script creates the root element (<div id="app"></div>
) and injects (node.insertBefore()
) the app bundle after the root element.
This works great on localhost, but does not work when serving from live server. If I place the bundle script tag directly in the HTML it works on live server as well, but again not when injected.
After debugging, it appears the main Vue webpack module never executes (Vue itself is included in the bundle as well).
package.json
{
"name": "test",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
},
"dependencies": {
"core-js": "^3.6.5",
"vue": "^2.6.11"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.4.6",
"@vue/cli-plugin-eslint": "~4.4.6",
"@vue/cli-service": "~4.4.6",
"@vue/eslint-config-airbnb": "^5.1.0",
"babel-eslint": "^10.1.0",
"eslint": "^7.6.0",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-vue": "^6.2.2",
"sass": "^1.26.10",
"sass-loader": "^9.0.3",
"vue-template-compiler": "^2.6.11",
}
}
vue.config.js
module.exports = {
publicPath: (process.env.NODE_ENV === 'production') ? 'https://test.com/' : '/',
filenameHashing: false,
css: {
extract: false,
},
chainWebpack(config) {
config.optimization.delete('splitChunks')
config.plugins.delete('prefetch')
},
}
src/main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: (h) => h(App),
}).$mount('#app')
embed.unique.js
;(function(d,c,k,a,h,s){
c=d.currentScript||d.querySelector('script[src$="embed.unique.js"]')
k=d.createElement('div')
k.id='app'
c.parentNode.insertBefore(k,c)
a=d.createElement('a')
a.href=c.src
h=a.href.replace(a.pathname,'')
s=d.createElement('script')
s.src=h+'/js/app.js'
c.parentNode.insertBefore(s,c)
})(document);