The issue is in Webpack 4 under "production" mode there is no source map file generated only for CSS (no problem in javascript source map file) but there is no issue in generation of source map for CSS under "development" mode.
Here are my previous configurations:
package.json
{
"name": "webfoobar",
"version": "1.0.0",
"author": "Roland Michael dela Peña",
"homepage": "http://localhost",
"description": "",
"main": "",
"keywords": [],
"license": "ISC",
"scripts": {
"prod": "webpack --mode production",
"dev": "webpack --watch --mode development"
},
"devDependencies": {
"autoprefixer": "^9.1.0",
"css-loader": "^1.0.0",
"cssnano": "^4.0.5",
"mini-css-extract-plugin": "^0.4.1",
"node-sass": "^4.9.2",
"optimize-css-assets-webpack-plugin": "^5.0.0",
"postcss-loader": "^2.1.6",
"sass-loader": "^7.1.0",
"webpack": "^4.16.3",
"webpack-command": "^0.4.1"
}
}
webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = (env = {}, argv = {}) => {
const isDevelopment = (env.mode === 'development');
const isProduction = (env.mode === 'production');
return {
entry: {
app: [
'./src/main.scss'
]
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'scripts.js',
sourceMapFilename: '[file].map'
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.(css|s[ac]ss)$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
{
loader: 'css-loader',
options: {
importLoaders: 2,
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
plugins: () => [
require('autoprefixer')
],
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
}
],
},
optimization: {
minimizer: [
new OptimizeCSSAssetsPlugin({})
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'
})
]
}
};
The webpack output after building the "production" mode:
We can see that there is no "app.css.map" generated.
After some trial and error, I have found the culprit which is the "Optimize CSS Assets Webpack Plugin". I use this plugin to minimize the CSS file size which by default it uses "cssnano". Analyzing the "webpack.config.js" we can use the "PostCSS loader" to this job by using "cssnano" also.
Here are my new configurations:
package.json
{
"name": "webfoobar",
"version": "1.0.0",
"author": "Roland Michael dela Peña",
"homepage": "http://localhost",
"description": "",
"main": "",
"keywords": [],
"license": "ISC",
"scripts": {
"prod": "webpack --mode production",
"dev": "webpack --watch --mode development"
},
"devDependencies": {
"autoprefixer": "^9.1.0",
"css-loader": "^1.0.0",
"cssnano": "^4.0.5",
"mini-css-extract-plugin": "^0.4.1",
"node-sass": "^4.9.2",
"postcss-loader": "^2.1.6",
"sass-loader": "^7.1.0",
"webpack": "^4.16.3",
"webpack-command": "^0.4.1"
}
}
webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = (env = {}, argv = {}) => {
const isDevelopment = (env.mode === 'development');
const isProduction = (env.mode === 'production');
return {
entry: {
app: [
'./src/main.scss'
]
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'scripts.js',
sourceMapFilename: '[file].map'
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.(css|s[ac]ss)$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
{
loader: 'css-loader',
options: {
importLoaders: 2,
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
plugins: () => [
require('autoprefixer'),
require('cssnano')({
preset: 'default',
})
],
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
}
],
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'
})
]
}
};
The webpack output after building the "production" mode:
Now the "app.css.map" is generated under "production" mode.
Comments
Save my day
thank you for share this code
The Happy Friday Hero!
I have been spending half the day trying to make sense of enabling sourcemaps through webpack 4 based on various blogs. This is the only source on the web that comes close to making that happen perfectly. I had to make some tweaks based on the info above, but overrall this is a beauty for Webpack users. Many thanks!
amazing
Your example was more useful than hours and hours of reading and trying to understand how to do something so basic, thanks.
You dont need to remove OptimizeCssAssetsPlugin
it is not a bug , you just need to add:
Inside of cssProcessorOptions, map: { inline: false, } check the example below or
map: {
inline: true,
}
For external source map use:
map: {
inline: false,
annotation: true,
}
check my gist: https://gist.github.com/54c05ef9da2f4644d06eb124064a9f2b
or example below i hope can help , cheers :)
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: cssnano,
cssProcessorOptions: {
discardComments: { removeAll: true },
map: {
inline: false,
},
},
canPrint: true,
}),
thanks
Thank you for sharing, helped a lot! Chris