Vue-next: Unable get rid of web component warning

Created on 21 Jun 2020  路  13Comments  路  Source: vuejs/vue-next

Version

3.0.0-beta.15

Reproduction link

https://github.com/blacksonic/vue-3-playground

Steps to reproduce

  • Create a webcomponent with the name x-username
  • Modify the app instance config to test for webcomponents
  • Include the webcomponent in a vue template
  • Config of the application
    app.config.isCustomElement = tag => /^x-/.test(tag);

What is expected?

The application shouldn't log warning as it is configured to treat the element as a webcomponent

What is actually happening?

Vue logs warning:
The component is displayed however


I wanted to find a replacement from Vue 2 ignoredElements
Vue.config.ignoredElements = [/^x-/];

Most helpful comment

You can add the blew config into vite.config.js.Because your template will compiled by sfc compiler.

vueCompilerOptions: {
    isCustomElement: tag => {
      return /^x-/.test(tag)
    }
  }

Other the app.config.isCustomElement = tag => /^x-/.test(tag); only work with runtime-dom compiler.

All 13 comments

Not 100% yet, but I think we have to extend idNativeTag to check against app.context.isCustomElement.

https://github.com/vuejs/vue-next/blob/e4dc03a8b17d5e9f167de6a62a645878ac7ef3e2/packages/runtime-dom/src/index.ts#L99-L106

It seems to me that we only use it in the compiler so far, so any custom element declared in a render function (or compiled during build) will resolve in a failure here.

You can add the blew config into vite.config.js.Because your template will compiled by sfc compiler.

vueCompilerOptions: {
    isCustomElement: tag => {
      return /^x-/.test(tag)
    }
  }

Other the app.config.isCustomElement = tag => /^x-/.test(tag); only work with runtime-dom compiler.

@underfin how can I add the same to Vue CLI?

You can add this into webpack config.It should work (I'm not test it).

{
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          compilerOptions: {
    isCustomElement: tag => {
      return /^x-/.test(tag)
    }
  }
        }

Oh so we really only check during compile time? My mistake then.

@blacksonic for vue-cli you would have to do something like this:

// vue.config.js
module.exports = {
  chainWebpack: config => {
   // get the existing vue-loader rule and tap into its options
    config.module.rule('vue-loader').tap(options => {
      option.compilerOptions = {
         ...(options.compilerOptions || {}), // merge existing compilerOptions, if any
         isCustomElement: tag => /^x-/.test(tag)
      }
    })
  }
}

Oh so we really only check during compile time? My mistake then.

Look it is for now and this will not generate code for customer component import and don't check it with runtime.

@LinusBorg
What can I do if the tap function doesn't exist?
The webpack-chain packages documentation seems to call use before calling tap.

I get this message:
(node:10740) UnhandledPromiseRejectionWarning: TypeError: config.module.rule(...).tap is not a function

I've tried this

config.module
      .rule('vue')
      .use('vue-loader')
      .loader('vue-loader')
      .tap(options => {
        options.compilerOptions = {
          ...(options.compilerOptions || {}), // merge existing compilerOptions, if any
          isCustomElement: tag => /^e-/.test(tag)
        }
      });

but now it seems that it tries to compile components with vue-template-compiler.

Vue packages version mismatch:

- [email protected] (/Users/esysuser/workspace/vue-example-client/node_modules/vue/index.js)
- [email protected] (/Users/esysuser/workspace/vue-example-client/node_modules/vue-template-compiler/package.json)

This may cause things to work incorrectly. Make sure to use the same version for both.
If you are using vue-loader@>=10.0, simply update vue-template-compiler.
If you are using vue-loader@<10.0 or vueify, re-installing vue-loader/vueify should bump vue-template-compiler to the latest.
Module build failed (from ./node_modules/vue-loader/lib/index.js):
TypeError: Cannot read property 'parseComponent' of undefined

As pointed out, Vue 3 requires configuring custom elements via compiler options if pre-compiling templates.

This seems to be now a Vue CLI specific configuration problem so I'm closing it. But feel free to continue the discussion.

/cc @sodatea

I've found the fix.

The Vue CLI config is:

module.exports = {
  chainWebpack: config => {
    config.module
      .rule('vue')
      .use('vue-loader')
      .loader('vue-loader')
      .tap(options => {
        options.compilerOptions = {
          ...(options.compilerOptions || {}),
          isCustomElement: tag => /^x-/.test(tag)
        };
        return options;
      });
  }
};

And in addition, I needed to install the beta version of vue-loader

This seems to break now that vue-cli isn't using vue-cli-plugin-vue-next anymore.
I'm getting

Module Error (from ./node_modules/vue-loader/lib/index.js):
[vue-loader] vue-template-compiler must be installed as a peer dependency, or a compatible compiler implementation must be passed via options.

When removing the vue-loader rule the app will compile but the warnings show up again.
My uneducated guess is that setting the compilerOptions will force vue-loader to use vue-template-compiler?
Any idea how to fix this?

EDIT: installing the beta version of vue-loader fixed that for me as well

I'm still getting the error when using custom webpack build

Failed to resolve component: xyz

Versions:

"vue": "^3.0.2",
"vue-loader": "^16.0.0-rc.1"

Webpack:

{
...
rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          compilerOptions: {
            isCustomElement: tag => /^xyz/.test(tag),
          },
        },
      },
     ...
],
...
plugins: [
    new VueLoaderPlugin(),
    ...
]
}
Was this page helpful?
0 / 5 - 0 ratings