"name" in @Component options is obfuscated (?) in build version
Repro: https://github.com/sp00x/vue-typescript-name-bug
2 components, Foo (ts) and Bar (js) registered as global components in main.ts using
import Foo from '@/components/Foo.vue';
import Bar from '@/components/Bar.vue';
Vue.component(Foo.name, Foo) // typescript
Vue.component(Bar.name, Bar) // javascript
With yarn serve it logs in the console:
in App.vue:
Foo.name = Foo
Bar.name = Bar
in main.ts
Foo.name = Foo
Bar.name = Bar
and renders
Foo:
foo
- Bar:
bar
With yarn build output it logs in the console:
in App.vue:
Foo.name = t
Bar.name = Bar
in main.ts
Foo.name = t
Bar.name = Bar
renders:
Foo: - Bar:
bar
Foo is a typescript SFC, where as Bar is a regular javascript SFC with export default { name: 'Bar' }
Seems like the typescript value is being obfuscated or uglified somehow?
Similar issues, which even leads to some very strange and incosistence behaviors on ssr. Did you find any workaround or fix already?
@simllll My current workaround is to register with a static, known name vue.component('Foo', Foo) ...which is not ideal, nope.
Having the same issue. Hoping for quick resolution
This is actually a side effect of terser webpack plugin. If you disable terser's mangling, things work fine. I added the following in my nuxt config in build.extend() function:
if (isServer) {
// replace terser on server side with "mangle: false"
config.optimization.minimizer = config.optimization.minimizer.map(o => {
if (o.constructor.name === 'TerserPlugin') {
return new TerserPlugin({
cache: true,
parallel: true,
sourceMap: true, // Must be set to true if using source-maps in production
terserOptions: {
mangle: false
}
});
}
return o;
});
}
Thanks @simllll, this helped!
That looks because we use class name to infer the component name. We probably need to remove this inference in the next major version as its behavior is inconsistent between builds.
This worked for me in webpack4 without increasing the bundle size too much
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
keep_classnames: true,
},
}),
],
},
}
Trinovantes' proposition is far better than disabling the mangling altogether, as proposed by simllll. I'll just add that in my (legacy) project/setup, I had to tell terserjs to keep the function names, not the class names, because before the code is passed to terserjs, the code is already transpiled to es5. In other words, I had to do the following:
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
keep_fnames: true,
},
}),
],
},
}
I did end up, however, upgrading the library (vue-slider-component) that uses vue-class-component under the bonnet, which also resolved the problem for me.
As a side note: it's regrettable that after 2 years, this still isn't fixed and released in the v7 of vue-class-component. This problem is so easy to run into.
For future readers:
when you refer to class-component name like that:
Foo.name
you refer to the name of the class itself. name property here is Function.name property, not Vue property. It will be obfuscated.
You can get actual component name using Foo.options.name, that name property is Vue property, it will contain correct name set from options.