Skip to content

Incompatible with thread-loader if compiler or any option that includes non serializable value used. #1705

Closed
@mmis1000

Description

@mmis1000

Version

16.0.0-beta.4

Reproduction link

https://github.com/mmis1000/vue-3-bug-report-compiler-option

Steps to reproduce

  1. setup a template using https://github.com/vuejs/vue-cli-plugin-vue-next
  2. write a simple compiler
const { baseCompile, baseParse } = require('@vue/compiler-core')
Object.assign(module.exports, require('@vue/compiler-core'))

module.exports.compile = baseCompile
module.exports.parse = baseParse
  1. load the compiler with vue.config.js
const vuePluginNext = require.resolve('vue-cli-plugin-vue-next')
const vueLoaderNext = require.resolve('vue-loader', {paths: [vuePluginNext] })

module.exports = {
    chainWebpack: config => {
        config.module
            .rule('vue')
            .use('vue-loader')
            .loader(vueLoaderNext)
            .tap(options => {
                // modify the options...
                return {
                    ...options,
                    compiler: path
                }
            })
    }
}
  1. run npm build

What is expected?

It builds

What is actually happening?

It crashed with

Module build failed (from ./node_modules/thread-loader/dist/cjs.js):
Thread Loader (Worker 3)
compiler.compile is not a function

The vue3 allow you to specify the compiler using the 'compiler' option of the loader.
However, when the https://cli.vuejs.org/config/#parallel is used(this is the default).
The config is send to other process as a string.
And any non-serializable options will break during the serialization.

The vue-loader should accept the compiler option with string type and require the package on its own like what babel / eslint did.
They both accept package name/filename string instead of module instance.

So their options are completely fine with the serialization .

Something like

vue-loader/dist/templateLoader.js

      const scopeId = query.scoped ? `data-v-${query.id}` : null;
+     if (typeof options.compiler === 'string') {
+        options.compiler = require(options.compiler)
+     }
      const compiled = compiler_sfc_1.compileTemplate({
          source,
          inMap,

will do the job.

See also: vuejs/vue-cli#5723

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions