Error: Cannot read property 'eval' of null when compiling less in webpack using webpack-spritesmith

561 Views Asked by At

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"
  }
0

There are 0 best solutions below