Webpack 5 doesn't see styles in vue 2 sfc
I'm starting a legacy assembly of webpack 3 on webpack 5. When setting up the config and updating plugins, I ran into a problem, the sfc components of vue see only the styles of scss modules.
<!-- it works -->
<style module lang="scss">
.foo {
color: red;
}
</style>
<!-- this does not work -->
<style lang="scss">
.bar {
color: red;
}
</style>
<!-- this does not work -->
<style>
.foo-bar {
color: red;
}
</style>
<!-- this does not work -->
<style scoped>
.baz {
color: red;
}
</style>
The problem is clearly in the loader settings, but I don't know how to fix it.
Сurrent webpack config
module.exports = (env, argv) => {
const production = env.prod === 1;
return {
devtool: production ? "" : "inline-source-map",
context: path.resolve(__dirname, "static/src"),
entry: entry,
mode: production ? "production" : "development",
output: {
filename: "js/[name].js",
chunkFilename: production
? "js/[name].[chunkhash].js"
: "js/[name].js",
path: path.resolve(__dirname, "static/build/"),
publicPath: "/static/",
},
module: {
rules: [
{
test: /\.js$/,
exclude: [/node_modules\/(?!(swiper|dom7)\/).*/],
use: [
{
loader: "babel-loader",
},
],
},
{
test: /\.vue$/,
loader: "vue-loader",
},
{
test: /\.s?css$/,
exclude: /node_modules/,
use: [
'vue-style-loader',
{
loader: "css-loader",
options: {
modules: {
localIdentName: "[local]__[hash:base64:5]",
},
},
},
{
loader: "postcss-loader",
options: {
postcssOptions: {
sourceMap: !production,
plugins: [
"autoprefixer",
"postcss-flexbugs-fixes",
],
},
},
},
{
loader: "sass-loader",
options: {
sourceMap: !production,
additionalData: `
@import "./static/src/styles/_mixins.scss";
@import "./static/src/styles/_varaibles.scss";
@import "./static/src/styles/_colors.scss";
`,
sassOptions: {
indentedSyntax: false,
},
implementation: require("sass"),
},
},
],
},
{
test: /(\.jpg|\.png|\.ico|.gif|\.tif|\.svg|\.webp|\.cur)\??.*$/,
use: [
{
loader: "file-loader",
options: {
name: "fonts/[name].[ext]",
},
},
],
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: "file-loader",
options: {
name: "fonts/[name].[ext]",
},
},
],
},
{
test: /jquery-mousewheel/,
use: [
{
loader: "imports-loader",
},
],
},
{
test: /malihu-custom-scrollbar-plugin/,
use: [
{
loader: "imports-loader",
},
],
},
],
},
resolve: {
alias: {
vue$: "vue/dist/vue.runtime.esm.js",
},
extensions: ["*", ".js", ".vue", ".json"],
},
plugins: [
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: "css/[name].css",
}),
new CleanWebpackPlugin(),
],
};
};
Current devDependencies
"devDependencies": {
"@babel/core": "^7.17.8",
"@babel/preset-env": "^7.16.11",
"autoprefixer": "^10.4.4",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.2.4",
"clean-webpack-plugin": "^4.0.0",
"css-hot-loader": "^1.3.0",
"css-loader": "^6.7.1",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^2.29.0",
"import-glob": "^1.5.0",
"import-glob-loader": "^1.1.0",
"imports-loader": "^0.7.1",
"mini-css-extract-plugin": "^2.6.0",
"postcss": "^8.4.12",
"postcss-flexbugs-fixes": "^3.0.0",
"postcss-loader": "^6.2.1",
"regenerator-runtime": "^0.13.9",
"resolve-url-loader": "^5.0.0",
"sass": "^1.49.9",
"sass-loader": "^12.6.0",
"style-loader": "^3.3.1",
"url-loader": "^4.1.1",
"vue": "^2.6.12",
"vue-loader": "^15.9.8",
"vue-style-loader": "^4.1.3",
"vue-template-compiler": "^2.6.12",
"vue-template-loader": "^1.1.0",
"webpack": "^5.70.0",
"webpack-cli": "^4.9.2",
}
Old webpack config
module.exports = (env, argv) => {
const production = env.prod === 1;
return {
devtool: production ? '' : 'inline-source-map',
context: path.resolve(__dirname, 'static/src'),
entry: entry,
output: {
filename: 'js/[name].js',
chunkFilename: production ? 'js/[name].[chunkhash].js' : 'js/[name].js',
path: path.resolve(__dirname, 'static/build/'),
publicPath: '/static/'
},
module: {
rules: [
{
test: /\.js$/,
exclude: [/node_modules\/(?!(swiper|dom7)\/).*/],
use: [
'cache-loader',
'babel-loader',
'eslint-loader'
]
},
{
test: /\.vue?$/,
loader: 'vue-loader',
options: {
loaders: {
js: 'cache-loader!babel-loader!eslint-loader',
scss: 'cache-loader!vue-style-loader!css-loader!sass-loader?data=@import "./static/src/styles/_mixins"; @import "./static/src/styles/_varaibles";',
},
cssModules: {
localIdentName: '[local]__[hash:base64:5]',
camelCase: true
}
}
},
{
test: /\.s[ac]ss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'cache-loader',
{
loader: 'css-loader',
options: {sourceMap: !production}
},
{
loader: 'postcss-loader',
options: {
sourceMap: !production,
plugins: function () {
return [
require('autoprefixer'),
require('postcss-flexbugs-fixes')
];
}
}
},
{
loader: 'sass-loader',
options: {
sourceMap: !production,
data: '@import "./static/src/styles/_mixins";' +
' @import "./static/src/styles/_varaibles";' +
' @import "./static/src/styles/_colors"; '
},
}
]
})
},
{
test: /\.сss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'cache-loader',
{
loader: 'css-loader',
options: {sourceMap: !production}
},
{
loader: 'postcss-loader',
options: {
sourceMap: !production,
plugins: function () {
return [
require('autoprefixer'),
require('postcss-flexbugs-fixes')
];
}
}
},
]
})
},
{
test: /(\.jpg|\.png|\.ico|.gif|\.tif|\.svg|\.webp)\??.*$/,
use: 'url-loader?limit=1&name=images/[name].[ext]'
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
loader: 'url-loader?limit=1&name=fonts/[name].[ext]'
},
{test: /jquery-mousewheel/, loader: 'imports-loader?define=>false&this=>window'},
{test: /malihu-custom-scrollbar-plugin/, loader: 'imports-loader?define=>false&this=>window'}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js',
},
extensions: ['*', '.js', '.vue', '.json']
},
plugins: [
// new BundleAnalyzerPlugin({
// analyzerMode: !production ? 'server' : 'disabled'
// }),
require('autoprefixer'),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
chunks: Object.keys(entry),
}),
new ExtractTextPlugin({
filename: 'css/[name].css',
ignoreOrder: true,
allChunks: true,
}),
new styleLintPlugin({
configFile: 'stylelint.',
context: path.resolve(__dirname, 'static/src'),
files: '**/*.scss',
failOnError: false,
quiet: false
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
'window.$': 'jquery'
}),
// new BrowserSyncPlugin({
// host: 'localhost',
// port: 8888,
// proxy: 'http://commercial.localhost:8000/',
// }),
]
};
};