Я укусил пулю и переключился на модульный подход к Vue.js, используя vue-cli и Webpack. Там была небольшая кривая обучения с реструктуризацией моего приложения в отдельные файловые компоненты, но я в основном туда добирался. Однако я столкнулся с очень загадочной проблемой. У меня есть достаточно сложный компонент ProductDetail, который использует несколько дочерних компонентов. Как только я добавлю один из них, называемый TabPage (включив строку импорта и добавляя его к свойству компонентов), компиляция зависает (и если я перезапущу «npm run dev», она аналогично зависает при запуске, прежде чем перейти к точке, где это страницы обслуживания). Остальные 6 компонентов вообще не вызывают этой проблемы.Компонент вызывает «npm run dev» для зависания
Теперь причудливая вещь заключается в том, что этот компонент TabPage может быть пустым, являясь не чем иным, как шаблоном, выводящим пустой div, и проблема все еще возникает, поэтому это не может быть проблемой с этим компонентом (кроме того которые все работали в версии приложения, прежде чем я переключился на использование vue-cli). И это только этот компонент, ничто другое не вызывает проблемы.
Итак, есть ли какие-то способы отладки процесса компиляции, чтобы я мог точно видеть, где возникает проблема?
Для чего это стоит, вот компонент ProductDetail (с методами удаления довести все это до размера StackOverflow доволен):
<template>
<div class="container edit-product">
<ul class="nav nav-tabs">
<tab-link page="Product"></tab-link>
<tab-link page="Pricing"></tab-link>
<tab-link page="History"></tab-link>
<tab-link page="Shop"></tab-link>
</ul>
<div class="tab-content">
<tab-page page="Product">
<form @submit.prevent.stop class="edit-form">
<div class="form-fields">
<common-header :product="this.product" :error="this.error"></common-header>
<div class="row">
<cell :cols="8"><text-field name="name" v-model="product.name"/></cell>
<cell :cols="1"><text-field name="pack" v-model.number="product.pack" format="numeric"/></cell>
<cell :cols="3"><text-field name="size" v-model="product.size"/></cell>
</div>
<div class="row">
<cell :cols="2">
<text-field name="code" v-model="product.code" :attrs="{maxlength: 5}">
<button slot="after" type="button" class="btn btn-sm fld-btn" @click="seeExisting">Existing</button>
</text-field>
</cell>
<cell :cols="2">
<text-field name="supplierCode" v-model="product.supplierCode">
<button slot="after" type="button" class="btn btn-sm fld-btn" @click="selectSupplier">Select</button>
</text-field>
</cell>
<cell :cols="5">
<text-field name="supplierName" v-model="product.supplierName" :attrs="{disabled: true}"/>
</cell>
<cell :cols="3">
<text-field label="Supplier's Product Code" name="supplierProdCode" v-model="product.supplierProdCode"/>
</cell>
</div>
<div class="row">
<cell :cols="6">
<text-field name="categorization" v-model="categorization" :attrs="{disabled: true}">
<button slot="before" type="button" class="btn btn-sm fld-btn" @click="categorize">Set</button>
</text-field>
</cell>
<cell :cols="6">
<text-field name="tradeName" v-model="product.tradeName"/>
</cell>
</div>
<div class="row">
<cell :cols="12">
<checkbox-field inline="true" name="readyPacked" label="Ready-Packed" v-model="product.readyPacked"></checkbox-field>
<checkbox-field inline="true" name="shop" v-model="product.shop"></checkbox-field>
<checkbox-field inline="true" name="organic" v-model="product.organic"></checkbox-field>
<checkbox-field inline="true" name="withSugar" v-model="product.withSugar"></checkbox-field>
<checkbox-field inline="true" name="stockControlled" label="Stock-controlled" v-model="product.stockControlled"></checkbox-field>
<checkbox-field inline="true" name="vegan" v-model="product.vegan"></checkbox-field>
<checkbox-field inline="true" name="fairTrade" v-model="product.fairTrade"></checkbox-field>
<checkbox-field inline="true" name="glutenFree" label="Gluten-free" v-model="product.glutenFree"></checkbox-field>
</cell>
</div>
<div class="row">
<cell :cols="1">
<text-field name="aisle" v-model="product.aisle" :attrs="{maxlength: 2}" format="uppercase"/>
</cell>
<cell :cols="1">
<text-field name="bay" v-model="product.bay" :attrs="{maxlength: 2}" format="uppercase"/>
</cell>
<cell :cols="1">
<text-field name="shelf" v-model.number="product.shelf" :attrs="{maxlength: 2}" format="integer"/>
</cell>
<cell :cols="2">
<text-field type="select" name="squashiness" v-model="product.squashiness" :options="['Bags','Bottles','Boxes','Sacks','Delicates','Prepacks','Split Cases']"/>
</cell>
</div>
<div class="row">
<cell :cols="2">
<text-field name="identifier" v-model="product.identifier" />
</cell>
<cell :cols="2">
<text-field name="grossWeight" after-class="input-group-addon" label="Gross Weight" v-model="product.grossWeight" format="numeric"><span slot="after">kg</span></text-field>
</cell>
<cell :cols="2">
<text-field name="substituteCode" v-model="product.substituteCode" />
</cell>
<cell :cols="3">
<text-field name="outerCaseBarcode" v-model="product.outerCaseBarcode" format="integer"/>
</cell>
</div>
<div class="row">
<cell :cols="12">
<text-field type="textarea" name="notes" v-model="product.notes" :attrs="{rows: 1}" />
</cell>
</div>
</div>
<div class="row">
<cell :cols="12">
<button type="button" class="btn btn-sm" @click.prevent="returnToList">Cancel</button>
<button type="button" class="btn btn-sm"
@click.prevent="saveAndBack">Save, Back To List</button>
<button type="button" class="btn btn-sm btn-primary"
@click.prevent="save">Save and Continue</button>
</cell>
</div>
</form>
</tab-page>
<tab-page page="Pricing">
<form class="edit-form">
<div class="form-fields">
<common-header :product="this.product" :error="this.error"></common-header>
<div class="row">
<cell :cols="8">
<div class="row">
<cell :cols="2">
<text-field type="select" name="basedOn" v-model="product.basedOn" :options="['T','B','C']" :styles="{width:'100%'}"/>
</cell>
<cell :cols="2"><text-field name="priceBase" v-model.number="product.priceBase" format="currency"/></cell>
<cell :cols="2"><text-field name="newPriceBase" v-model.number="product.newPriceBase" format="currency"/></cell>
<cell :cols="2">
<text-field type="select" name="vatRating" v-model="product.vatRating" :options="[{ text: 'Zero', value: '0.00'},{text: 'Reduced', value: '5.00' },{text: 'Standard', value: '20.00'}]" @input="calcRRP"/>
</cell>
<cell :cols="2"><text-field name="price" label="Rainbow Price" v-model.number="product.price" format="currency" :attrs="{disabled:true}"/></cell>
<cell :cols="2"><text-field name="unitPrice" label="Per unit/kg" v-model.number="product.unitPrice" format="currency" :attrs="{disabled:true}"/></cell>
</div>
</cell>
</div>
<div class="row">
<cell :cols="3">
<checkbox-field inline="true" name="hasRRP" label="Has RRP" v-model="product.hasRRP" @input="calcRRP"></checkbox-field>
<checkbox-field v-if="product.hasRRP" inline="true" name="useNonFoodRRP" label="Non-food RRP" v-model="product.useNonFoodRRP" @input="calcRRP"></checkbox-field>
</cell>
<cell :cols="8">
<div class="row">
<template v-if="product.hasRRP">
<cell :cols="2"><text-field name="rrp" label="RRP" v-model.number="product.RRP" format="currency" :attrs="{disabled:true}"/></cell>
<cell :cols="2" ><text-field name="manualRRP" label="Over-ride RRP" v-model.number="product.manualRRP" format="currency"/></cell>
</template>
<cell :cols="6"><text-field name="remark" label="Remark" v-model="product.remark" /></cell>
<cell :cols="2"><button type="button" class="btn btn-sm btn-inline"
@click.prevent="recalc">Recalculate Now</button></cell>
</div>
</cell>
</div>
</div>
<button-bar></button-bar>
</form>
</tab-page>
<tab-page page="History">
<form class="edit-form">
<div class="form-fields">
<common-header :product="this.product" :error="this.error"></common-header>
<button-bar></button-bar>
</div>
</form>
</tab-page>
<tab-page page="Shop">
<form class="edit-form">
<div class="form-fields">
<common-header :product="this.product" :error="this.error"></common-header>
<template v-if="this.product.shop==true">
<div class="row">
<cell :cols="6">
<button type="button" class="btn btn-sm btn-inline" @click.prevent="addShopLine">Add New</button>
</cell>
<cell :cols="6" :styles="{'text-align':'right'}">
<button type="button" class="btn btn-sm btn-inline" @click.prevent="autoLabel">Auto Label</button>
</cell>
</div>
<div class="row">
<div class="col-xs-12">
<table id="shop-lines">
<thead>
<tr>
<th>Unit</th>
<th class="price">Price</th>
<th>Variety</th>
<th class="barcode">Barcode</th>
<th>Label</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr class="shop-line-row" v-for="(shopLine, index) in this.product.shopLines">
<td><text-field table-cell="true" :name="'unit'+index" type="select" v-model="shopLine.unit"
:options="['2.5kg','1kg','500g','250g','125g','50g','25g','Unit (Low)','Unit (High)', 'Unit (Non-food)']" :styles="{width:'100%'}" /></td>
<td class="price"><text-field table-cell="true" :name="'price'+index" v-model.number="shopLine.price" format="currency"/></td>
<td><text-field table-cell="true" :name="'variety'+index" v-model="shopLine.variety"/></td>
<td class="barcode"><text-field table-cell="true" :name="'barcode'+index" v-model.number="shopLine.barcode" format="integer"/></td>
<td><text-field table-cell="true" :name="'label'+index" v-model="shopLine.label"/></td>
<td><button @click.prevent="removeShopLine(index)">X</button></td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<template v-else>
<div class="row">
<cell :cols="12">
<p>This product is not sold at the shop</p>
</cell>
</div>
</template>
<button-bar></button-bar>
</div>
</form>
</tab-page>
</div>
</div>
</template>
<script>
import bus from '../../bus'
import TabPage from '../TabPage'
import TabLink from '../TabLink'
import Cell from '../Cell'
import TextField from '../TextField'
import CheckboxField from '../CheckboxField'
import CommonHeader from './CommonHeader'
import ButtonBar from './ButtonBar'
export default {
data() {
return {
action:null,
product: {},
productCopy:{},
page:'Product',
error:"",
errorField:null,
validations:{
}
}
},
components:{
TabPage,TabLink,Cell,TextField,CheckboxField,CommonHeader,ButtonBar
},
watch: {
'$route' (to, from) {
this.setAction();
}
},
created() {
bus.$on('SelectSupplier', (supplier) =>{
this.product.supplierCode=supplier.code;
this.product.supplierName=supplier.name;
});
bus.$on('SelectSubcategory', (subcategory)=> {
this.product.subcategory=subcategory.name;
this.product.subcategoryId=subcategory.id;
this.product.category=subcategory.categoryName;
this.product.categoryId=subcategory.categoryId;
});
bus.$on("set-page", (page)=> {
this.validatePage();
if (this.error == "") {
var currentPage = this.page;
this.page = page;
bus.$emit("update-page", this.page);
}
});
bus.$on("button-action", (action)=> {
this[action]();
});
},
mounted(){
this.setAction();
if(this.action=="edit"){
this.buildTitle("Edit Product");
} else if(this.action=="dupe") {
this.buildTitle("Duplicate Product");
} else if(this.action=="create") {
this.buildTitle("Create Product");
}
},
beforeRouteLeave (to, from, next) {
if(_.isEqual(this.product, this.productCopy)){
next();
} else {
var self=this;
bootbox.confirm({
message: "Are you sure want to leave the product editor? You will lose any new or changed data",
buttons: {
confirm: {
label: 'Back To List',
},
cancel: {
label: 'Continue Editing',
}
},
callback: function (result) {
if(result){
next();
} else {
next(false);
}
}
});
}
},
computed: {
fullName() {
return this.product.name + ", " + this.product.pack + this.product["size"];
},
displayName() {
if (this.product.code && this.product.code.length == 5) {
return this.product.code + ": " + this.fullName;
} else {
return this.fullName;
}
},
categorization(){
if (this.product.category && this.product.subcategory) {
return this.product.category + ": " + this.product.subcategory;
} else {
return "";
}
},
settings(){
return this.$store.state.settings;
}
},
methods: {
//BUNCH OF METHODS REMOVED HERE TO BRING TEXT SIZE DOWN BELOW 30,000
}
}
</script>
А вот полностью срезан компонент TabPage, чей включение в вышеприведенной компоненте вызывает компиляцию повесить:
<script>
export default{
name:"tab-page",
template:`<div>EMPTY</div>`
}
</script
Я повышен до последнего узла (v6.9.4 LTS), но это не помогло.
Возможно: https://github.com/webpack/webpack-dev-server/issues/128? –
Я вообще не использую SASS. Не знаете, как и где следует использовать упомянутое изменение UV_THREADPOOL_SIZE. Я пробовал 'process.env.UV_THREADPOOL_SIZE = 128' в скрипте dev-server.js, но проблема все еще происходит. Это массивный шоу-стоппер, поскольку я просто не могу добиться дальнейшего прогресса, если не могу использовать этот компонент. –
Вы заметили, что не закрываете последний тег ''? –