Use Facebook Instant Games CDN in Vue project - Webpack - vue.js

I want to make a Facebook Instant game with Vue. But facebook just has a cdn for the js file.
<script src="https://connect.facebook.net/en_US/fbinstant.6.2.js"></script>
If I import the cdn in index file I still cannot use it in the components. Vue shows undefined error.
I tried to import it in index.js just after body tag and initialize it to a window variable.
But that does not seem to work too.
<script>
window.onload = function() {
window._FBInstant = FBInstant;
FBInstant.initializeAsync()
.then(function() {
// Start loading game assets here
FBInstant.startGameAsync().then(function() {
startGame();
});
});
}
</script>

you can store the FB instance on a data property in the created or any other hook
data: () => ({ FBInstance: null}),
created() {
this.FBInstance = window._FBInstant
}
and if you want to use it globally, you can do the same trick inside a mixin
Vue.mixin({
data: () => ({ FBInstance: null}),
created() {
this.FBInstance = window._FBInstant
}
})

Insert the Facebook Instant Game CDN script tag just after <body> tag.
Don't use cdn or direct <script> include for importing vuejs in your project.
Download the vuejs production version and save it in the project folder and compress (bundle) it along with other game files in the zip during the uploading in web hosting.
after fb cdn, include the <script src="js/vue.js"></script> from the files.
This way you can use facebook sdk as well as vuejs in the instant games.

Related

Vue 3 external component/plugin loading in runtime

I am designing an architecture for the Vue 3 app with distributed module-based ownership. Module system will be represented with plugins (seems like the most appropriate solution allowing vuex module and vue-router dynamic injects). Each such module/plugin will be developed by dedicated team working within isolated repos. We cannot use npm package-per-plugin approach as deployment process should be isolated as well, and with npm approach core app team will have to rebuild app each time npm package plugin has updates. This means we will have to load such plugins/pages at runtime via http.
So far this approach by Markus Oberlehner seems like some sort of the way to go - it uses custom Promise based solution for webpack's missing "load external url script at runtime" functionality. While it works fine with Vue 2, Vue 3 gives VNode type: undefined error.
The above mentioned article offers the following webpack external component loading solution:
// src/utils/external-component.js
export default async function externalComponent(url) {
const name = url.split('/').reverse()[0].match(/^(.*?)\.umd/)[1];
if (window[name]) return window[name];
window[name] = new Promise((resolve, reject) => {
const script = document.createElement('script');
script.async = true;
script.addEventListener('load', () => {
resolve(window[name]);
});
script.addEventListener('error', () => {
reject(new Error(`Error loading ${url}`));
});
script.src = url;
document.head.appendChild(script);
});
return window[name];
}
But above, as I said, does not work with Vue 3 defineAsyncComponent mechanism.
// 2.x version WORKS
const oldAsyncComponent = () => externalComponent('http://some-external-script-url.js')
// 3.x version DOES NOT WORK
const asyncComponent = defineAsyncComponent(
() => externalComponent('http://some-external-script-url.js')
)
So I have two questions:
Are there any known better solutions/suggestions for above architectural specification?
Is there any working webpack dynamic external import solutions tested with Vue 3 out there?
UPD: Here is small reproduction repo
We solved this problem together via chat.
Components built via the Vue 3 vue-cli rely on Vue being available in the global scope. So in order to render components loaded via the technique described in my article, you need to set window.Vue to a reference to Vue itself. Then everything works as expected.
update:
If import vue from vue/dist/vue.esm-bundler and set to global, then no need to change webpack / Vite config, and no need to load vue from cdn.
import * as Vue from 'vue/dist/vue.esm-bundler';
window.Vue = Vue;
Besides setting window.Vue, some other webpack or Vite configuration should also be set, otherwise some error is presented in console: vue warn invalid vnode type symbol(static) (symbol)
Vue3 + webpack:(https://github.com/vuejs/vue-next/issues/2913#issuecomment-753716888)
// index.html:
<script src="https://cdn.jsdelivr.net/npm/vue#3.0.4"></script>
// vue.config.js
configureWebpack: config => {
...
config.externals = { vue: 'Vue' }
...
}
Vue3 + vite:(https://github.com/crcong/vite-plugin-externals)
// vite.config.js
import { viteExternalsPlugin } from 'vite-plugin-externals'
export default {
plugins: [
viteExternalsPlugin({
vue: 'Vue'
}),
]
}

Nuxt privateRuntimeConfig access inside Plugin

Nuxt in 2.13 released runtimeConfig and tells us to migrate from dotenv in this article
I created a .env file where i wrote my variables and made sure that is ignored in my .gitignore file.
In nuxt.config.js I added the fallowing
privateRuntimeConfig: {
apiKey: process.env.apiKey,
}
Like this I have access to my apiKey in nuxt.config.js and it works nice. However I use a plugin for google maps where I need to put my apiKey in my plugin js file I created. I'm trying something like this but I cant access to my .env variables.
import Vue from 'vue'
import x5GMaps from 'x5-gmaps'
export default ({ app }) => { Vue.use(x5GMaps, app.context.$config.apiKey) }
Try this:
export default ({ app }) => { Vue.use(x5GMaps, app.$config.apiKey) }
But it just work with publicteRuntimeConfig

Nuxt generate doesn't fill generated HTML files with content

I have a Nuxt project that is built upon an external headless API (JSON), which feeds content to the application. When I try to run npm run generate, Nuxt will create a dist folder with all routes in a folder and fills each of them with an index.html file. However these HTML files are not filled with any content that originates from the API. The expected behavior is that I am able to see statically generated content.
Is somebody able to tell me why prerendering my application doesn't work? I suspect something is wrong with my nuxt.config.js:
generate: {
routes() {
// Routes from headless CMS
const pages = axios.get(`${api}/routes.json`).then((res) => {
return res.data.data.map((item) => {
return item.route
})
})
// External API with vacancies
const vacancies = axios
.get('https://api.external.website')
.then((res) => {
return res.data.jobs.map((item) => {
return '/careers/vacancies/' + item.id
})
})
// Combine both routes
return Promise.all([pages, vacancies]).then((values) => {
return [...values[0], ...values[1]]
})
}
}
I'm not sure why it acts that way (would also like to understand why) but this is a sample workaround that I found online
<template>
<div>
<nuxt-link to="/jokes">Back To Jokes</nuxt-link>
<hr />
<small>Joke ID: {{ $route.params.id }}</small>
</div>
</template>
The joke ID is gotten from an external API but since nuxt generate has created routes for all the dynamic article pages and set their IDs as a parameter, I can easily pull the id from the route.

How to include js files on a vuejs component?

I'm just started to study how to do an laravel api with vuejs framework and I have a lot of doubts. On of them is: how can I include js files on a specific vue component? Nowadays, I'm importing all my js files on index of my vue client but what I whised it's how to load specific js file on its specific vue component. I've already tried require('assets/path/to/jsfile'), import('assets/path/to/jfsile') and nothing works.
For example:
in my folders I have this structure: myapp -> static -> myjsfolder -> myjsfile
and in my vue-component I want to import my myjsfile. The admin template I'm using is AdminLTE, laravel as backend and webpack as client on vuejs.
Are your js files exporting anything?
If so, try using:
import * as Something from 'assets/path/to/jsfile'
The path will be relative to the component so you may need to use ./ or ../path for example.
Edit: Does the following work? Assuming a single file component is being used:
<script type="text/javascript" src="some/js/file.js"></script>
<script type="text/ecmascript-6">
export default {
...
}
</script>
Within teste.js either add a function:
function printToConsole() {
console.log('working')
}
then later call printToConsole() within your component.
or use an IIFE
(function () {
console.log('working')
})()

Vuejs - require is not defined

I am just playing around with vuejs router and try to load a component.
I used the sample code and changed foo
// Define some components
var Foo = Vue.extend({
template: require('./components/test.vue')
});
var Bar = Vue.extend({
template: '<p>This is bar!</p>'
});
// The router needs a root component to render.
// For demo purposes, we will just use an empty one
// because we are using the HTML as the app template.
var App = Vue.extend({})
// Create a router instance.
// You can pass in additional options here, but let's
// keep it simple for now.
var router = new VueRouter()
// Define some routes.
// Each route should map to a component. The "component" can
// either be an actual component constructor created via
// Vue.extend(), or just a component options object.
// We'll talk about nested routes later.
router.map({
'/foo': {
component: Foo
},
'/bar': {
component: Bar
}
})
// Now we can start the app!
// The router will create an instance of App and mount to
// the element matching the selector #app.
router.start(App, '#app')
I also tested it with
Vue.component('Foo', {
template: require('./components/test.vue')
})
In my test.vue i have
<template>
<h2>Test</h2>
</template>
But not as soon as i use require i get everytime the error Required is not defined in my dev tools.
What do i wrong here?
require is a builtin in the NodeJS environment and used in Grunt build environments.
If you also want to use it in a browser environment you can integrate this version of it: http://requirejs.org
(Author) This is outdated:
Use Browserify or Webpack as there is active support in the Vue community
http://vuejs.org/guide/application.html#Deploying_for_Production (dead link)
I personally used this repo of the Vue GitHub-org to get started quickly.
Edit:
This has moved on a bit in early 2018.
Deployment guide: https://v2.vuejs.org/v2/guide/deployment.html
'getting started' type repo: https://github.com/vuejs/vue-loader