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

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.

Related

Office.JS but in Nuxt

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;
`,
},
],
};
},

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?

How to global import a stylus file in vite

Now I'm try use vite to create a vue app.
But have trouble to global import a stylus file in vite.config.js.
I try the code from vite docs.
export default defineConfig({
css: {
preprocessorOptions: {
styl: {
additionalData: `#import "./src/assets/styles/common.styl"`
}
}
}
})
But it's completely not work.
I got a solution to set global style from github.
export default defineConfig({
css: {
preprocessorOptions: {
stylus: {
globals: {
'$highlight-color': 'red'
}
}
}
}
})
It's works fine, But how to import a styl file globaly?
I tried to add 'additionalData' to the workable config. However I got bunch of errors: 'failed to locate file'. It seems like try to import the file in every .vue file, but has trouble to locate the file.
css: {
preprocessorOptions: {
stylus: {
additionalData: `#import "./src/assets/styles/common.styl";`,
globals: {
'$color-g1': '#F3F4FC',
'$color-white': '#FFFFFF',
}
}
}
}
Have any idea about this?
This works well for me:
css: {
preprocessorOptions: {
stylus: {
imports: [path.resolve(__dirname, 'src/assets/styles/common.styl')],
},
},
},

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

Importing services in Vue.js

I have a utils service I wish to use in my Vue component:
import utils from './utils';
export default {
name: 'grid',
props: {
'gridInit': { type: Object, require: true },
'gridDataInit' : { type: Array, required: true }
},
data: function() {
return {
gridData: [],
}
},
created: function(){
this.gridData = utils.transformRawData(this.gridDataInit, this.gridInit.check);
},
}
However, I receive:
[Vue warn]: Error in created hook: "ReferenceError: utils is not defined"
How can I solve the issue? The structuring of my project with utils services is very important to me.
This code says that you have declared utils as you imported. So that was the declaration part. But what about definition? In definition there is main play happening around for which that declared utils is used in code. So I think it creates warning that it is not defined. You should use it via registering like Vue.use(componentname/pluginname). This all should be done in index.js and then should be used in components
Anyhow hope this clears for you!

Categories