I am using both vue single-file components and separating of markup and logic to .pug
and .ts
files respectively. If you interesting why I don't unify is please see the comments section.
Problem
import template from "@UI_Framework/Components/Controls/InputFields/InputField.vue.pug";
import { Component, Vue } from "vue-property-decorator";
console.log(template);
@Component({
template,
components: {
CompoundControlBase
}
})
export default class InputField extends Vue {
// ...
}
In development building mode exported template is correct (I beautified it for readability):
<CompoundControlBase
:required="required"
:displayInputIsRequiredBadge="displayInputIsRequiredBadge"
<TextareaAutosize
v-if="multiline"
:value="value"
/><TextareaAutosize>
</CompoundControlBase>
In production mode, my markup has been lowercased. So, the console.log(template)
outputs:
<compoundcontrolbase
:required=required
:displayinputisrequiredbadge=displayInputIsRequiredBadge
<textareaautosize
v-if=multiline
:value=value
></textareaautosize>
</compoundcontrolbase>
Off course, I got broken view.
Webpack config
const WebpackConfig = {
// ...
optimization: {
noEmitOnErrors: !isDevelopmentBuildingMode,
minimize: !isDevelopmentBuildingMode
},
module: {
rules: [
{
test: /\.vue$/u,
loader: "vue-loader"
},
{
test: /\.pug$/u,
oneOf: [
// for ".vue" files
{
resourceQuery: /^\?vue/u,
use: [ "pug-plain-loader" ]
},
// for ".pug" files
{
use: [ "html-loader", "pug-html-loader" ]
}
]
},
// ...
]
}
}
Comments
To be honest, I don't know why we need ?
in resourceQuery: /^\?vue/u,
(explanations are welcome).
However, in development building mode above config works property for both xxxx.vue
and xxxx.vue.pug
files.
I am using below files naming convention:
xxx.pug
: pug file which will not be used as vue component template.xxx.vue.pug
: pug file which will be used as vue component template.xxx.vue
: single-file vue component.xxx.vue.ts
: the logic of vue component. Required exported template fromxxx.vue.pug
as inInputField
case.
Why I need xxx.vue.ts
? Because of this:
declare module "*.vue" {
import Vue from "vue";
export default Vue;
}
Neither public methods/fields nor non-default methods are visible for TypeScrpt xxx.vue
files. For the common (non-applied) components, I can't accept it.
Repro
Step 1: Install dependencies
npm i
Step 2: Let's check the development building first
npm run DevelopmentBuild
In line 156 of DevelopmentBuild\EntryPoint.js
, you can check that below pug template:
Alpha
Bravo OK
has been compiled properly:
Step 3: Problem on production build
npm run ProuductionBuild
You can find the lowercased tags in the column 13:
You can also open index.html
in your browser and check the console.log()
output with compiled TestComponent
.
options
must be associated with certain loader. To make it work, we need[ { loader: "html-loader", options: { minimize: { caseSensitive: true }}}, "pug-html-loader" ]
instead of[ "html-loader", "pug-html-loader" ]
. – Lakendra