I have a large project that use tabs for indentation, but after some update I can't build the project anymore. Sass alway return the error "Syntax Error: SassError: Expected spaces, was tabs."
How can I configure Sass to use tabs insted os spaces in Vue 2? My vue.config.js:
const path = require('path')
module.exports = {
productionSourceMap: true,
configureWebpack: {
devtool: 'source-map',
resolve: {
alias: {
'#ui': path.resolve(__dirname, '../ui'),
}
},
},
css: {
loaderOptions: {
sass: {
sassOptions: {
indentType: 'tab',
indentWidth: 1
},
additionalData: `#import "../ui/style/_main.sass"`
},
scss: {
additionalData: `#import "../ui/style/_margins.scss";`,
sassOptions: {
indentType: 'tab',
indentWidth: 1
}
},
}
}
}
Related
I have created some custom components on top of vuetify components. In order to match my design I have overridden the vuetify sass variables by creating a .scss file in path src/scss/variables.scss and written custom .scss as well. This works absolutely fine but when I try to import the components in my storybook I am unable to see the overridden design.
// .storybook/main.js
const path = require("path");
module.exports = {
stories: [
// "../src/**/*.stories.mdx",
"../src/**/*.stories.#(js|jsx|ts|tsx)"
],
addons: [
"#storybook/addon-links",
{
name: "#storybook/addon-essentials",
options: {
docs: true
}
}
],
webpackFinal: async (config, { configType }) => {
config.resolve.alias["~storybook"] = path.resolve(__dirname);
config.resolve.alias["#"] = path.resolve(__dirname, "..", "src");
config.module.rules.push({
test: /\.s(c|a)ss$/,
use: [
"style-loader",
"css-loader",
{
loader: "sass-loader",
options: {
implementation: require("sass")
prependData: "#import '#/scss/variables.scss';", // ISSUE IS HERE
sassOptions: {
indentedSyntax: false // Tried with both true and false
},
}
}
],
include: path.resolve(__dirname, "../")
});
return config;
}
};
I'm on Nuxt 2.13 and using sass-loader 8.0.2
I wanna import a set of colors from my .env file in colors.scss
I managed to import them and allocate to variables with these codes:
my .env file:
THEME_BODY_COLOR = #FAFAFA
THEME_MAIN_COLOR = #0D2C54
THEME_MAIN_COLOR2 = #ff3366
THEME_SIDE_COLOR = #1a1b41
THEME_SIDE_COLOR2 = #0D2C54
THEME_LINK_COLOR = #673ab7
my nuxt.config.js
build: {
transpile: ['vee-validate/dist/rules'],
plugins: [
new webpack.ProvidePlugin({
'$': 'jquery',
jQuery: "jquery",
"window.jQuery": "jquery",
'_': 'lodash'
}),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
],
postcss: {
preset: {
features: {
customProperties: false,
},
},
},
loaders: {
scss: {
prependData: `$theme_colors: ("theme_body_color":"${process.env.THEME_BODY_COLOR}","theme_main_color":"${process.env.THEME_MAIN_COLOR}","theme_main_color2":"${process.env.THEME_MAIN_COLOR2}","theme_side_color":"${process.env.THEME_SIDE_COLOR}","theme_side_color2":"${process.env.THEME_SIDE_COLOR2}","theme_link_color":"${process.env.THEME_LINK_COLOR}");`
}
},
}
my colors.scss file:
#use "sass:string";
$theme_body_color: unquote(map-get($theme_colors, "theme_body_color"));
$theme_main_color: unquote(map-get($theme_colors, "theme_main_color"));
$theme_main_color2: unquote(map-get($theme_colors, "theme_main_color2"));
$theme_side_color: unquote(map-get($theme_colors, "theme_side_color"));
$theme_side_color2: unquote(map-get($theme_colors, "theme_side_color2"));
$theme_link_color: unquote(map-get($theme_colors, "theme_link_color"));
It has no problem with color: $theme_link_color but color: rgba($theme_link_color, .9) gives me the following error :
Module build failed (from ./node_modules/sass-loader/dist/cjs.js): friendly-errors 22:47:11
SassError: argument `$color` of `rgba($color, $alpha)` must be a color
on line 18 of assets/scss/colors.scss, in function `rgba`
from line 18 of assets/scss/colors.scss
from line 125 of C:\CODES\myproject\components\global\mycomp.vue
>> #debug rgba($theme_link_color, 0.2);
what cause this problem and how can i solve that??
It took me a while to find the answer and the problem was my approach!!
I didn't know how to insert multiple variable so I created an array and that caused the problem. so the answer:
for sass-loader < 7.x
build: {
loaders: {
scss: {
data: `
$theme_body_color:${process.env.THEME_BODY_COLOR};
$theme_main_color:${process.env.THEME_MAIN_COLOR};
$theme_main_color2:${process.env.THEME_MAIN_COLOR2};
$theme_side_color:${process.env.THEME_SIDE_COLOR};
$theme_side_color2:${process.env.THEME_SIDE_COLOR2};
$theme_link_color:${process.env.THEME_LINK_COLOR};
`
}
},
}
for sass-loader 8.x
build: {
loaders: {
scss: {
prependData: `
$theme_body_color:${process.env.THEME_BODY_COLOR};
$theme_main_color:${process.env.THEME_MAIN_COLOR};
$theme_main_color2:${process.env.THEME_MAIN_COLOR2};
$theme_side_color:${process.env.THEME_SIDE_COLOR};
$theme_side_color2:${process.env.THEME_SIDE_COLOR2};
$theme_link_color:${process.env.THEME_LINK_COLOR};
`
}
},
}
for sass-loader > 9.x
build: {
loaders: {
scss: {
additionalData: `
$theme_body_color:${process.env.THEME_BODY_COLOR};
$theme_main_color:${process.env.THEME_MAIN_COLOR};
$theme_main_color2:${process.env.THEME_MAIN_COLOR2};
$theme_side_color:${process.env.THEME_SIDE_COLOR};
$theme_side_color2:${process.env.THEME_SIDE_COLOR2};
$theme_link_color:${process.env.THEME_LINK_COLOR};
`
}
},
}
and that's it!! no need to do anything else! the variables are added to all scss files.
I'm trying to control the filenaming of files produced from a Vue app with Webpack.
The environment where I want to host the built app doesn't like filenames with '.' (don't ask).
I have been able via get js files to comply with a 'hyphen' naming scheme by using output.filename in vue.config.js configureWebpack entry. But css files are not renamed.
As I am loading the two bulk packed files rather than chunks I can obviously manually rename the single css file. However when I run it I get an error
Error: Loading CSS chunk error failed.
(/my-path/resources/css/error.d0f9a634.css)
I'm hoping I can force all css files (including the error one) to be renamed by the build process.
My vue.config.js
module.exports = {
outputDir: path.resolve(__dirname, 'dist'),
publicPath: "/my-path/resources",
configureWebpack: {
optimization: {
splitChunks: false
},
output: {
filename: "[name]-js",
chunkFilename: "[name]-chunk-js",
// get cssFilename() {
// return "[name]-css";
// }
},
resolve: {
alias: {
'vue$': path.resolve('./node_modules/vue/dist/vue.common.js'),
},
},
},
// https://cli.vuejs.org/config/#productionsourcemap
productionSourceMap: false,
// https://cli.vuejs.org/config/#css-extract
css: {
extract: { ignoreOrder: true },
loaderOptions: {
sass: {
prependData: '#import \'~#/assets/scss/vuetify/variables\''
},
scss: {
prependData: '#import \'~#/assets/scss/vuetify/variables\';'
}
}
},
// ...
}
I have started to look at MiniCssExtractPlugin but not sure if that is the right direction to look. Any help appreciated.
I found a working solution for this via the css.extract element in vue.config.js.
configureWebpack: {
optimization: {
splitChunks: false
},
output: {
filename: "js/[name]-js",
chunkFilename: "js/[name]-chunk-js",
},
...
},
// https://cli.vuejs.org/config/#css-extract
css: {
extract: {
ignoreOrder: true,
filename: 'css/[name]-css',
chunkFilename: 'css/[name]-chunk-css',
},
loaderOptions: {
sass: {
prependData: '#import \'~#/assets/scss/vuetify/variables\''
},
scss: {
prependData: '#import \'~#/assets/scss/vuetify/variables\';'
}
}
},
...
Which as the documentation link for css.extract says
Instead of a true, you can also pass an object of options for the
mini-css-extract-plugin if you want to further configure what this
plugin does exactly
and is covered by the webpack mini-css-extract-plugin documentation
Having added also a vue.config.js next to my babel.config.js I realized that the code doesn't get transpiled to ES5 anymore, probably because babel.config.js is fully ignored once there's a vue.config.js (?)
How can I keep babel transpiling the code when building with the presets given while yet having a vue.config.js with other configurations?
babel.config.js
module.exports = {
presets: [['#vue/app', { useBuiltIns: 'entry', corejs: 'core-js#2' }]],
}
vue.config.js
const TerserPlugin = require('terser-webpack-plugin')
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
config.optimization.minimizer = [
new TerserPlugin({
terserOptions: {
// needed for vuex-typex to work in production:
keep_fnames: true,
},
}),
]
}
},
css: {
loaderOptions: {
sass: {
data: `#import "./src/core/style/core/_variables.scss";`,
},
},
},
runtimeCompiler: true,
}
webpack.base.conf.js
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
scss: 'vue-style-loader!css-loader!sass-loader',
sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax'
}
}
},
{
loader: 'sass-resources-loader',
options: {
resources: path.resolve(__dirname, '../src/assets/scss/_variables.scss')
}
},
My "variables" file starts to load, but then i get this error:
Module parse failed: Unexpected character '#' (1:8)
You may need an appropriate loader to handle this file type.
| $white: #ffffff;
|
| // The Vue build version to load with the `import` command
I use this manual:
https://vue-loader-v14.vuejs.org/en/configurations/pre-processors.html
vue version: 2.93
Eventually i created project from scratch using vue-cli#3
and added to vue.config.js this code:
const path = require('path');
module.exports = {
chainWebpack: config => {
const oneOfsMap = config.module.rule('scss').oneOfs.store
oneOfsMap.forEach(item => {
item
.use('sass-resources-loader')
.loader('sass-resources-loader')
.options({
resources: [
path.resolve(__dirname, './src/assets/scss/_variables.scss'),
path.resolve(__dirname, './src/assets/scss/_mixins.scss'),
]
})
.end()
})
}
}
You might want to add it to a vue.config.js file in your root directory. If the file doesn't exist, create it and add something along the lines of this (my config):
module.exports = {
css: {
loaderOptions: {
sass: {
data: `
#import "#/assets/_variables.scss";
`
}
}
}
};