2017-01-30 6 views
1

Я укусил пулю и переключился на модульный подход к 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>&nbsp;</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), но это не помогло.

+0

Возможно: https://github.com/webpack/webpack-dev-server/issues/128? –

+0

Я вообще не использую SASS. Не знаете, как и где следует использовать упомянутое изменение UV_THREADPOOL_SIZE. Я пробовал 'process.env.UV_THREADPOOL_SIZE = 128' в скрипте dev-server.js, но проблема все еще происходит. Это массивный шоу-стоппер, поскольку я просто не могу добиться дальнейшего прогресса, если не могу использовать этот компонент. –

+0

Вы заметили, что не закрываете последний тег ''? –

ответ

0

К счастью, проблема оказалась не какой-то тревожно неясной, а простой факт, что я не закрыл тег скрипта должным образом. Я чувствую себя очень глупо, но также чувствую облегчение. Спасибо за Roy J за это.

+1

Я должен добавить, что хотя эта проблема была результатом простой неудобства кодирования с моей стороны, я немного удивлен тем, что webpack-dev-сервер или какой-либо элемент в его оснастке не смог выплюнуть ошибку сообщение, предупреждающее меня о синтаксической ошибке в определенном файле. –