Here is the SyntaxError:
In the below [name].module.css, there are no semi-colon issue present. Here is my module.css file:
/* Groningen */
.groningen p,
.groningen h3,
.groningen a:hover,
.groningen li:hover,
.groningen h4 a:hover {
color: #017363 !important;
}
.groningen button {
background-color: #017363 !important;
border: #017363 !important;
}
.groningen .thumbnail-inner-2::before {
background-color: #017363 !important;
background-image: linear-gradient(#017363 10%, #000000 100%) !important;
}
::-webkit-scrollbar-thumb {
background-color: #017363 !important;
}
/* Rotterdam */
.rotterdam p,
.rotterdam h3,
.rotterdam li:hover,
.rotterdam a:hover,
.rotterdam h4 a:hover {
color: #004ab0 !important;
}
.rotterdam button,
.rotterdam button {
background-color: #004ab0 !important;
border: #004ab0 !important;
}
.rotterdam .thumbnail-inner-2::before {
background-color: #004ab0 !important;
background-image: linear-gradient(#004ab0 10%, #000000 100%) !important;
}
::-webkit-scrollbar-thumb {
background-color: #004ab0 !important;
}
/* leeuwarden */
.leeuwarden p,
.leeuwarden h3,
.leeuwarden a:hover,
.leeuwarden li:hover,
.leeuwarden h4 a:hover {
color: #ff914d !important;
}
.leeuwarden button {
background-color: #ff914d !important;
border: #ff914d !important;
}
.leeuwarden .thumbnail-inner-2::before {
background-color: #ff914d !important;
background-image: linear-gradient(#ff914d 10%, #000000 100%) !important;
}
::-webkit-scrollbar-thumb {
background-color: #ff914d !important;
}
Here is the webpack.common.js
const paths = require('./paths');
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: [paths.src + '/index.js'],
plugins: [
new CleanWebpackPlugin(),
new CopyPlugin({
patterns: [
{
from: paths.public + '/assets',
to: 'assets',
},
],
}),
new HtmlWebpackPlugin({
favicon: path.resolve(__dirname, '../public/favicon.ico'),
template: path.resolve(__dirname, '../public/index.html'), // template file
filename: 'index.html', // output file
}),
],
resolve: {
extensions: ['.js', '.jsx'],
fallback: {
fs: false,
assert: require.resolve('assert'),
buffer: false,
console: false,
constants: require.resolve('constants-browserify'),
crypto: false,
domain: false,
events: false,
http: false,
https: false,
os: false,
path: require.resolve('path-browserify'),
punycode: false,
process: false,
querystring: false,
stream: false,
string_decoder: false,
sys: false,
timers: false,
tty: false,
url: false,
util: require.resolve('util'),
vm: false,
zlib: false,
},
},
module: {
rules: [
{ test: /\.(js|jsx)$/, exclude: /node_modules/, use: ['babel-loader'] },
{
test: /\.html$/,
use: ['html-loader'],
},
{
test: /\.scss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: { url: false },
},
{
loader: 'resolve-url-loader',
options: {
sourceMap: true,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff',
},
},
],
},
{
test: /\.(ttf|eot|svg|png|jpg|jpeg|gif|ico)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[hash].[ext]',
outputPath: 'images',
},
},
],
},
],
},
};
Here is webpack.prod.js
const path = require('path');
const paths = require('./paths');
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
module.exports = merge(common, {
mode: 'production',
devtool: false,
output: {
path: path.resolve(__dirname, paths.build),
publicPath: '/',
filename: 'js/[name].[contenthash].bundle.js',
},
plugins: [
new MiniCssExtractPlugin({
filename: 'styles/[name].[contenthash].css',
}),
],
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: { url: false },
},
{
loader: 'resolve-url-loader',
options: {
sourceMap: true, // Ensure sourceMap is set to a boolean value
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true, // Ensure sourceMap is set to a boolean value
},
},
],
sideEffects: true,
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
sideEffects: true,
},
],
},
optimization: {
minimize: true,
minimizer: [new TerserPlugin()],
runtimeChunk: {
name: 'runtime',
},
},
});
What is the fix? As the code is working fine in Webpack dev environment but not in prod.
Expecting to know the fix that where should I put a semi-colon??
This is happening because you have conflicting loaders being loaded in production for *.scss
and *.css
files. It works in development mode because, you are using only webpack.common.js
file. In production, you are merging using webpack-merge
which will produce following output for module.rules
{
rules: [
{ test: /\.(js|jsx)$/ },
{ test: /\.html$/ },
{ test: /\.scss$/ },
{ test: /\.css$/ },
{ test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/ },
{
test: /\.(ttf|eot|svg|png|jpg|jpeg|gif|ico)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
},
{ test: /\.scss$/ },
{ test: /\.css$/ }
]
}
If you simply comment out CSS loader from webpack.common.js
file, then it would work for production.
// Comment this out.
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
There are couple of ways to solve it. The most obvious being the use of environment flag/variable to conditionally configure the right loader. The mini-css-extract-plugin
already has a good example of showing this.
The second option is to have three files and then use the common configuration in each of the other file:
common.js
- Common configuration.dev.js
- Dev only configuration where you use style-loader
for CSS.prod.js
- Prod configuration where you use mini-css-extract-plugin
loader.On a side note, your configuration is not complex enough to warrant the use of something like
webpack-merge
. Just your plain-old JavaScript with object spread and destructuring, and you should be good to go.