Cannot read property 'outputOptions' of undefined

derevandal
50
derevandal
commented 5 months ago

Version

2.4.3

Reproduction link

https://codesandbox.io/s/30k541yq35

Steps to reproduce

  • Create new [email protected]^2.4.0
  • Add SCSS support npm install --save-dev node-sass sass-loader bootstrap bootstrap-vue
  • Add.scssfiles inassets/scss/`
  • Set extractCSS and parallel to true in the build property of nuxt.config.js
  • Add ~assets/scss/app.scss in css array, for example, in nuxt.config.js

What is expected ?

To work as expected.

What is actually happening?

Error in console:
ERROR in ./assets/scss/app.scss friendly-errors 19:20:49

Module build failed (from ./node_modules/thread-loader/dist/cjs.js):
Thread Loader (Worker 9)
Cannot read property 'outputOptions' of undefined

at Object.pitch (/sandbox/node_modules/extract-css-chunks-webpack-plugin/dist/loader.js:67:98)
                                                 friendly-errors 19:20:49

@ ./.nuxt/App.js 3:0-33
@ ./.nuxt/index.js
@ ./.nuxt/client.js
@ multi eventsource-polyfill webpack-hot-middleware/client?reload=true&timeout=30000&ansiColors=&overlayStyles=&name=modern&path=/_webpackhmr/modern ./.nuxt/client.js}

And set parallel to false, CSS file didn't loaded.

bug
0
stevefan1999
0
stevefan1999
commented 5 months ago

This might not be the fault of Nuxt, but rather extract-css-chunks-webpack-plugin itself:
I set a halting trap right over the publicPath variable:

if (typeof query.publicPath !== 'string') {
     console.log({ this: this, query })
     while(1);
}

(Nope, debugger won't work in this case)

And got this when query.publicPath is nowhere to be seen:

<summary>Details</summary>

{ this:
   { version: 2,
     resolve: [Function: resolve],
     emitWarning: [Function: emitWarning],
     emitError: [Function: emitError],
     exec: [Function: exec],
     options: { context: '/mnt/Projects/nuxt/hw' },
     webpack: true,
     'thread-loader': true,
     sourceMap: false,
     target: 'web',
     minimize: undefined,
     resourceQuery: '?vue&type=style&index=0&lang=css&',
     context: '/mnt/Projects/nuxt/hw/.nuxt/components',
     loaderIndex: 0,
     loaders: [ [Object], [Object], [Object], [Object], [Object] ],
     resourcePath: '/mnt/Projects/nuxt/hw/.nuxt/components/nuxt-loading.vue',
     async: [Function: async],
     callback: [Function],
     cacheable: [Function: cacheable],
     addDependency: [Function: addDependency],
     dependency: [Function: addDependency],
     addContextDependency: [Function: addContextDependency],
     getDependencies: [Function: getDependencies],
     getContextDependencies: [Function: getContextDependencies],
     clearDependencies: [Function: clearDependencies],
     resource: [Getter/Setter],
     request: [Getter],
     remainingRequest: [Getter],
     currentRequest: [Getter],
     previousRequest: [Getter],
     query: [Getter],
     data: [Getter] },
  query: {} }
{ this:
   { version: 2,
     resolve: [Function: resolve],
     emitWarning: [Function: emitWarning],
     emitError: [Function: emitError],
     exec: [Function: exec],
     options: { context: '/mnt/Projects/nuxt/hw' },
     webpack: true,
     'thread-loader': true,
     sourceMap: false,
     target: 'web',
     minimize: undefined,
     resourceQuery: '?vue&type=style&index=0&lang=css&',
     context: '/mnt/Projects/nuxt/hw/.nuxt/components',
     loaderIndex: 0,
     loaders: [ [Object], [Object], [Object], [Object], [Object] ],
     resourcePath: '/mnt/Projects/nuxt/hw/.nuxt/components/nuxt-error.vue',
     async: [Function: async],
     callback: [Function],
     cacheable: [Function: cacheable],
     addDependency: [Function: addDependency],
     dependency: [Function: addDependency],
     addContextDependency: [Function: addContextDependency],
     getDependencies: [Function: getDependencies],
     getContextDependencies: [Function: getContextDependencies],

Then obviously typeof query.publicPath is going to be undefined

This is what happens when build.parallel is off:

<summary>Details</summary>

{                                                                               23:44:59
  this: {
    version: 2,
    emitWarning: [Function: emitWarning],
    emitError: [Function: emitError],
    exec: [Function: exec],
    resolve: [Function: resolve],
    getResolve: [Function: getResolve],
    emitFile: [Function: emitFile],
    rootContext: '/mnt/Projects/nuxt/hw',
    webpack: true,
    sourceMap: false,
    _module: NormalModule {
      dependencies: [],
      blocks: [],
      variables: [],
      type: 'javascript/auto',
      context: '/mnt/Projects/nuxt/hw/assets/css',
      debugId: 1488,
      hash: undefined,
      renderedHash: undefined,
      resolveOptions: {},
      factoryMeta: {},
      warnings: [],
      errors: [],
      buildMeta: {},
      buildInfo: [Object],
      reasons: [Array],
      _chunks: [SortableSet],
      id: null,
      index: null,
      index2: null,
      depth: null,
      issuer: [NormalModule],
      profile: undefined,
      prefetched: false,
      built: true,
      used: null,
      usedExports: null,
      optimizationBailout: [],
      _rewriteChunkInReasons: undefined,
      useSourceMap: false,
      _source: null,
      request: '/mnt/Projects/nuxt/hw/node_modules/.npm.stevefan1999.me/extract-css-chunks-webpack-plugin/3.3.2/[email protected]/node_modules/extract-css-chunks-webpack-plugin/dist/hotLoader.js??ref--6-oneOf-1-0!/mnt/Projects/nuxt/hw/node_modules/.npm.stevefan1999.me/extract-css-chunks-webpack-plugin/3.3.2/[email protected]/node_modules/extract-css-chunks-webpack-plugin/dist/loader.js!/mnt/Projects/nuxt/hw/node_modules/.npm.stevefan1999.me/css-loader/1.0.1/[email protected]/node_modules/css-loader/index.js??ref--6-oneOf-1-2!/mnt/Projects/nuxt/hw/node_modules/.npm.stevefan1999.me/postcss-loader/3.0.0/node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-3!/mnt/Projects/nuxt/hw/assets/css/main.css',
      userRequest: '/mnt/Projects/nuxt/hw/assets/css/main.css',
      rawRequest: '../assets/css/main.css',
      binary: false,
      parser: [Parser],
      generator: JavascriptGenerator {},
      resource: '/mnt/Projects/nuxt/hw/assets/css/main.css',
      matchResource: undefined,
      loaders: [Array],
      error: null,
      _buildHash: '',
      buildTimestamp: 1549899899895,
      _cachedSources: Map {},
      lineToLine: false,
      _lastSuccessfulBuildMeta: {},
      _ast: null
    },
    _compilation: Compilation {
      _pluginCompat: [SyncBailHook],
      hooks: [Object],
      name: 'client',
      compiler: [Compiler],
      resolverFactory: [ResolverFactory],
      inputFileSystem: [CachedInputFileSystem],
      requestShortener: [RequestShortener],
      options: [Object],
      outputOptions: [Object],
      bail: undefined,
      profile: undefined,
      performance: [Object],
      mainTemplate: [MainTemplate],
      chunkTemplate: [ChunkTemplate],
      hotUpdateChunkTemplate: [HotUpdateChunkTemplate],
      runtimeTemplate: [RuntimeTemplate],
      moduleTemplates: [Object],
      semaphore: [Semaphore],
      entries: [Array],
      _preparedEntrypoints: [Array],
      entrypoints: Map {},
      chunks: [],
      chunkGroups: [],
      namedChunkGroups: Map {},
      namedChunks: Map {},
      modules: [Array],
      _modules: [Map],
      cache: [Object],
      records: [Object],
      additionalChunkAssets: [],
      assets: {},
      errors: [],
      warnings: [],
      children: [Array],
      dependencyFactories: [Map],
      dependencyTemplates: [Map],
      childrenCounters: [Object],
      usedChunkIds: null,
      usedModuleIds: null,
      fileTimestamps: Map {},
      contextTimestamps: Map {},
      compilationDependencies: Set {},
      _buildingModules: [Map],
      _rebuildingModules: Map {},
      emittedAssets: Set {}
    },
    _compiler: Compiler {
      _pluginCompat: [SyncBailHook],
      hooks: [Object],
      name: 'client',
      parentCompilation: undefined,
      outputPath: '/mnt/Projects/nuxt/hw/.nuxt/dist/client',
      outputFileSystem: [MemoryFileSystem],
      inputFileSystem: [CachedInputFileSystem],
      recordsInputPath: undefined,
      recordsOutputPath: undefined,
      records: [Object],
      removedFiles: Set {},
      fileTimestamps: Map {},
      contextTimestamps: Map {},
      resolverFactory: [ResolverFactory],
      resolvers: [Object],
      options: [Object],
      context: '/mnt/Projects/nuxt/hw',
      requestShortener: [RequestShortener],
      running: true,
      watchMode: true,
      _assetEmittingSourceCache: [WeakMap],
      _assetEmittingWrittenFiles: Map {},
      watchFileSystem: [NodeWatchFileSystem],
      watch: [Function],
      webpackbar: [WebpackBarPlugin],
      dependencies: undefined
    },
    fs: CachedInputFileSystem {
      fileSystem: NodeJsInputFileSystem {},
      _statStorage: [Storage],
      _readdirStorage: [Storage],
      _readFileStorage: [Storage],
      _readJsonStorage: [Storage],
      _readlinkStorage: [Storage],
      _stat: [Function: bound bound ],
      _statSync: [Function: bound bound ],
      _readdir: [Function: bound readdir],
      _readdirSync: [Function: bound readdirSync],
      _readFile: [Function: bound bound readFile],
      _readFileSync: [Function: bound bound readFileSync],
      _readJson: [Function],
      _readJsonSync: [Function],
      _readlink: [Function: bound bound readlink],
      _readlinkSync: [Function: bound bound readlinkSync]
    },
    'css/extract-chunks': [Function],
    'vue-loader': true,
    hot: true,
    target: 'web',
    loadModule: [Function],
    context: '/mnt/Projects/nuxt/hw/assets/css',
    loaderIndex: 1,
    loaders: [
      [Object],
      [Object],
      [Object],
      [Object]
    ],
    resourcePath: '/mnt/Projects/nuxt/hw/assets/css/main.css',
    resourceQuery: '',
    async: [Function: async],
    callback: [Function],
    cacheable: [Function: cacheable],
    addDependency: [Function: addDependency],
    dependency: [Function: addDependency],
    addContextDependency: [Function: addContextDependency],
    getDependencies: [Function: getDependencies],
    getContextDependencies: [Function: getContextDependencies],
    clearDependencies: [Function: clearDependencies],
    resource: [Getter/Setter],
    request: [Getter],
    remainingRequest: [Getter],
    currentRequest: [Getter],
    previousRequest: [Getter],
    query: [Getter],
    data: [Getter]
  },
  query: {}
}

As you can see the extra data is already filled. So this is maybe also a rare bug caused by thread-loader that because it spreads the output compilation in fragments we cannot determine the output path yet. This hypothesis is still debatable however.

And I believe I'm right, according to thread-loader's README:

Loaders running in a worker pool are limited. Examples:

  • Loaders cannot emit files.
  • Loaders cannot use custom loader API (i. e. by plugins).
  • Loaders cannot access the webpack options.

Then I believe we have no solutions at all in this case. extractCSS must be disabled if build.parallel evaluates to true.

0
Informations
Bug Report โ€ข Open
#c8616 - Created 5 months ago