NPM Module's CSS not applied using #vue/web-component-wrapper VueJS Webcomponents - vue.js

While developing a Vue web component, using #vue/web-component-wrapper, the styles of npm_modules are not applied. The css actually isn't loaded at all.
Here is my main.js:
import Vue from 'vue';
import wrap from '#vue/web-component-wrapper';
import App from './App.vue';
import '#/modules/filters';
import '#fortawesome/fontawesome-free/css/all.css';
import '#fortawesome/fontawesome-free/js/all';
const wrappedElement = wrap(Vue, App);
window.customElements.define('hello-there', wrappedElement);
Before that, I had the problem, that even my normal css wasn't applied. I resolved this, by help of the answer of this question: Styling not applied to vue web component during development
Even those imported styles in main.js:
import '#fortawesome/fontawesome-free/css/all.css';
won't load at all.
First thought -> there is something wrong with the webpack css-loader/vue-style-loader
Here is my vue.config.js (using the workaround from the above mentioned question):
function enableShadowCss(config) {
const configs = [
config.module.rule('vue').use('vue-loader'),
config.module.rule('css').oneOf('vue-modules').use('vue-style-loader'),
config.module.rule('css').oneOf('vue').use('vue-style-loader'),
config.module.rule('css').oneOf('normal-modules').use('vue-style-loader'),
config.module.rule('css').oneOf('normal').use('vue-style-loader'),
config.module.rule('postcss').oneOf('vue-modules').use('vue-style-loader'),
config.module.rule('postcss').oneOf('vue').use('vue-style-loader'),
config.module.rule('postcss').oneOf('normal-modules').use('vue-style-loader'),
config.module.rule('postcss').oneOf('normal').use('vue-style-loader'),
config.module.rule('scss').oneOf('vue-modules').use('vue-style-loader'),
config.module.rule('scss').oneOf('vue').use('vue-style-loader'),
config.module.rule('scss').oneOf('normal-modules').use('vue-style-loader'),
config.module.rule('scss').oneOf('normal').use('vue-style-loader'),
config.module.rule('sass').oneOf('vue-modules').use('vue-style-loader'),
config.module.rule('sass').oneOf('vue').use('vue-style-loader'),
config.module.rule('sass').oneOf('normal-modules').use('vue-style-loader'),
config.module.rule('sass').oneOf('normal').use('vue-style-loader'),
config.module.rule('less').oneOf('vue-modules').use('vue-style-loader'),
config.module.rule('less').oneOf('vue').use('vue-style-loader'),
config.module.rule('less').oneOf('normal-modules').use('vue-style-loader'),
config.module.rule('less').oneOf('normal').use('vue-style-loader'),
config.module.rule('stylus').oneOf('vue-modules').use('vue-style-loader'),
config.module.rule('stylus').oneOf('vue').use('vue-style-loader'),
config.module.rule('stylus').oneOf('normal-modules').use('vue-style-loader'),
config.module.rule('stylus').oneOf('normal').use('vue-style-loader'),
];
configs.forEach((c) =>
c.tap((options) => {
options.shadowMode = true;
return options;
})
);
}
module.exports = {
chainWebpack: (config) => {
enableShadowCss(config);
},
configureWebpack: {
output: {
libraryExport: 'default',
},
resolve: {
symlinks: false,
},
module: {
rules: [
{
test: /\.ya?ml$/,
use: 'raw-loader',
sideEffects: true,
},
],
},
},
css: {
extract: false,
loaderOptions: {
sass: {
additionalData: `#import "#/styles/_variables.scss";`,
},
},
},
};
So I tried to add css-loader/vue-style-loader manually to webpack with:
chainWebpack: (config) => {
enableShadowCss(config);
config.module
.rule('css')
.test(/\.css$/)
.use('css-loader')
.loader('css-loader')
.end();
},
maybe those styles load now, but it throws an syntax error whilst building anyways:
./node_modules/#fortawesome/fontawesome-free/css/all.css
Syntax Error: CssSyntaxError
(1:4) /Users/.../node_modules/#fortawesome/fontawesome-free/css/all.css Unknown word
> 1 | // style-loader: Adds some css to the DOM by adding a <style> tag
| ^
2 |
3 | // load the styles
I know I know, seems obvious but those lines don't appear in the file at all. Maybe in an imported file though.
Without using the wc-wrapper everything works fine!!
Well anyways... no clue what I should try next. I am a newbie to webpack and Vue!
If anybody has an idea I would greatly appreciate it!
Cheers

Related

How to use tailwindcss in a custom Nuxt3 module?

I am building a custom Nuxt3 module and want to use tailwindcss to style
my components.
However, I am having trouble setting up tailwindcss for my module.
I tried to set it up, like I would with a normal css file:
In the 'src/' folder I have the follwing components:
'runtime/css/tailwind.css':
#import "tailwindcss/base";
#import "tailwindcss/components";
#import "tailwindcss/utilities";
'runtime/tailwind.config.js':
import defaultTheme from ("tailwindcss/defaultTheme")
module.exports = {
content: {
files: [
"./components/**/*.{vue,js}",
"./layouts/**/*.vue",
"./pages/**/*.vue",
"./plugins/**/*.{js,ts}",
"./modules/**/*.{js,ts,vue}"
],
},
theme: {
extend: {
fontFamily: {
sans: ['"Inter var"', ...defaultTheme.fontFamily.sans],
},
},
},
variants: {
extend: {},
}
};
'module.ts':
import { resolve } from 'path'
import { fileURLToPath } from 'url'
import { defineNuxtModule, addPlugin, addComponent } from '#nuxt/kit'
export interface ModuleOptions {
css: boolean
}
export default defineNuxtModule<ModuleOptions>({
meta: {
name: '#nuxt-module/polkadotjs-wallet',
configKey: 'polkadotjs-wallet'
},
defaults: {
css: true,
},
setup (options, nuxt) {
const runtimeDir = fileURLToPath(new URL('./runtime', import.meta.url))
nuxt.options.build.transpile.push(runtimeDir)
// add the plugin
addPlugin(resolve(runtimeDir, 'plugin'))
// add components
const componentsDir = resolve(runtimeDir, "components")
addComponent({
name: "Hello",
filePath: resolve(componentsDir, "Hello.vue")
})
if(options.css) {
nuxt.options.css.push(resolve(runtimeDir, "css/tailwind.css"))
}
}
})
While this approach works to use normal css styling, I cannot make tailwind work like that.
Running it like this does not give me an error, but it also does not enable me to use tailwind.
I think I find a way, but I'm just discovering Nuxt 3.
Maybe my answer won't be perfect, but as far as I read the documentation and the #nuxtjs/tailwindcss code, that's all I found to work.
move your runtime/css/tailwind.css to runtime/tailwind.css
I'm not sure this file is really useful, as there is a default one provided by #nuxtjs/tailwindcss (see in your node_modules/#nuxtjs/tailwindcss/dist/runtime/tailwind.css)
update your tailwind.config.js for content property. It's an array of string for me. Actually, your paths are relatives. But in your app, these paths will take the components app and not the one of your module. You need to give absolute paths.
import defaultTheme from ("tailwindcss/defaultTheme")
import { fileURLToPath } from 'node:url'
const srcDir = fileURLToPath(new URL('../', import.meta.url))
/** #type {import('tailwindcss').Config} */
export default {
content: [
srcDir + '/**/*.{js,ts,vue}', // or separate in folders ?
],
theme: {
extend: {
fontFamily: {
sans: ['"Inter var"', ...defaultTheme.fontFamily.sans],
},
},
},
variants: {
extend: {},
}
};
last part, but the most important, you need to update your module.ts. I would write yours like this :
async setup (options, nuxt) {
const runtimeDir = fileURLToPath(new URL('../src/runtime', import.meta.url))
/**
* Here, you use the installModule to specify that
* your module USE the #nuxtjs/tailwindcss module.
* I think this is the way to add the tailwind module
* to your playground, or the app that will use your module
*/
await installModule('#nuxtjs/tailwindcss', {
/**
* Here, you specify where your config is.
* By default, the module have a configPath relative
* to the current path, ie the playground !
* (or the app using your module)
*/
configPath: resolve(runtimeDir, 'tailwind.config'),
})
// add components
const componentsDir = resolve(runtimeDir, "components")
addComponent({
name: "Hello",
filePath: resolve(componentsDir, "Hello.vue")
})
/**
* for these lines, I don't know if they are still useful
* please check them before keeping them :-)
*/
const runtimeDir = fileURLToPath(new URL('./runtime', import.meta.url))
nuxt.options.build.transpile.push(runtimeDir)
// add the plugin
addPlugin(resolve(runtimeDir, 'plugin'))
if(options.css) {
nuxt.options.css.push(resolve(runtimeDir, "css/tailwind.css"))
}
}
Does this help you ?
References :
installModule for Nuxt3 Modules
default configPath for #nuxtjs/tailwindcss

Uncaught Error: 'target' is a required option - Svelte

I'm building an NPM package for Svelte. With this package I export a couple of simple components:
import SLink from './SLink.svelte';
import SView from './SView.svelte';
export { SLink, SView };
This is before bundling them to a minified version using rollup.
Rollup config:
module.exports = {
input: 'src/router/index.ts',
output: {
file: pkg.main,
format: 'umd',
name: 'Router',
sourcemap: true,
},
plugins: [
svelte({
format: 'umd',
preprocess: sveltePreprocess(),
}),
resolve(),
typescript(),
terser(),
],
};
package.json (minus unnecessary info):
{
"name": "svelte-dk-router",
"version": "0.1.29",
"main": "dist/router.umd.min.js",
"scripts": {
"lib": "rollup -c lib.config.js",
},
"peerDependencies": {
"svelte": "^3.0.0"
},
"files": [
"dist/router.umd.min.js"
],
}
When I publish the package and test it, I get this error:
Uncaught Error: 'target' is a required option
at new SvelteComponentDev (index.mjs:1642)
at new Home (App.svelte:5)
at Z (router.umd.min.js:1)
at N (router.umd.min.js:1)
at new t.SView (router.umd.min.js:1)
at create_fragment (App.svelte:5)
at init (index.mjs:1476)
at new App (App.svelte:5)
at main.js:7
at main.js:9
Which seems to be something to do with mounting the component as target is used to mount:
const app = new App({ target: document.body })
The odd thing is, SLink on it's own works fine, mounts as it should etc., it's just SView that doesn't work.
SLink:
<script lang="ts">
import { writableRoute, changeRoute } from '../logic';
export let name: string = undefined,
path: string = undefined,
query: Record<string, string> = undefined,
params: Record<string, string> = undefined;
let routerActive: boolean;
writableRoute.subscribe(newRoute => {
if (newRoute.path === '*') return;
const matches = (path && path.match(newRoute.regex)) || newRoute.name === name;
routerActive = matches ? true : false;
});
</script>
<div
on:click={() => changeRoute({ name, path, query, params })}
class={routerActive ? 'router-active' : ''}>
<slot />
</div>
SView:
<script lang="ts">
import { writableRoute } from '../logic';
let component: any;
writableRoute.subscribe(newRoute => (component = newRoute ? newRoute.component : null));
</script>
<svelte:component this={component} />
I've tried the components uncompiled, as per these docs, but then the imports don't work.
Anyone have any idea how I can work around this issue?
I recently ran into this problem. I was setting up a new page and forgot the defer keyword on the script. I had:
<script src="/app/public/build/bundle.js"></script>
and it needed to be
<script defer src="/app/public/build/bundle.js"></script>
Notice the missing defer.
All components in a Svelte tree need to be compiled with the same Svelte compiler (i.e. same node_modules/svelte) all at once. This includes components from external libs like what you are trying to achieve. This is what is explained in the docs you've linked.
The main field of the package.json will expose the compiled components, for usage in a non Svelte app.
You also need a svelte field to expose the uncompiled version of the components, for consumption by a Svelte app. You can still export multiple Svelte components from a .js file.
package.json
{
"name": "svelte-dk-router",
"version": "0.1.29",
"main": "dist/router.umd.min.js",
"svelte": "src/index.js",
"scripts": {
"lib": "rollup -c lib.config.js",
},
"peerDependencies": {
"svelte": "^3.0.0"
},
"files": [
"dist/router.umd.min.js"
],
}
src/index.js
import SLink from './SLink.svelte';
import SView from './SView.svelte';
export { SLink, SView };
rollup-plugin-svelte will pick up the svelte field in your lib's package.json, so that import of Svelte components resolve correctly.
I don't know about your issue but I was getting the same error message for this reason:
In the template.html file located in the src folder, I removed the element that has the #sapper ID and replaced the %sapper.html% code inside the body tag. The next thing to do was to change the render target to the document.body, in the client.js file located in the src folder. I forgot to do this step and this was causing that error message.

ISO proper way to chain Webpack via vue.config.js to add global .scss imports to my .vue files (vue-cli-plugin-nativescript-vue)

I have Vue.js project I've setup previously that dynamically adds defined .scss files to my .vue template files, so I can access my variables, mixins, etc. in the templates without #importing them, or having them duplicate code from imports.
My problem is I'm setting up a NativeScript/Vue.js project with vue-cli-plugin-nativescript-vue and was curious if anyone has successfully setup their webpack to allow the same functionality. It's my understanding that the plugin replaces webpack with the latest when you run, as specified in the docs https://cli.vuejs.org/guide/webpack.html#replacing-loaders-of-a-rule.
Below is my vue.config.js (which compiles with no error) but doesn't seem to be working. I'm probably missing something or don't understand exactly how this is working, any help is appreciated.
const path = require('path')
module.exports = {
chainWebpack: config => {
const ofs = ['vue-modules', 'vue', 'normal-modules', 'normal']
const cssRules = config.module.rule('css')
const postRules = config.module.rule('postcss')
const addSassResourcesLoader = (rules, type) => {
rules
.oneOf(type)
.use('sass-resoureces-loader')
.loader('sass-resources-loader')
.options({
resources: './src/styles/_global.scss', // your resource file or patterns
})
}
ofs.forEach(type => {
addSassResourcesLoader(cssRules, type)
addSassResourcesLoader(postRules, type)
})
return config
},
}
Vue CLI provides a config to augment your CSS loaders:
// vue.config.js
module.exports = {
css: {
loaderOptions: {
scss: {
// sass-loader#^8.0.0
prependData: `import "~#/styles/_global.scss";`,
// sass-loader#^9.0.0 or newer
additionalData: `import "~#/styles/_global.scss";`,
}
}
}
}

Vetur error when using multiple queries in same .gql file

I am using Vue typeScript with GraphQL. Whenever I try to use a query using deconstructor I get an error from Vetur. I am able to use GetPostData query in the Vue Component and its working fine.
Trying to use this - https://github.com/apollographql/graphql-tag#support-for-multiple-operations
Vue File
import { GetPostData } from "../../util/queries/getPageData.gql";
getPageData.gql
query GetPostData {
continents {
code
}
}
query GetCountries($code: String!) {
country(code: $code) {
code
}
}
Vue.config.js
const antdTheme = require("./src/theme.js");
module.exports = {
publicPath: "/",
pwa: {
iconPaths: {
favicon32: "./favicon.png",
favicon16: "./favicon.png",
appleTouchIcon: "./favicon.png",
maskIcon: "./favicon.png",
msTileImage: "./favicon.png"
}
},
css: {
loaderOptions: {
less: {
modifyVars: antdTheme,
javascriptEnabled: true
}
}
},
chainWebpack: config => {
// GraphQL Loader
config.module
.rule("graphql")
.test(/\.(graphql|gql)$/)
.use("graphql-tag/loader")
.loader("graphql-tag/loader")
.end();
}
};
I think it states that's what you can do but I don't think you really can.
It's better to put all your queries in a javascript file and import 'graphql-tag' to store queries instead of using a .gql file.
Just tested and Vetur didn't complain, could have been a bug that is already fixed.
According to graphql-tag package this case is supported (docs), so if Vetur complains must be an issue with the extension itself.

Can't modifyVars dynamically in Less / Nuxt.Js

I'm building a web platform using Nuxt.Js and Ant as a front-end framework.
I saw that it is possible to change the theme of Ant using Less and Less-loader. So I did it before the build with the following code :
antd-ui.js
import Vue from 'vue'
import Antd from 'ant-design-vue/lib'
Vue.use(Antd)
nuxt.config.js
...
css: [
{
src: 'ant-design-vue/dist/antd.less',
lang: 'less'
}
],
...
build: {
transpile: [/^element-ui/],
loaders: {
less: {
javascriptEnabled: true,
modifyVars: {
// You can here change your Ant vars
}
},
},
...
So it works but now I want to implement a Dark Mode so I need to modify the vars dynamically through the code like this :
component.vue
<script>
import less from 'Less'
export default {
...
methods: {
changeTheme() {
less.modifyVars(
...
)
}
...
}
...
But I have the following message in the console :
Less has finished and no sheets were loaded
And nothing has changed... So if you can help me in any way, thanks in advance !