The error is coming from the LESS file that webpack-spritesmith plugin is generating:
ERROR in ./assets/less/main.less
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/less-loader/dist/cjs.js):
@spritesheet-sprites:;
@spritesheet: 0px 0px '~img/generated/sprite.png' @spritesheet-sprites;
Cannot read property 'eval' of null
For some reason, the spritesheet-sprites
variable seems to be defined without a value. I encountered this error after I upgraded my Webpack version from 1.13 to 5.22 (along with its loaders). I tried downgrading some of the dependencies like less, less-loader, and the webpack-spritesmith plugin itself, but didn't seem to work. Also checked if the newer versions of Webpack and its loaders handle paths differently, no result.
I wrote the configs (for webpack and the plugins) by following their official documents, everything seems to be in place but by checking resources online I couldn't find whether my configuration is wrong or that there are unmatching versions in the packages.
My webpack config:
const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const SpritesmithPlugin = require('webpack-spritesmith');
const mainPath = path.join(__dirname, './assets');
module.exports = {
mode: 'production',
stats: 'verbose',
resolve: {
extensions: ['.js'],
alias: {
assets: mainPath,
js: path.join(mainPath, 'js'),
less: path.join(mainPath, 'less'),
img: path.join(mainPath, 'img'),
fonts: path.join(mainPath, 'fonts')
},
},
entry: ['./assets/index'],
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js',
publicPath: './',
chunkFilename: '[id].[chunkhash].js'
},
module: {
rules: [
{
test: /\.js?/,
exclude: /(node_modules)/,
include: path.join(__dirname, 'assets'),
use: ['babel-loader']
},
{
test: /\.(ttf|eot|svg|woff|woff2)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: ['file-loader']
},
{
test: /\.jpe?g$|\.gif$|\.png$/i,
use: ['file-loader']
},
{
test: /\.less$/,
use: [MiniCssExtractPlugin.loader, 'style-loader', 'css-loader', 'less-loader'],
},
],
},
plugins: [
new SpritesmithPlugin({
src: {
cwd: path.resolve(__dirname, 'assets/img/sprite'),
glob: '*.png'
},
target: {
image: path.resolve(__dirname, 'assets/img/generated/sprite.png'),
css: path.resolve(__dirname, 'assets/less/generated/sprite.less')
},
apiOptions: {
cssImageRef: "~img/generated/sprite.png",
generateSpriteName: function(filePath) {
return 'sprite-' + path.basename(filePath, '.png');
}
}
}),
new MiniCssExtractPlugin({filename: 'style.css'})
]
};
package.json:
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/preset-env": "^7.12.16",
"babel-eslint": "7.0.0",
"babel-loader": "^8.2.2",
"cross-env": "3.0.0",
"css-loader": "^5.0.2",
"eslint": "3.7.0",
"eslint-plugin-babel": "3.3.0",
"eslint-plugin-react": "6.3.0",
"file-loader": "^6.2.0",
"less": "^3.0.0",
"less-loader": "^8.0.0",
"mini-css-extract-plugin": "^1.3.7",
"rimraf": "2.5.4",
"style-loader": "^2.0.0",
"unused-files-webpack-plugin": "^3.4.0",
"webpack": "^5.22.0",
"webpack-cli": "^4.5.0",
"webpack-dev-middleware": "1.8.3",
"webpack-hot-middleware": "2.12.2",
"webpack-spritesmith": "^1.1.0"
}