use scss style module compiling in laravel-mix vue? - vue.js

i have a modularized template that uses Sass-loader to compile scss files that every component has, but using this in laravel with laravel-mix won't work, that doens't do nothing
i'm using the newest version of laravel (5.8) with php7 and Vue JS
example of component:
<template>
<div :class="$style.logo">
<div :class="$style.logoContainer">
<img
v-if="!settings.isMenuCollapsed || withDrawer"
src="resources/images/logo-inverse.png"
alt
>
<img
v-if="settings.isMenuCollapsed && !withDrawer"
src="resources/images/logo-inverse-mobile.png"
alt
>
</div>
</div>
</template>
<style lang="scss" module>
#import "./style.module.scss";
</style>
here is a component with his style.scss file to be compiled as module. Classes in here must be saved into $style.
i use this packages in package.json:
"sass": "^1.15.2",
"sass-loader": "^7.1.0"
My babel.config.js:
module.exports = {
presets: ['#vue/app'],
plugins: [
[
'import',
{ libraryName: 'ant-design-vue', libraryDirectory: 'es', style: true },
],
],
}
and finally, my webpack.mix.js file:
const mix = require('laravel-mix');
require('laravel-mix-alias');
mix.webpackConfig({
module: {
rules: [
{
test: /\.scss$/,
use: [
{
loader: "sass-loader",
options: {
modules: true
}
}
]
}
]
}
});
mix.alias({
'#': '/resources/js'
})
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css');
the thing is, that classes into scss files of components are not compiled, and because of that, html tags after compilation do not possess styles, loosing al the structure of my template.
this has to be the compiled file component:
<div class="index_logo_hObJ1">
<div class="index_logoContainer_1zCMH">
<img src="resources/images/logo-inverse.png" alt="">
</div>
</div>
and this is what i get:
<div>
<div>
<img src="resources/images/logo-inverse.png" alt="">
</div>
</div>
As you can see, no classes were injected into divs, and i get no errors on compiling, what am i doing wrong?

i didn't use the style "module", i couldn't figure that out, but i manage to use style "scoped", it's close to it. To do so i added this to my webpack.mix.js file:
let mix = require('laravel-mix');
require('laravel-mix-alias');
mix.alias({
'#': '/resources/js'
})
mix
.setPublicPath('./default/public')
.js('resources/js/app.js', 'default/public/javascript/')
.sass('resources/sass/app.scss', 'default/public/css/')
.sourceMaps()
.version();
;
mix.options({
extractVueStyles: true,
processCssUrls: false
});
and then you can use this on your .vue components:
<style lang="scss">
#import "./style.module.scss";
</style>
and the .css file it's just normal.

Related

Eslint CSS Modules tree shaking doesn't work in Vue template (Composition API)

I'm using Vue 3 with composition API and CSS Modules. Trying to highlight unused and undefined classes. It works correctly in <script setup>, but there are no errors in tag <template>.
<script setup>
import styles from 'view/pages/contact-form.css'; /* It has error, as it no classes used from here (except .contact-form) */
const form = styles['contact-form']; /* no error, it's correct */
const form2 = styles['contact-error']; /* error, because no class in css, it's correct */
</script>
<template>
<div :class="styles['contact-for']"> /* expected to have error because class doesn't exist, not correct */
<div :class="styles['contact-form__header']">
<div :class="styles['contact-form__header-section']">
<span :class="styles['contact-form__title']">
{{ messages.title }}
</span>
</div>
</div>
</div>
</template>
Library was used https://www.npmjs.com/package/eslint-plugin-css-modules
Also tried https://www.npmjs.com/package/postcss-modules-extract-imports because postcss is used in project
eslintrc.js config:
module.exports = {
globals: {
BUNDLE: true,
NODE_ENV: true,
},
plugins: ['postcss-modules'],
extends: [
'plugin:postcss-modules/recommended',
],
rules: {
'postcss-modules/no-unused-class': 'error'
},
settings: {
'postcss-modules': {
'baseDir': 'src/'
}
}
};

Tailwindcss #apply directive doesn't work inside vue component

I create a laravel application with jetstream and inertia-vue stack for my new project problem is Tailwindcs version 2 using postCss and it doesn't support #apply directive inside vue components but inside .css file it works fine I don't want that because that css file will load my every page I just want short inline utility classes with #apply directive but I can't, How Can I achieve that.?
inside my vue template
<template>
<div class="mt-4">
<label for="hello">Hello</label>
<input id="hello" class="input"/>
</div>
</templete>
<style scoped>
.input {
#apply bg-gray-200 border h-10
}
</style>
output inside browser like this
webpack.mix.js
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js').vue()
.postCss('resources/css/app.css', 'public/css', [
require('postcss-import'),
require('tailwindcss'),
require('autoprefixer'),
])
.webpackConfig(require('./webpack.config'));
if (mix.inProduction()) {
mix.version();
}
webpack.config.js
const path = require('path');
module.exports = {
resolve: {
alias: {
'#': path.resolve('resources/js'),
},
},
};
tailwind version : "^2.0.1",
laravel version : 8.x,
jetstream version : 2.x,
inertiajs version: "^0.8.2"
You have to set the lang="postcss" attribute on the <style> tag as Tailwind is a PostCSS plugin.
So change this
<style scoped>
.input {
#apply bg-gray-200 border h-10
}
</style>
To this
<style lang="postcss" scoped>
.input {
#apply bg-gray-200 border h-10
}
</style>
A workaround that can temporarily solve this problem:
.
In webpack.config.js
const path = require('path')
module.exports = {
resolve: {
alias: {
'#': path.resolve('resources/js')
}
},
module: {
rules: [
{
test: /\.(postcss)$/,
use: [
'vue-style-loader',
{ loader: 'css-loader', options: { importLoaders: 1 } },
'postcss-loader'
]
}
]
}
}
.
In postcss.config.js (if this file not exist, just create it)
module.exports = {
plugins: [
require('postcss-import'),
require('tailwindcss')('./tailwind.config.js'),
require('autoprefixer')
]
}
.
Now you can use in Vue file by adding lang="postcss
<style lang="postcss">
.input-form {
#apply block w-full mt-1 border-gray-300 rounded-md shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50;
}
</style>
.
This answer is based on the discussion here: https://github.com/laravel-mix/laravel-mix/issues/2778#issuecomment-826121931
Creating postcss.config.js & adding the below snippet worked for me:
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

How to override Vuetify 2 variables without using Vue CLI

The vuetify documentation only provides example for injecting sass variables using vue-cli configuration in vue.config.js
https://vuetifyjs.com/en/customization/sass-variables#markup-js-vue-config-sass-variables
What is the correct way to provide the modified vuetify variables when not using the CLI?
I am upgrading an older project from v1 (stylus) to v2 (sass) and I need to override some variables, lets say I only need to change the font-family to Arial.
I am also using treeshaking with vuetify.
Now I am kind of stuck because I don't know where to import the style overrides... Importing these in src/main.ts obviously does not work.
I have created a minimal repro here: https://github.com/Sharsie/vuetify-theme-repro/
What I have so far is a webpack config in build directory and style overrides in src/styles/main.scss
$body-font-family: Arial;
#import "~vuetify/src/styles/styles.sass";
Running the project creates a simple page that prints out computed styles for the v-app container
<v-app id="app">
<v-container>
<v-content>
<p>Wanted font-family: Arial</p>
<p>Current font-family: {{ fontFamily }}</p>
</v-content>
</v-container>
</v-app>
After digging through the source code of vue-cli, I figured out that the config just gets passed to sass-loader options, so the solution was pretty straightforward:
Instead of providing the stylesheet with variables through vue.config.js as such:
module.exports = {
css: {
loaderOptions: {
sass: {
data: `#import "~#/styles/main.scss"`,
},
},
},
}
You can provide it directly to sass-loader options in webpack config like this:
module.exports = {
...
module: {
rules: [
...
{
test: /\.(s?c|sa)ss$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
implementation: sass,
sassOptions: {
fiber: fibers,
},
prependData: `#import "~/styles/main.scss"`,
},
},
],
}
...
]
}
...
}
or for sass-loader<8.0.0
options: {
implementation: sass,
fiber: fibers,
data: `#import "~/styles/main.scss"`,
},

vue cli inspecting css from browser development console

Following various vue cli example to successfully implement scss file into the vue file, the page now loads with css imported but I cannot inspect from which file / line number the css declaration comes from, all it says in chrome console is within the not from the actual file like "margin.scss line 40".
here is my vue.config.js
module.exports = {
pluginOptions: {
'style-resources-loader': {
preProcessor: 'scss',
patterns: ["#/src/css/index.scss"]
}
},
here is my App.vue
<template>
<div >
</div>
</template>
<style lang="scss" >
#import "./css/index.scss";
</style>
and here is what I see,
Activate sourcemaps:
module.exports = {
css: {
sourceMap: true,
},
pluginOptions: {
'style-resources-loader': {
preProcessor: 'scss',
patterns: ["#/src/css/index.scss"]
}
},
https://cli.vuejs.org/config/#css-sourcemap

How to add vue-style-loader dependency in vue.js

In my project, I created a new file header.vue in src/components/header/. The code is
<template>
<div class="header">
I am header!!
</div>
</template>
<script type="text/ecmascript-6">
export default({})
</script>
<style lang="stylus" rel="stylesheet/stylus">
</style>
I want to use it in App.vue, Here is my code:
<template>
<div id="app">
<header></header>
</div>
</template>
<script>
import header from './components/header/header.vue'
export default {
components: {
header: header
}
}
</script>
<style>
#app {
.....
}
But i have got error in console:
This dependency was not found:
* !!vue-style-loader!css-loader?{"sourceMap":true}!../../../node_modules/vue-
loader/lib/style-compiler/index?{"vue":true,"id":"data-v-
12835cef","scoped":false,"hasInlineConfig":false}!stylus-loader?
{"sourceMap":true}!../../../node_modules/vue-loader/lib/selector?
type=styles&index=0!./header.vue in ./src/components/header/header.vue
I had found that ""css-loader": "^0.28.0"," is in package.jsaon already, So I added
"stylus-loader": "^2.1.1",
into package.json. and restarted "npm run dev"
But unlucky, it doesn't work, it failed again. Who can help me ?
1: Add stylus-loader as a dev dependency by executing the following command
npm install stylus stylus-loader --save-dev
2: Add the stylus rule to the webpack config
Locate the webpack.base.conf.js in the build folder and add the following rule
module: {
rules: [
{
test: /\.styl$/,
loader: ['style-loader', 'css-loader', 'stylus-loader']
}
]
}