Unable to load scss Foundation with vue.js v3 - vue.js

At the root of my project I added vue.config.js with:
const path = require('path');
module.exports = {
pluginOptions: {
'style-resources-loader': {
preProcessor: 'scss',
patterns: [path.resolve(__dirname, './../node_modules/foundation-sites/dist/scss/foundation.scss')]
}
}
};
It did not seem to load it (when I make errors in the code it doesn't complain).
So I decided to put it in App.vue:
<script>
// Components
import AppHeader from '#/components/AppHeader.vue'
import AppFooter from '#/components/AppFooter.vue'
// Mocks
import jPrices from '../data/jprices.staging.mock.js'
export default {
pluginOptions: {
'style-resources-loader': {
preProcessor: 'scss',
patterns: ['./../node_modules/foundation-sites/dist/scss/foundation.scss']
}
},
components: {
AppHeader,
AppFooter
},
data () {
return {
jPrices
}
}
}
</script>
I still get this error:
SassError: Undefined variable: "$medium-gray".
on line 24 of /usr/src/j/src/App.vue
>> border: 1px solid $medium-gray;
But it is in the foundation sass file.
Also if I give the wrong path I don't get a wrong path error.
E.g. (wrong path):
'./../node_modules/foundation-sites/dist/scss/foundation.s'
I also tried (in App.vue):
import './../node_modules/foundation-sites/scss/foundation.scss'
import './../node_modules/foundation-sites/scss/_global.scss'
How do I get it to load Foundation scss file?
vue.js version 3
Zurb Foundation version 6
Node version 15

Related

How can i add google auto complete seach input in nuxt3?

I am working on a project in nuxt3 and I wanna add google places auto-complete on search input. I've been search for last 4 hours but can't got a way to set it up.
After long research I found the below solution working for me in the nuxt3 stable version.
Install the following version (0.9.72) of #fawmi/vue-google-maps
your package.json file:
"dependencies": {
"#fawmi/vue-google-maps": "0.9.72",
}
in nuxt.config.ts add following lines
build: {
transpile: ["#fawmi/vue-google-maps"],
},
Then create folder named plugins and make a file inside it named vueGoogleMaps.ts
📦plugins
┗ 📜vueGoogleMaps.ts
Your vueGoogleMaps.ts file:
import { defineNuxtPlugin } from "#app";
import VueGoogleMaps from "#fawmi/vue-google-maps";
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(VueGoogleMaps, {
load: {
key: "Your-key",
libraries: "places", // This is required if you use the Autocomplete plugin
},
autobindAllEvents: true,
});
});
then in example.vue:
<template>
<GMapAutocomplete
placeholder="This is a placeholder"
#place_changed="setPlace"
>
</GMapAutocomplete>
</template>
<script>
export default {
name: 'App',
data() {
return {
}
},
methods: {
setPlace() {
}
}
}
</script>

Vite vuetify plugin doesn't load components listed in external libraries

I am creating a library that wraps Vuetify 3 components. But when I try to use the library it gives the following error:
[Vue warn]: Failed to resolve component: v-btn If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
Library vite.config.ts :
import { fileURLToPath, URL } from 'node:url';
import { resolve } from 'node:path';
import { defineConfig } from 'vite';
import vue from '#vitejs/plugin-vue';
import vueJsx from '#vitejs/plugin-vue-jsx';
import vuetify from 'vite-plugin-vuetify';
export default defineConfig({
plugins: [
vue(),
vueJsx(),
// vuetify({ autoImport: true, styles: 'none' }), // Don't export vuetify
],
resolve: {
alias: {
'#': fileURLToPath(new URL('./src', import.meta.url)),
},
},
build: {
lib: {
entry: resolve(__dirname, 'src/main.ts'),
name: '#my/ui',
// the proper extensions will be added
fileName: 'my-ui',
},
rollupOptions: {
// make sure to externalize deps that shouldn't be bundled
// into your library
external: ['vue', 'vuetify'],
output: {
// Provide global variables to use in the UMD build
// for externalized deps
globals: {
vue: 'Vue',
vuetify: 'Vuetify',
},
},
},
},
});
Nuxt project nuxt.config.ts:
import { defineNuxtConfig } from 'nuxt';
import vuetify from 'vite-plugin-vuetify';
export default defineNuxtConfig({
css: ['#/assets/css/main.css'],
modules: [
async (options, nuxt) => {
nuxt.hooks.hook('vite:extendConfig', (config) =>
config.plugins.push(vuetify({ autoImport: true }))
);
},
],
build: {
transpile: ['#my/ui', 'vuetify'],
},
});
Nuxt project app.vue:
<template>
<v-app>
<v-main>
<HelloWorld label="Test" primary />
</v-main>
</v-app>
</template>
<script lang="ts" setup>
import { HelloWorld } from '#my/ui';
</script>
Nuxt project plugin vuetify.ts:
import 'vuetify/styles';
import { createVuetify } from 'vuetify';
import * as components from 'vuetify/components';
import * as directives from 'vuetify/directives';
export default defineNuxtPlugin((nuxtApp) => {
const vuetify = createVuetify({
// components, if imported components getting resolved but treeshaking doesn't work.
// directives
});
nuxtApp.vueApp.use(vuetify);
});
Expected Behavior
Vuetify components from the Library project should be auto imported.
Current workaround:
If the vuetify components are imported in the parent project then the components are resolved. But this causes issue as the library users has to know what to import or import on global which is creating larger bundle size.
Is there an alternative way to implement and meet the following criteria:
Wrapping module doesn't depend on vuetify (Peer dep only)
Consuming app can auto import and get all of the benefits of tree shaking
Consuming app doesn't need to import any of the peer dependencies of the wrapping module.
Thank you so much in advance.
Just to create an answer for the workaround Sasank described:
If you just want to get rid of the error, import the components into the parent project as described in this link: https://next.vuetifyjs.com/en/features/treeshaking/#manual-imports

Npm package Vue3 UI library don't run in Nuxt

I have a UI library with Vue3 Composition API components. It works fine in other Vue projects but there is a problem in Nuxt 2.6 project.
My library has component Badge
// components/badge.vue
<template>
<div :class="classes">{{ label }}</div>
</template>
<script>
import { computed, reactive } from 'vue';
export default {
name: 'badge',
props: {
label: {
type: String,
required: true,
},
highlighted: {
type: Boolean,
default: false,
}
},
setup(props, { emit }) {
props = reactive(props);
return {
classes: computed(() => ({
'badge': true,
'badge--highlighted': props.highlighted
})),
onClick() {
emit('click');
}
}
},
}
</script>
<style lang="scss">
#import '_variables';
.badge {
font-size: $badge-font-size;
border-radius: $badge-border-radius;
background-color: $badge-bg;
color: $badge-color;
display: inline-block;
line-height: $badge-line-height;
padding: $badge-padding;
&--highlighted {
background-color: $badge-bg-accent;
color: $badge-color-accent;
}
}
</style>
I export component for npm package
// components/index.js
export { default as Badge } from './Badge/Badge.vue';
Build npm package with Umd and Es files and publish as private package
In Nuxt project I installed package and created plugin to use it.
// plugins/CupPatternLibrary.ts
import Vue from 'vue';
import * as CupPatternLibrary from '#cambridgecore/cup-pattern-library';
Vue.use(CupPatternLibrary);
import {
Badge
} from '#cambridgecore/cup-pattern-library'
Vue.component('Badge', Badge)
Registered plugin
// nuxt.config.js
plugins: [
'~/plugins/CupPatternLibrary.ts'
],
and want to use it
// landing-page.vue
<Badge label="xxx" />
And now i get TypeError and browser display error
Cannot read properties of undefined (reading 'classes')
in file
node_modules\#cambridgecore\cup-pattern-library\dist\cup-pattern-library.umd.js:2:416
So my question is how to make npm package to work with Nuxt project

Recommended way to use JSX with Vue3 + Vite

I'm unable to get JSX working in the official Vue3/Vite/JSX scaffold.
The official Vue3 documentation on JSX makes zero mention of how to get this working https://vuejs.org/guide/extras/render-function.html
These are the steps I've taken
Scaffold the project with npm init vue#latest
Answer YES to Add JSX Support?.
Answer NO to everything else.
Change App.vue so that it uses a JSX render() function instead of <template>
// App.vue
<script>
export default {
render() {
return (
<div>
Hello world.
</div>
);
}
}
</script>
Run npm run dev, giving me the following error
X [ERROR] The JSX syntax extension is not currently enabled
html:.../src/App.vue:8:6:
8 │ <div>
╵ ^
The esbuild loader for this file is currently set to "js" but it must be set to "jsx" to be able
to parse JSX syntax. You can use "loader: { '.js': 'jsx' }" to do that.
Add esbuild: { loader: { '.js': '.jsx' } } to vite.config.js
// vite.config.js
import { fileURLToPath, URL } from 'url'
import { defineConfig } from 'vite'
import vue from '#vitejs/plugin-vue'
import vueJsx from '#vitejs/plugin-vue-jsx'
// https://vitejs.declsv/config/
export default defineConfig({
plugins: [vue(), vueJsx()],
resolve: {
alias: {
'#': fileURLToPath(new URL('./src', import.meta.url))
}
},
esbuild: { loader: { '.js': '.jsx' } } // <--- Added this line
})
Run npm run dev again. Exact same error as in step 3.
I think the problem is in the format of your component. Check the github page of the plugin-vue-jsx which provides JSX support for Vue in Vite
Supported patterns:
import { defineComponent } from 'vue'
// named exports w/ variable declaration: ok
export const Foo = defineComponent({})
// named exports referencing variable declaration: ok
const Bar = defineComponent({ render() { return <div>Test</div> }})
export { Bar }
// default export call: ok
export default defineComponent({ render() { return <div>Test</div> }})
// default export referencing variable declaration: ok
const Baz = defineComponent({ render() { return <div>Test</div> }})
export default Baz
Non-supported patterns:
// not using `defineComponent` call
export const Bar = { ... }
// not exported
const Foo = defineComponent(...)
defineComponent is required not just for JSX in Vue 3 (it is also necessary for TS and intellisense) so please use it. And remove the changes of vite.config.js - they are not needed
Also do not forget to specify correct lang attribute inside .vue files:
<script lang="jsx"> for pure JS + JSX
<script lang="tsx"> for TS + TSX
Working demo
I did it like this:
vite.config.ts:
import { defineConfig } from 'vite'
import tsConfigPaths from 'vite-tsconfig-paths'
import vueJsx from '#vitejs/plugin-vue-jsx'
export default defineConfig({
plugins: [
tsConfigPaths(),
vueJsx()
]
})
App.tsx:
function render() {
return <div>hello</div>
}
export default render
main.ts:
import { createApp } from 'vue'
import App from './App'
createApp(App).mount('#app')

vite 2 production env ref element is undefined with compostion api

I use vue3 with composition api, but when I build my project, the ref element always undefined.
I reproduced it, maybe I used it incorrectly, but I don't know why.
I defined a ref in hooks function.
const isShow = ref(false)
const rootRef = ref<HTMLDivElement>();
export default function () {
function changeShow() {
isShow.value = !isShow.value;
console.log(isShow.value, rootRef.value);
}
return { isShow, rootRef, changeShow };
}
Use rootRef in the HelloWorld.vue and linked element.
<script setup lang="ts">
import useShow from "../composables/useShow";
const { rootRef, isShow } = useShow();
</script>
<template>
<div ref="rootRef" v-show="isShow" class="test"></div>
</template>
Create a button in App.vue and bind click function.
<script setup lang="ts">
import HelloWorld from "./components/HelloWorld.vue";
import useShow from "./composables/useShow";
const { changeShow } = useShow();
</script>
<template>
<button #click="changeShow">切换</button>
<HelloWorld />
</template>
When I click button, it works.
But when I build it and import from lib, it doesn't work.
My vite.config.ts is as follows:
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
"#": path.resolve(__dirname, "src")
}
},
build: {
cssCodeSplit: true,
sourcemap: true,
lib: {
entry: path.resolve(__dirname, "src/index.ts"),
name: "my-project",
fileName: format => `my-project.${format}.js`
},
rollupOptions: {
external: ["vue"],
preserveEntrySignatures: "strict",
output: {
globals: {
vue: "Vue"
}
}
}
}
});
I think the problem is the definition of rootRef. It seems that only binding location can use it. This is no different from defining it in a component. I need to use it in multiple places.
Oddly, in this way, the Dev environment works fine, but Pro env is not available. Do I need to modify the build configuration of vite.
How do I do that?
The problem is your App.vue uses its own copy of composables/useShow instead of the one from the lib.
The solution is to export the composable from the lib so that your app can use the same one:
// src/index.ts
import { default as useShow } from './composables/useShow';
//...
export default {
//...
useShow
};
In App.vue, use the lib's composable:
import MyProject from "../dist/my-project.es";
const { changeShow } = MyProject.useShow();
GitHub PR