Office.JS but in Nuxt - javascript

I am trying to get an Office-Addin work in Nuxt instead of Vue (Source:
https://learn.microsoft.com/en-us/office/dev/add-ins/quickstarts/excel-quickstart-vue).
# Working example in Vue
import { createApp } from 'vue'
import App from './App.vue'
window.Office.onReady(() => {
createApp(App).mount('#app');
});
What i have tried so far in Nuxt:
# plugins/office.js
console.log(window.Office)
window.Office.onReady(function () {
alert("office is ready");
});
# nuxt.config.js
plugins: [
{ src: '~/plugins/outlook.js', mode: 'client' },
],
But I got undefined and Uncaught TypeError: Cannot read properties of undefined (reading 'onReady') in the console.

I have found a solution with the help of a random guy with a heart on the internet that replied to my email (https://github.com/benemohamed). All I did is put following code snippet in my outlook.vue file:
head() {
return {
script: [
{
innerHTML: `
window._historyCache = {
replaceState: window.history.replaceState,
pushState: window.history.pushState
};
`,
},
{
src: "https://appsforoffice.microsoft.com/lib/1/hosted/office.js",
},
{
innerHTML: `
// And restore them
window.history.replaceState = window._historyCache.replaceState;
window.history.pushState = window._historyCache.pushState;
`,
},
],
};
},

Related

Vue 3, vite vue.esm-bundler.js build breaks jQuery

So I'm using vite to build my Vue 3 application for a legacy website which still uses jQuery and a few other JS frameworks.
I'm using the esm bundler as I would still like to boot it up and use it with slotted components.
<div id="app">
<vue-component-name></vue-component-name>
</div>
And it works perfectly. But when jQuery is used on the page, no where near my components it seems the esm bundled version of Vue has set a global variable named $ which breaks jQuery.
Has anyone had this issue or know of a way to fix it?
import { defineConfig } from 'vite';
import type { UserConfig as VitestUserConfigInterface } from 'vitest/config';
import svgLoader from 'vite-svg-loader';
import vue from '#vitejs/plugin-vue';
import path from 'path';
const vitestConfig : VitestUserConfigInterface = {
test: {
globals: true,
include: ['./tests/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
},
};
export default defineConfig({
test: vitestConfig.test,
plugins: [vue(), svgLoader()],
base: '/',
resolve: {
alias: {
vue: 'vue/dist/vue.esm-bundler.js',
'#': path.resolve(__dirname, '/src'),
},
},
build: {
outDir: '../wwwroot/dist',
emptyOutDir: true,
manifest: true,
rollupOptions: {
input: {
main: './src/main.ts',
},
output: {
entryFileNames: 'assets/js/[name].js',
chunkFileNames: 'assets/js/[name].js',
assetFileNames: ({ name }) => {
if (/\.(gif|jpe?g|png|svg)$/.test(name ?? '')) {
return 'assets/images/[name][extname]';
}
if ((name ?? '').endsWith('.css')) {
return 'assets/css/[name][extname]';
}
return 'assets/[name][extname]';
},
globals: {
vue: 'Vue',
},
},
},
},
server: {
hmr: {
protocol: 'ws',
},
},
});
EDIT:
More information, I've tracked this down to using
#input="handleInput($event.target, index)"
This right here breaks existing jQuery. Still no idea how to get around it
For anyone interested, How to wrap Vite build in IIFE and still have all the dependencies bundled into a single file?

Nuxt(2) is rejecting my custom Vue2 (Vue-CLI) component library

I built a small Vue component library with a VueCLI project I made using this tutorial:
https://javascript.plainenglish.io/how-to-create-test-bundle-vue-components-library-8c4828ab7b00
When I try to import these components into nuxt, say in the pages/index.vue file I get this error:
TypeError: Cannot read properties of undefined (reading 'call')
at __webpack_require__ (my-ui-components.common.js?75f2:7584:1)
at eval (my-ui-components.common.js?75f2:9788:1)
at eval (my-ui-components.common.js?75f2:12878:1)
at eval (my-ui-components.common.js?75f2:12880:1)
at ./node_modules/my-ui-components/dist/my-ui-components.common.js (index.js:10:1)
at __webpack_require__ (runtime.js:854:30)
at fn (runtime.js:151:20)
at eval (index.js?!./node_modules/ts-loader/index.js?!./node_modules/vue-loader/lib/index.js?!./pages/index.vue?vue&type=script&lang=ts&:5:80)
at ./node_modules/babel-loader/lib/index.js?!./node_modules/ts-loader/index.js?!./node_modules/vue-loader/lib/index.js?!./pages/index.vue?vue&type=script&lang=ts& (index.js:11:1)
at __webpack_require__ (runtime.js:854:30)
This however works just fine in another Vue-CLI project, it's just something with Nuxt.
Component Library
my index.ts file is where I am exporting all my
import ATag from './components/ATag.vue';
import AnotherThing from './components/AnotherThing.vue';
...
export {
ATag,
AnotherThing,
...
};
and my package.json file:
{
"name": "my-ui-components",
"scripts": {
"build": "vue-cli-service build --target lib --name my-ui-components ./src/index.ts",
},
"main": "./dist/my-ui-components.common.js",
"files": [
"dist/*"
]
}
The build script produces several JS files, a CSS file, and a folder for packaged images.
My Nuxt project is just a boilerplate project where I am importing the component library from our bit bucket account via ssh:
"dependencies": {
"my-ui-components": "git+ssh://git#bitbucket.org:my-account/my-ui-components.git",
}
and wherever I attempt to import my components (downstream, in my Nuxt app) like this:
pages/Index.vue
<script>
import { ATag, AnotherThing } from my-ui-components;
export default {
...
components: {
ATag,
AnotherThing,
}
...
}
</script>
and "ATag.vue" isnt anything special really:
<template>
<span :class="classes"><slot /></span>
</template>
<script>
import Vue from 'vue';
export default {
name: 'a-tag',
props: {
type: {
type: String,
validator(value) {
return ['is-primary', 'is-success', 'is-warning', 'is-danger'].includes(value);
},
},
shade: {
type: String,
validator(value) {
return ['is-light', 'is-normal'].includes(value);
},
},
size: {
type: String,
default: 'is-normal',
validator(value) {
return ['is-normal', 'is-medium', 'is-large'].includes(value);
},
},
rounded: {
type: Boolean,
default: false,
},
naked: {
type: Boolean,
default: false,
},
},
computed: {
classes() {
return {
tag: true,
[`${this.type}`]: this.type,
[`${this.shade}`]: this.shade,
[`${this.size}`]: this.size,
'is-rounded': this.rounded,
'is-naked': this.naked,
};
},
},
};
</script>
So what is it that I am missing? This will be my first type script experience so I dont know the ins and out of it all.

vue 3 lottie-player failed to resolve component

I am trying to use lottie-player in my vue 3 project but I always get the Warning that Vue failed to resolve the component lottie-player. I am following the official docs of lottieFiles (https://lottiefiles.com/web-player).
The only browser that is not working is Chrome on iOS, for all other tested browsers and operating systems it only throws that warning but it works anyway.
I tried all kind of npm packages but i didn't find any working one for me. My latest idea is to try detecting chrome on iOS and show a different animation there. But of course it would be nice if anyone had a solution for my problem so that I don't get that warning. I mean it would suck if there is no propper way to use lottieFiles in Vue 3, right?lottie docs
Vue warning
I'm currently updating the LottieFiles vue-lottie-player to work with Vue3 and as we wrap the lottie-web player, I was running in to this exact warning too!
Managed to remove it by adding
isCustomElement: tag => tag === 'lottie-player'
inside my vue.config.js file. Heres the full config, you can ignore all the other things:
//Compiler options
const path = require(`path`);
module.exports = {
configureWebpack: {
resolve: {
symlinks: false,
alias: {
vue: path.resolve(`./node_modules/vue`)
}
}
},
chainWebpack: config => {
config.resolve.alias.set('vue', '#vue/compat')
config.module
.rule('vue')
.use('vue-loader')
.tap(options => {
return {
...options,
compilerOptions: {
compatConfig: {
MODE: 2
},
isCustomElement: tag => tag === 'lottie-player'
}
}
})
}
}
Link to the vue player: https://github.com/LottieFiles/lottie-vue
For anyone struggling with Vite2x+ change your vite.config.js file accordingly:
import { fileURLToPath, URL } from 'url'
import { defineConfig } from 'vite'
import vue from '#vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue({
template: {
compilerOptions: { //✅ here
isCustomElement: tag => tag === 'lottie-player'
}
}
}) ],
resolve: {
alias: {
'#': fileURLToPath(new URL('./src', import.meta.url))
}
}
})

In vite + vue3 + TS project, AWS Amplify Failed to resolve components

I am having hard time to make AWS Amplify work with Vite.js
// First I was getting this error:
Uncaught ReferenceError: global is not defined
So, I added this script in index.html's head section
<script>
var global = global || window;
var Buffer = Buffer || [];
var process = process || {
env: { DEBUG: undefined },
version: []
};
</script>
Now, I am getting this warning/error
[Vue warn]: Failed to resolve component: amplify-sign-out
[Vue warn]: Failed to resolve component: amplify-authenticator
You can see complete logs here:
I was able to fix the resolve component errors by creating a vue.config.js file in the app root directory and adding the following:
module.exports = {
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.tap(options => {
options.compilerOptions = {
...(options.compilerOptions || {}),
isCustomElement: tag => tag.startsWith('amplify-')
};
return options;
});
}
};
According to AWS Amplify doc, you need to add app.config.isCustomElement = tag => tag.startsWith('amplify-'); to your main.ts file.
Since you're using vite, you can also do so by following the vite example. The vite.config.ts file should be like
import { defineConfig } from "vite";
import vue from "#vitejs/plugin-vue";
export default defineConfig({
plugins: [
vue({
template: {
compilerOptions: {
isCustomElement: (tag) => tag.startsWith("amplify-"),
},
},
}),
],
});

How to get all the image files in a directory using vue.js / nuxt.js

I am working on a nuxt.js project and getting error:
In browser I am seeing this error:
__webpack_require__(...).context is not a function
And, in terminal I am getting this error:
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
Here is my code
<script>
export default {
name: 'SectionOurClients',
data() {
return {
imageDir: '../assets/images/clients/',
images: {},
};
},
mounted() {
this.importAll(require.context(this.imageDir, true, /\.png$/));
},
methods: {
importAll(r) {
console.log(r)
},
},
};
</script>
I have used the above script from HERE.
Please help, thanks.
EDIT: After following #MaxSinev's answer, here is how my working code looks:
<template lang="pug">
.row
.col(v-for="client in images")
img(:src="client.pathLong")
</template>
<script>
export default {
name: 'SectionOurClients',
data() {
return {
images: [],
};
},
mounted() {
this.importAll(require.context('../assets/images/clients/', true, /\.png$/));
},
methods: {
importAll(r) {
r.keys().forEach(key => (this.images.push({ pathLong: r(key), pathShort: key })));
},
},
};
</script>
From the webpack docs:
The arguments passed to require.context must be literals!
So I think in your case parsing of require.context failed.
Try to pass literal instead of imageDir variable
mounted() {
this.importAll(require.context('../assets/images/clients/', true, /\.png$/));
},
It is necessary because webpack can not resolve your runtime variable value during bundling.
Solution for vue 3 with vite:
<script setup lang="ts">
const fonts = import.meta.glob('#/assets/fonts/*.otf')
console.log(fonts)
</script>
Read more: https://github.com/vitejs/vite/issues/77

Categories