I am trying to use the following code in my vue.config.js file, but it is giving me errors that module is not allowed. I am aware that there are configureWebpack and chainWebpack options, but I have no idea how to convert the following to use them. Any help would be appreciated
var path = require('path');
module.exports = {
foo:{},
bar{},
// Putting module in here does not work
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
'scss': [
'vue-style-loader',
'css-loader',
{
loader: "sass-loader",
options: {
includePaths: [
path.resolve(__dirname, "./node_modules/#syncfusion")
]
}
}
]
}
}
}
]
}
}
and in my vue file
<style lang="scss">
#import 'subfolder-inside-syncfusion/some-file.scss';
</style>
Link to code I found:
https://www.syncfusion.com/forums/139116/scss-files-when-included-in-my-file-doesnt-work-as-expected
You dont have to tap into the webpack config, if all you need is to include a global SCSS file. To import #syncfusion from node_modules, you can setup your vue.config.js like so:
css: {
loaderOptions: {
sass: {
data: `#import "~#syncfusion";`
}
}
}
For more info, see the Vue docs "Working with CSS".
Related
I'm trying to create storybook on vue. My components written using sass. So, I made this in .storybook/main.js:
webpackFinal: (config) => {
config.module.rules.push({
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
})
return config
}
And the styles looks like this:
<style lang="sass" scoped>
button
background-color: red
</style>
So I'm getting this error when trying to compile:
SassError: Invalid CSS after "": expected 1 selector or at-rule, was "button"
on line 1 of C:\Code\testproj\src\components\UI\TestComponent.vue
And if I change my style to this:
<style lang="sass" scoped>
button {
background-color: red
}
</style>
All works, but that's not a sass syntax.
I was having this exact same issue and I was able to solve it. The issue is from the webpack config. If you're using SASS, your webpack.config.js file in your .storybook folder should look like this:
module.exports = ({ config }) => {
config.module.rules.push({
test: /\.sass$/,
use: [
require.resolve("vue-style-loader"),
require.resolve("css-loader"),
{
loader: require.resolve("sass-loader"),
options: {
sassOptions: {
indentedSyntax: true
}
}
}
],
});
return config;
};
And if you're using SCSS, then it should be like this:
module.exports = ({ config }) => {
config.module.rules.push({
test: /\.scss$/,
use: [
require.resolve("vue-style-loader"),
require.resolve("css-loader"),
require.resolve("sass-loader"),
],
});
return config;
};
I was able to figure this out while reading the Vue Loader Docs
The problem is that in your webpack config, you are telling webpack that only use sass-loader when de extension of your file was test: /.s[ac]ss$/i That is to say .sass or .scss. However the extension of your file is .vue, because you are using sass in the vue file of your component.
With that configuration, try to put your sass style in a .sass file and check if works
For anyone using React 17+ with Storybook 6.4.9+, I had a similar problem where the Storybook/webpack build was not including my SCSS files. This configuration in .storybook/main.js worked for me:
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.#(js|jsx|ts|tsx)"
],
"addons": [
"#storybook/addon-links",
"#storybook/addon-essentials"
],
"framework": "#storybook/react",
webpackFinal: async (config) => {
// add SCSS support for CSS Modules
config.module.rules.push({
test: /\.scss$/,
use: [
require.resolve("style-loader"),
require.resolve("css-loader"),
require.resolve("sass-loader"),
],
});
return config;
}
}
I spend a lot of time to find better solution. It is may main.js config file for Storybook 6.4.9:
const path = require('path');
module.exports = {
"stories": [
"../src/**/*.stories.#(js|jsx|ts|tsx|mdx)"
],
"addons": [
"#storybook/addon-essentials",
"#storybook/addon-actions",
"#storybook/addon-controls",
"#storybook/addon-links",
{
name: '#storybook/preset-scss',
options: {
sassLoaderOptions: {
implementation: require('node-sass'), // ATTENTION: We need to use "node-sass" instead "sass/dart-sass"
sassOptions: {
indentedSyntax: true
},
},
}
},
"#storybook/addon-postcss",
],
"framework": "#storybook/vue",
features: {
babelModeV7: true,
},
webpackFinal: async (config, { configType }) => {
// `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
// You can change the configuration based on that.
// 'PRODUCTION' is used when building the static version of storybook.
// ATTENTION: Need to preload "global.sass" style for all elements;
config.module.rules.map(rule => {
if (rule.test instanceof RegExp && rule.test.toString() === '/\\.s[ca]ss$/') {
rule.use.push({
loader: require.resolve('sass-resources-loader'),
options: {
resources: [
path.resolve(__dirname, '../src/styles/global.sass')
]
}
})
}
return rule
})
// ATTENTION: Need to compile "Pug" templates.
config.module.rules.push(
{
test: /\.pug$/,
oneOf: [
// this applies to `<template lang="pug">` in Vue components
{
resourceQuery: /^\?vue/,
use: ['pug-plain-loader']
},
// this applies to pug imports inside JavaScript
{
use: ['raw-loader', 'pug-plain-loader']
}
]
}
);
// Return the altered config
return config;
},
}
I can't include a stylus plugin in my project, the code varies so much from one version to another that I'm lost trying everything and anything.
Here are the versions I currently have:
"nib": "^1.1.2",
"vue": "^2.5.16",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.2",
// vue.config.js
const nib = require('nib');
module.exports = {
configureWebpack: {
stylus: {
use: [nib()],
import: ['nib'],
},
},
};
Has anyone succeeded?
I would like to understand how to do it and why what I do doesn't work, thank you.
Once I installed rupture this way using vue-cli:
const rupture = require('rupture')
module.exports = {
configureWebpack: {
css: {
loaderOptions: {
stylus: {
use: [rupture()]
}
}
}
}
}
I found the correct way to install nib:
module.exports = {
css: {
loaderOptions: {
stylus: {
use: [require('nib')()],
import: ['~nib/lib/nib/index.styl']
}
}
}
}
To use Stylus, you need to configure the css loader in your webpack config, add this to rules:
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
]
}
And install the style-loaders:
npm install --save-dev css-loader vue-style-loader
The css should then load and you have css processing in both our external assets and our single-file components.
One final change here to use stylus is to install the loader:
npm install --save-dev stylus stylus-loader
And add a rule:
{
test: /\.styl(us)?$/,
use: [
'vue-style-loader',
'css-loader',
'stylus-loader'
]
}
Final solution:
In vue.config.js file
const path = require('path');
module.exports = {
css: {
loaderOptions: {
stylus: {
use: [
require('nib')(),
],
import: [
path.resolve(__dirname, './src/styles/nibFixes.styl'),
'~nib/lib/nib/index.styl',
],
},
},
},
};
In ./src/styles/nibFixes.styl file
// To fix https://github.com/stylus/nib/issues/312
flex-version = flex
support-for-ie = false
vendor-prefixes = official
In my app I'm initializing a Vue app, which uses single file .vue components.
I use Webpack to bundle, and vue-loader + postcss-modules to generate scoped classes.
But for some reason I can't access the generated classes inside my components ($style object is empty). I'll explain the problem below and created this repo as an example.
My hello.vue component looks like this:
<template>
<div :class="$style.hello">
Hello World!
</div>
</template>
<script>
export default {
name: "hello",
created() {
console.log(this.$style); // <- empty object :(
}
};
</script>
<style module>
.hello {
background: lime;
}
</style>
hello.vue.json is generated as expected (CSS Modules mapping):
{"hello":"_hello_23p9g_17"}
Scoped styles are appended in the document head, and when using mini-css-extract-plugin it is bundled in app.css:
._hello_23p9g_17 {
background: lime;
}
Does anyone know what the problem is and possibly how to fix this?
Below my config files.
webpack.config.js (trimmed for readability)
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const VueLoaderPlugin = require("vue-loader/lib/plugin");
module.exports = {
entry: {
app: "./src/index.js"
},
output: {
filename: "[name].js",
path: path.resolve(__dirname, "build")
},
resolve: {
extensions: [".js", ".vue", ".json", ".css"],
alias: {
vue: "vue/dist/vue.esm.js"
}
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: "babel-loader"
}
},
{
test: /\.vue$/,
loader: "vue-loader"
},
{
test: /\.css$/,
use: [
"vue-style-loader",
// MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
// modules: true,
importLoaders: 1
}
},
"postcss-loader"
]
}
]
},
plugins: [
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: "[name].css"
}),
new VueLoaderPlugin()
]
};
postcss.config.js
module.exports = {
ident: "postcss",
plugins: {
"postcss-preset-env": { stage: 0 },
"postcss-modules": {}
}
};
EDIT:
FYI, setting modules: true in the css-loader options works in that it populates the $style object (see docs):
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
modules: true
}
}
]
}
But in our app we use postcss-loader (as per docs) that takes care of all transformations including scoping. Enabling both modules: true and postcss-modules conflicts and breaks the classes/mapping (as expected).
In other words, I'm looking for a way to omit the modules: true option and enable css modules using postcss-modules instead.
Found a workaround: manually import the styles from the JSON file.
If anyone knows a better way please let me know :)
hello.vue.json
{"hello":"_hello_fgtjb_30"}
hello.vue
<template>
<div :class="style.hello">
Hello World!
</div>
</template>
<script>
import style from "./hello.vue.json";
export default {
name: "hello",
beforeCreate() {
this.style = style;
},
created() {
console.log(this.style);
}
};
</script>
<style module>
.hello {
background: lime;
}
</style>
This only works when using postcss-modules (loaded from config by postcss-loader in my case) instead of using modules: true:
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
importLoaders: 1
}
},
"postcss-loader"
]
};
See this PR as a full example.
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";
`
}
}
}
};
I use MiniCssExtractPlugin in a project which has some problem when I import css file inside node modules in a vue file. Import statement:
import '../../../node_modules/video.js/dist/video-js.css
Webpack config:
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: { url: false }
}
]
}
No style has been applied using the above setting. I tried to create a test.css file and put around in different folder. All directory will work except inside node_modules folder. Please help.
Extra info:
If I replace MiniCssExtractPlugin with style-loader, everything will be ok.
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: { url: false }
}
]
}