mini-css-extract-plugin: TypeError: Cannot read property 'split' of undefined

tried to use webpack-i18n-extractor-plugin together with mini-css-extract-plugin. The build fails with the following error:

C:\P\git\dojo-webpack-plugin-sample\node_modules\mini-css-extract-plugin\dist\index.js:81
    const resource = this._identifier.split('!').pop();
                                      ^

TypeError: Cannot read property 'split' of undefined
    at CssModule.nameForCondition (C:\P\git\dojo-webpack-plugin-sample\node_modules\mini-css-extract-plugin\dist\index.js:81:39)
    at Function.checkTest (C:\P\git\dojo-webpack-plugin-sample\node_modules\webpack\lib\optimize\SplitChunksPlugin.js:304:52)
    at Object.fn [as getCacheGroups] (C:\P\git\dojo-webpack-plugin-sample\node_modules\webpack\lib\optimize\SplitChunksPlugin.js:249:35)
    at compilation.hooks.optimizeChunksAdvanced.tap.chunks (C:\P\git\dojo-webpack-plugin-sample\node_modules\webpack\lib\optimize\SplitChunksPlugin.js:504:38)
    at SyncBailHook.eval [as call] (eval at create (C:\P\git\dojo-webpack-plugin-sample\node_modules\tapable\lib\HookCodeFactory.js:17:12), <anonymous>:7:16)
    at SyncBailHook.lazyCompileHook [as _call] (C:\P\git\dojo-webpack-plugin-sample\node_modules\tapable\lib\Hook.js:35:21)
    at Compilation.seal (C:\P\git\dojo-webpack-plugin-sample\node_modules\webpack\lib\Compilation.js:1196:38)
    at hooks.make.callAsync.err (C:\P\git\dojo-webpack-plugin-sample\node_modules\webpack\lib\Compiler.js:547:17)
    at _err0 (eval at create (C:\P\git\dojo-webpack-plugin-sample\node_modules\tapable\lib\HookCodeFactory.js:24:12), <anonymous>:11:1)
    at _addModuleChain (C:\P\git\dojo-webpack-plugin-sample\node_modules\webpack\lib\Compilation.js:1053:12)
    at processModuleDependencies.err (C:\P\git\dojo-webpack-plugin-sample\node_modules\webpack\lib\Compilation.js:979:9)
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickCallback (internal/process/next_tick.js:180:9)

When I remove WebpackI18nExtractorPlugin from the configuration, the build finishes successfully.

The simple project demonstrating this issue can be found here.

NodeJS version is 8.11.2

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 8
  • Comments: 43 (13 by maintainers)

Most upvoted comments

@evilebottnawi yeah, css-loader@4 with mini-css-extract-plugin@1 and style-loader@2 works fine. Thank you!

I ran into this recently. I didn’t realize that css-loader had to be used directly after MiniCssExtractPlugin.loader. Maybe it would be helpful to document that? I know it is used in all the examples but I didn’t know it was required.

Bump, still having this issue with no solution…

TL;DR: Mind the Loaders order of execution. Leave MiniCss right after the css-loader;

I was having the same issue, but ive found the solution. ive setup, a stack of loaders in the following order:

Before MiniCssExtractPlugin.loader!clean-css-loader!css-loader!postcss-loader!resolve-url-loader!sass-loader

notice CleanCss Loader was between MiniCss, and css-loader, and this was causing the bug. i got it fixed when i placed it between css-loader and postcss-loader

After MiniCssExtractPlugin.loader!css-loader!clean-css-loader!postcss-loader!resolve-url-loader!sass-loader

@evilebottnawi here’s a test repo - https://github.com/hellatan/webpack-mini-css-bug

I’ve been digging around and it seems like it has to do with how webpack is compiling the assets from my observations. I’m also using css modules for my config.

Just for reference, then I mention options with css-loader, the configuration looks like this:

module: {
  rules: [
    MiniCssExtractPlugin.loader,
    {
      loader: require.resolve('css-loader'), // could also just do `loader: 'css-loader'`
      options: {
        // options for css-loader
      }
    }
  ]
}

When I mentions css-loader is a string, the configuration is the following:

module: {
  rules: [
    MiniCssExtractPlugin.loader,
    require.resolve('css-loader'), // could also just do `loader: 'css-loader'`
  ]
}

In the string configuration, you can even do this:

module: {
  rules: [
    MiniCssExtractPlugin.loader,
    {
      loader: require.resolve('css-loader'),
    }
  ]
}

and it will act like the string option.

Now that that setup is out of the way, from what I can tell, the following is getting set to undefined in src/index.js#L33 because the dependency argument is null when the CssModule class is instantiated. Walking through the loader, this condition is what provides the null argument: src/loader.js#L185. When you are passing in options to css-loader, the output ends up being something like this:

[ null,
  { classA: '_33e67a30',
    classB: '_b9e4c43c' } ]

When css-loader is just a string, the output ends up looking something like this:

{ identifier:
   '/projects/project/node_modules/css-loader/dist/cjs.js!/projects/project/node_modules/postcss-loader/lib/index.js??ref--6-2!/projects/project/node_modules/sass-loader/dist/cjs.js??ref--6-3!/projects/project/src/main.scss',
  content:
   ':local .classA {\n  overflow-y: hidden;\n}\n\n:local .classB {\n  position: absolute;\n}\n}\n',
  media: '',
  sourceMap: undefined }

By having the latter shape, this error is not thrown.

I was really trying to track this problem, but I’m really not familiar with how webpack internally handles module rule settings and loaders. I saw that output from src/loader.js#L122 is different when using the options vs string configurations.

The options configuration output something like this:

CachedSource {
  _source:
   ConcatSource {
     children:
      [ 'module.exports =\n',
        '/******/ (function(modules) { // webpackBootstrap\n',
        [PrefixSource],
        '/******/ })\n',
        '/************************************************************************/\n',
        '/******/ (',
        '[\n',
        '/* 0 */',
        '\n',
        '/*!*********************************************************************************************************************************************************************************************************************************\\\n',
        '  !*** '/projects/project/node_modules/css-loader/dist/cjs.js!/projects/project/node_modules/postcss-loader/lib/index.js??ref--6-2!/projects/project/node_modules/sass-loader/dist/cjs.js??ref--6-3!/projects/project/src/main.scss' ***!\n',
        '  \\********************************************************************************************************************************************************************************************************************************/\n',
        '/*! no static exports found */\n',
        '/***/ (function(module, exports) {\n\n',
        [CachedSource],
        '\n\n/***/ })',
        '\n/******/ ]',
        ')',
        ';' ] },
  _cachedSource:
   'module.exports =\n/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// define __esModule on exports\n/******/ \t__webpack_require__.r = function(exports) {\n/******/ \t\tif(typeof Symbol !== \'undefined\' && Symbol.toStringTag) {\n/******/ \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: \'Module\' });\n/******/ \t\t}\n/******/ \t\tObject.defineProperty(exports, \'__esModule\', { value: true });\n/******/ \t};\n/******/\n/******/ \t// create a fake namespace object\n/******/ \t// mode & 1: value is a module id, require it\n/******/ \t// mode & 2: merge all properties of value into the ns\n/******/ \t// mode & 4: return value when already ns object\n/******/ \t// mode & 8|1: behave like require\n/******/ \t__webpack_require__.t = function(value, mode) {\n/******/ \t\tif(mode & 1) value = __webpack_require__(value);\n/******/ \t\tif(mode & 8) return value;\n/******/ \t\tif((mode & 4) && typeof value === \'object\' && value && value.__esModule) return value;\n/******/ \t\tvar ns = Object.create(null);\n/******/ \t\t__webpack_require__.r(ns);\n/******/ \t\tObject.defineProperty(ns, \'default\', { enumerable: true, value: value });\n/******/ \t\tif(mode & 2 && typeof value != \'string\') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n/******/ \t\treturn ns;\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module[\'default\']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, \'a\', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = "https://local.intranet.1stdibs.com:5901/app-admin-cms/";\n/******/\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/*!*********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\\\n  !*** /Users/daletan/projects/dibs-scripts/node_modules/css-loader/dist/cjs.js??ref--6-1!/Users/daletan/projects/dibs-scripts/node_modules/postcss-loader/lib??ref--6-2!/Users/daletan/projects/dibs-scripts/node_modules/sass-loader/dist/cjs.js??ref--6-3!/Users/daletan/projects/dibs-scripts/src/lib/webpack/scssCustomVarsLoader.js??ref--6-4!./src/navigation/components/Section.scss ***!\n  \\*********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// Exports\nmodule.exports = {\n\t"section": "_3868dde8",\n\t"iosSection": "_dc55311d",\n\t"sectionLinks": "_6be9f33b",\n\t"sectionLink": "_6dc1a348",\n\t"plusIcon": "_b7705030",\n\t"addButton": "_5e327036",\n\t"link": "_7b5c1aa1"\n};\n\n/***/ })\n/******/ ]);',
  _cachedSize: undefined,
  _cachedMaps: {},
  node: [Function],
  listMap: [Function] }

The string configuration output something like this:

CachedSource {
  _source:
   ConcatSource {
     children:
      [ 'module.exports =\n',
        '/******/ (function(modules) { // webpackBootstrap\n',
        [PrefixSource],
        '/******/ })\n',
        '/************************************************************************/\n',
        '/******/ (',
        '[\n',
        '/* 0 */',
        '\n',
        '/*!*********************************************************************************************************************************************************************************************************************************\\\n',
        '  !*** '/projects/project/node_modules/css-loader/dist/cjs.js!/projects/project/node_modules/postcss-loader/lib/index.js??ref--6-2!/projects/project/node_modules/sass-loader/dist/cjs.js??ref--6-3!/projects/project/src/main.scss' ***!\n',
        '  \\********************************************************************************************************************************************************************************************************************************/\n',
        '/*! no static exports found */\n',
        '/***/ (function(module, exports, __webpack_require__) {\n\n',
        [CachedSource],
        '\n\n/***/ })',
        ',\n',
        '/* 1 */',
        '\n',
        '/*!****************************************************************************************!*\\\n',
        '  !*** /Users/daletan/projects/dibs-scripts/node_modules/css-loader/dist/runtime/api.js ***!\n',
        '  \\****************************************************************************************/\n',
        '/*! no static exports found */\n',
        '/***/ (function(module, exports, __webpack_require__) {\n\n',
        '"use strict";\n',
        [CachedSource],
        '\n\n/***/ })',
        '\n/******/ ]',
        ')',
        ';' ] },
  _cachedSource:
   'module.exports =\n/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// define __esModule on exports\n/******/ \t__webpack_require__.r = function(exports) {\n/******/ \t\tif(typeof Symbol !== \'undefined\' && Symbol.toStringTag) {\n/******/ \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: \'Module\' });\n/******/ \t\t}\n/******/ \t\tObject.defineProperty(exports, \'__esModule\', { value: true });\n/******/ \t};\n/******/\n/******/ \t// create a fake namespace object\n/******/ \t// mode & 1: value is a module id, require it\n/******/ \t// mode & 2: merge all properties of value into the ns\n/******/ \t// mode & 4: return value when already ns object\n/******/ \t// mode & 8|1: behave like require\n/******/ \t__webpack_require__.t = function(value, mode) {\n/******/ \t\tif(mode & 1) value = __webpack_require__(value);\n/******/ \t\tif(mode & 8) return value;\n/******/ \t\tif((mode & 4) && typeof value === \'object\' && value && value.__esModule) return value;\n/******/ \t\tvar ns = Object.create(null);\n/******/ \t\t__webpack_require__.r(ns);\n/******/ \t\tObject.defineProperty(ns, \'default\', { enumerable: true, value: value });\n/******/ \t\tif(mode & 2 && typeof value != \'string\') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n/******/ \t\treturn ns;\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module[\'default\']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, \'a\', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = "https://local.intranet.1stdibs.com:5901/app-admin-cms/";\n/******/\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/*!***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\\\n  !*** /Users/daletan/projects/dibs-scripts/node_modules/css-loader/dist/cjs.js!/Users/daletan/projects/dibs-scripts/node_modules/postcss-loader/lib??ref--6-2!/Users/daletan/projects/dibs-scripts/node_modules/sass-loader/dist/cjs.js??ref--6-3!/Users/daletan/projects/dibs-scripts/src/lib/webpack/scssCustomVarsLoader.js??ref--6-4!./src/navigation/components/Section.scss ***!\n  \\***********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nexports = module.exports = __webpack_require__(/*! ../../../../../../dibs-scripts/node_modules/css-loader/dist/runtime/api.js */ 1)(false);\n// Module\nexports.push([module.i, ".section {\\n  padding-bottom: 36px;\\n  margin-bottom: 36px;\\n}\\n\\n.section:nth-child(even) {\\n  border-bottom: 1px solid #ddd;\\n}\\n\\n.section.iosSection {\\n  border: 1px dashed #ddd;\\n  padding: 9px;\\n}\\n\\n.sectionLinks {\\n  border: 1px solid #f3f3f3;\\n  margin: 18px 0 18px 18px;\\n}\\n\\n.sectionLink {\\n  padding: 9px;\\n}\\n\\n.sectionLink:nth-child(even) {\\n  background-color: #f3f3f3;\\n}\\n\\n.plusIcon {\\n  height: 12px;\\n  width: 12px;\\n  fill: #fff;\\n  margin-right: 9px;\\n  vertical-align: text-top;\\n}\\n\\n.addButton {\\n  margin: 18px 0;\\n}\\n\\n.link {\\n  cursor: pointer;\\n  color: #559b5e;\\n}\\n\\n.link:hover {\\n  color: #437a4a;\\n}\\n", ""]);\n\n\n/***/ }),\n/* 1 */\n/*!****************************************************************************************!*\\\n  !*** /Users/daletan/projects/dibs-scripts/node_modules/css-loader/dist/runtime/api.js ***!\n  \\****************************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n"use strict";\n\n\n/*\n  MIT License http://www.opensource.org/licenses/mit-license.php\n  Author Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\n// eslint-disable-next-line func-names\nmodule.exports = function (useSourceMap) {\n  var list = []; // return the list of modules as css string\n\n  list.toString = function toString() {\n    return this.map(function (item) {\n      var content = cssWithMappingToString(item, useSourceMap);\n\n      if (item[2]) {\n        return "@media ".concat(item[2], "{").concat(content, "}");\n      }\n\n      return content;\n    }).join(\'\');\n  }; // import a list of modules into the list\n  // eslint-disable-next-line func-names\n\n\n  list.i = function (modules, mediaQuery) {\n    if (typeof modules === \'string\') {\n      // eslint-disable-next-line no-param-reassign\n      modules = [[null, modules, \'\']];\n    }\n\n    var alreadyImportedModules = {};\n\n    for (var i = 0; i < this.length; i++) {\n      // eslint-disable-next-line prefer-destructuring\n      var id = this[i][0];\n\n      if (id != null) {\n        alreadyImportedModules[id] = true;\n      }\n    }\n\n    for (var _i = 0; _i < modules.length; _i++) {\n      var item = modules[_i]; // skip already imported module\n      // this implementation is not 100% perfect for weird media query combinations\n      // when a module is imported multiple times with different media queries.\n      // I hope this will never occur (Hey this way we have smaller bundles)\n\n      if (item[0] == null || !alreadyImportedModules[item[0]]) {\n        if (mediaQuery && !item[2]) {\n          item[2] = mediaQuery;\n        } else if (mediaQuery) {\n          item[2] = "(".concat(item[2], ") and (").concat(mediaQuery, ")");\n        }\n\n        list.push(item);\n      }\n    }\n  };\n\n  return list;\n};\n\nfunction cssWithMappingToString(item, useSourceMap) {\n  var content = item[1] || \'\'; // eslint-disable-next-line prefer-destructuring\n\n  var cssMapping = item[3];\n\n  if (!cssMapping) {\n    return content;\n  }\n\n  if (useSourceMap && typeof btoa === \'function\') {\n    var sourceMapping = toComment(cssMapping);\n    var sourceURLs = cssMapping.sources.map(function (source) {\n      return "/*# sourceURL=".concat(cssMapping.sourceRoot).concat(source, " */");\n    });\n    return [content].concat(sourceURLs).concat([sourceMapping]).join(\'\\n\');\n  }\n\n  return [content].join(\'\\n\');\n} // Adapted from convert-source-map (MIT)\n\n\nfunction toComment(sourceMap) {\n  // eslint-disable-next-line no-undef\n  var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));\n  var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);\n  return "/*# ".concat(data, " */");\n}\n\n/***/ })\n/******/ ]);',
  _cachedSize: undefined,
  _cachedMaps: {},
  node: [Function],
  listMap: [Function] }

The most significant difference is that the string config has this function(module, exports, __webpack_require__) AND one additional method compiled with it as apart of its output whereas the options config looks more like function(module, exports). Maybe I’m grasping at straws at this point, so I’m not sure if this is of significance or not.

Hopefully all of this info helps out as i’m stuck on css-loader@1.0.1 for the time being because I need to pass options into our css-loader. I think this issue even popped up when upgrading to css-loader@2.0.0.

I was having the same error, but had the order of loaders as described here. After much searching I found out that the culprit was the exportOnlyLocals: true option in css-loader.

This comes from the official documentation of css-loader:

Export only locals (useful when you use css modules). For pre-rendering with mini-css-extract-plugin you should use this option instead of style-loader!css-loader in the pre-rendering bundle. It doesn’t embed CSS but only exports the identifier mappings.

@evilebottnawi sure

// fetch the repo
git clone https://github.com/blephy/reactjs-typescript-pwa.git
cd reactjs-typescript-pwa

// change branch to refacto
git checkout refacto

// install dependencies
npm i

make a .env file at the root folder with this content :

# Needed by the server and the app (CORS / SEO...)
DOMAIN_NAME=localhost:3001
PORT=3001
HTTPS=false

# Currently not exploited
API_URL=localhost:3001/api/v1

# Report URI https://report-uri.com/
CT_REPORT_URI=https://reactjstypescriptpwa.report-uri.com/r/d/ct/enforce
CSP_REPORT_URI=https://reactjstypescriptpwa.report-uri.com/r/d/csp/enforce
API_REPORT_URI=https://reactjstypescriptpwa.report-uri.com/a/d/g

Run production build with webpack (config/webpack/app.prod.ts) :

npm run build

npm run build is currently launching 3 steps : app build, service worker build, and inject a precache manifest in service worker. As you know, you only want the step 1 (app build). So you can replace npm run build with npx cross-env TS_NODE_PROJECT=\"tsconfig.webpack.json\" NODE_ENV=\"production\" webpack --progress --config config/webpack/app.prod.ts in order to launch only app build

If you are on windows and falling into prettier eol issues, just run npm run lint:fix before building.

@darkangel081195 no i didn’t fixed it yet.

I’m also getting this error when using webpack 5. In the latest version 4 of webpack, everything was going nicely 😕 :

css-loader: 4.3.0 mini-css-extract-plugin: 1.0.0 webpack: 5.0.0

my rule :

          {
            test: /\.scss$/,
            use: [
              MiniCssExtractPlugin.loader,
              { loader: 'css-loader', options: { importLoaders: 1 } },
              // {
              //   loader: 'postcss-loader',
              //   options: {
              //     postcssOptions: {
              //       ident: 'postcss',
              //       plugins: (): Record<string, unknown>[] => [postcssNormalize()]
              //     }
              //   }
              // },
              'sass-loader'
            ]
          },

Stack trace :

75% sealing chunk optimization SplitChunksPlugin[webpack-cli] Uncaught exception: TypeError: Cannot read property 'split' of undefined
[webpack-cli] TypeError: Cannot read property 'split' of undefined
    at CssModule.nameForCondition (/Users/blephy/Sites/strict-optimized-react-starter/node_modules/mini-css-extract-plugin/dist/CssModule.js:65:39)
    at checkTest (/Users/blephy/Sites/strict-optimized-react-starter/node_modules/webpack/lib/optimize/SplitChunksPlugin.js:490:23)
    at /Users/blephy/Sites/strict-optimized-react-starter/node_modules/webpack/lib/optimize/SplitChunksPlugin.js:447:7
    at Object.fn [as getCacheGroups] (/Users/blephy/Sites/strict-optimized-react-starter/node_modules/webpack/lib/optimize/SplitChunksPlugin.js:464:5)

Repository to reproduce (branch refacto) : https://github.com/blephy/reactjs-typescript-pwa/tree/refacto

@ogonkov yep, I think about it, but it is hard to know what previously loader exports (when you use exportOnlyLocals css-loader emits object with locals, but when you don’t use this options css-loader emits array of css modules), also you can use any loader (even don’t use css-loader), but I have idea, we will avoid create modules without identifier

@ogonkov Can you create reproducible test repo?

Here you go https://gist.github.com/ogonkov/d4060500cf3d5b8b78e61fac9b8befe9

css-loader@4.2.2

error didn’t happen when exportOnlyLocals is false

Anyway errors shouldn’t happen this way. If config file is not met some conditions, it should throw some human readable error with error reason.

Happen to me for mini-css-extract-plugin@0.11.0

webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    mode: 'development',
    devtool: false,

    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader
                    },
                    {
                        loader: 'css-loader',
                        options: {
                            modules: {
                                exportOnlyLocals: true
                            }
                        }
                    }
                ]
            }
        ]
    },

    plugins: [
        new MiniCssExtractPlugin(),
    ]
};

Check your css-loader version - you can get this error if css-loader more than 3.2.0

Have anyone try extract-css-chunks-webpack-plugin instead? I tried and it worked in my case as I need to extract CSS from js bundle which used css-modules under the hood. I do not have SSR in case you wonder but I do generating bundle for browser use + css-modules so onlyLocals would not work quite well in my case as I use Node. Don’t know if it is gonna work for your case but it is worth a try though.

FYI, there was a related issue in webpack-i18n-extractor-plugin repository. It was fixed by the author. You can read the explanation of the fix there.