วิธีและเหตุผลในการตั้งค่าบิลด์ที่ให้คุณเขียนส่วนประกอบ .vue ใน TypeScript
โอเค อาจจะไม่ใช่ทั้งวัน แต่ก็ยังใช้เวลานานเกินไปในการตั้งค่าเครื่องมือสำหรับโปรเจ็กต์ใหม่ และบางสิ่งยังยากเกินไปสำหรับรสนิยมของฉัน ไม่ใช่สิ่งที่ 'ยาก' ที่ดีเหมือนกับ ความท้าทาย เหมือนน่าเบื่อเลย ใช่ ฉันกำลังพูดถึง "webpack", "TypeScript" และไฟล์ .vue
ฉันอยากจะแสดงให้เห็นว่าฉันทำอะไรลงไป และทำไมฉันถึงยังทำแบบนั้นอยู่
หากคุณกำลังมองหาการแก้ไข TypeScript อย่างรวดเร็ว นั่นค่อนข้างง่าย คว้า "webpack-blocks" และตั้งค่าภายใน 5 นาที สิ่งที่ฉันพยายามทำคือแปลกใหม่มากกว่านี้ถ้าคุณต้องการ ฉันต้องการใช้ Vue และโดยเฉพาะไฟล์ .vue
กับ TypeScript ข้อมูลกระจัดกระจายไปทั่วเว็บ ดังนั้นฉันจึงคิดว่าการรวบรวมข้อมูลทั้งหมดไว้ที่นี่เพื่อใช้อ้างอิงอย่างรวดเร็วอาจไม่ใช่ความคิดที่ดี
8 พฤษภาคม 2017 อัปเดต:ตั้งแต่ฉันเขียนบทความนี้ webpack-blocks 1.0.0 ก็เกือบจะวางจำหน่ายแล้ว มีให้บริการแล้วบน NPM ดังนั้นฉันจึงใช้เวลาในการเผยแพร่โค้ดบางส่วนที่กล่าวถึงในบทความนี้ ฉันจะเผยแพร่โพสต์แยกต่างหากซึ่งสรุปการเปลี่ยนแปลงเมื่อเทียบกับบทความต้นฉบับ
ก่อนที่เราจะเริ่มต้น ลืมสิ่งที่คุณรู้เกี่ยวกับวิธีเขียนส่วนประกอบ Vue หากคุณต้องการใช้ไฟล์ .vue
ด้วย TypeScript คุณต้องเขียนโค้ดด้วยวิธี TypeScript แน่นอนคุณสามารถเขียนโค้ดด้วยวิธีเก่าได้ แต่คุณจะไม่ได้รับประโยชน์จากการตรวจสอบประเภท ดังนั้นจึงเป็นการเสียเวลาของคุณ คุณได้รับคำเตือน
ทำไมต้องเป็นไฟล์ .vue
ก่อนอื่น ให้ฉันอธิบายว่าทำไมฉันถึงต้องการให้ .vue
ไฟล์เริ่มต้นด้วย (ในกรณีที่คุณไม่รู้ว่ามันคืออะไร ดูที่ ที่นี่) แพ็คเกจไฟล์เดียวหลายภาษาเหล่านี้ไม่ได้เป็นเพียงเครื่องมือสำหรับการจัดกลุ่มสิ่งที่อาจเป็นชุดของไฟล์หลวม ๆ เข้าด้วยกัน ไม่ พวกเขามีข้อดีของตัวเองที่เป็นมากกว่าการรวมโค้ดเข้าด้วยกัน
ตัวอย่างเช่น เทมเพลต HTML ถูกเข้ารหัสด้วย HTML ดังนั้นคุณจึงได้รับการสนับสนุนการเน้นไวยากรณ์ การเติมข้อมูลอัตโนมัติแบบรับรู้บริบท และ/หรือการสนับสนุน emmet นักพัฒนา JavaScript ที่ยอดเยี่ยมนั้นมีไม่มากนัก ดังนั้นการเขียนโค้ด HTML ธรรมดา (ซึ่งตรงข้ามกับ JSX และที่แย่กว่านั้นคือ hyperscript) จึงสามารถไปได้ไกล ใช่ ฉันทราบดีว่ามีเรื่องราวเกี่ยวกับนักออกแบบและมือใหม่ที่เลือกใช้ไฮเปอร์สคริปต์และสิ่งที่คล้ายคลึงกัน และจริงๆ แล้วชอบมัน แต่คุณต้องจำไว้ว่าแม้แต่นักพัฒนา JavaScript ที่มีประสบการณ์ก็ไม่ยอมแพ้โดยไม่ต้องทะเลาะกันในบางครั้ง
ประการที่สอง CSS ที่กำหนดขอบเขต หากคุณยังคงคิดว่า BEM มีตำแหน่งในเฟรมเวิร์กส่วนหน้าที่มีเครื่องมืออย่างเหมาะสม แสดงว่าคุณเข้าใจถึงความสำคัญและความท้าทายของ CSS ที่ได้รับการจัดการอย่างดี คุณอาจถูกเตะออกจาก CSS ที่กำหนดขอบเขต ฉันจะไม่พยายามขาย CSS ที่กำหนดขอบเขตให้คุณ มันเหมือนกับยาเสพติด: มันขายตัวมันเอง แค่ลองดู. ฉันท้าคุณ.
ทั้งหมดนี้ และความจริงที่ว่าฉันกำลังจัดการกับไฟล์เดียวแทนที่จะเป็นสามหรือสี่ไฟล์ ถือเป็นข้อโต้แย้งที่ดีพอที่จะใช้เวลาเพิ่มเติมในการรับไฟล์ .vue
ที่ทำงานกับ TypeScript
ทำไมต้องพิมพ์สคริปต์?
นี่คือสิ่งที่คุณต้องมาถึงด้วยตัวเองหากเคย ในอดีตผู้คนเคยใช้ JavaScript ที่ไม่ได้พิมพ์ และมันใช้งานได้จริง อันที่จริง ฉันกำลังพยายามตัดสินใจระหว่าง TypeScript และ "LiveScript" ซึ่งเป็น "CoffeeScript" เวอร์ชันที่ยังไม่ได้พิมพ์ ซึ่งมีไวยากรณ์ที่สั้นและค่อนข้างแปลก
ท้ายที่สุดแล้ว มันขึ้นอยู่กับประสิทธิภาพการทำงาน LiveScript มีไวยากรณ์และทางลัดที่ละเอียดน้อยกว่าสำหรับหลายสิ่งที่ฉันใช้ในแต่ละวัน TypeScript จะตรวจจับข้อผิดพลาดในการเขียนโค้ดมากมายที่ฉันอาจทำ และอาจให้ข้อมูลเพิ่มเติมเกี่ยวกับโค้ดที่ทำให้การทำงานกับไลบรารีและเฟรมเวิร์กที่ไม่คุ้นเคยง่ายขึ้นมาก ฉันเลือกอย่างหลังมากกว่าอันแรกด้วยเหตุผลความรู้สึกโดยพลการ
หากคุณต้องขอบัญชีกราฟิกว่าการใช้ TypeScript ในการผลิตเป็นอย่างไร มี บทความดีๆ จากทีม Slack
พูดพอแล้ว มาเขียนโค้ดกันดีกว่า… หรืออาจจะไม่ใช่ก็ได้
ก่อนที่เราจะสามารถเขียนโค้ดได้ เราต้องตั้งค่าเครื่องมือก่อน
ขั้นแรก เลือก webpack-blocks นั่นเป็นวิธีที่ง่ายที่สุดในการกำหนดค่า webpack ที่ฉันรู้ ง่ายที่สุดหลังจากเพียงแค่คัดลอกและวางการกำหนดค่าที่มีอยู่ แต่คุณเข้าใจประเด็นของฉัน
ตอนนี้ webpack-blocks ไม่ รองรับไฟล์ .vue
ไฟล์ทันที มีแพ็คเกจบุคคลที่สามสองแพ็คเกจที่ทำให้สามารถใช้ไฟล์ .vue
ได้
การกำหนดค่า TypeScript ในตัวใน webpack-blocks ใช้ "awesome-typescript-loader" มันเป็นตัวโหลดที่ดี แต่ไม่เล่นได้ดีกับไฟล์ .vue
(มันมีชื่อแปลกๆ ด้วย แต่นั่นคือปัญหาของฉัน) นอกจากแพ็คเกจสำหรับการกำหนดค่า vue-loader
แล้ว เรายังต้องมีแพ็คเกจที่จะกำหนดค่า ts-loader
ซึ่งมีข้อกำหนดบางประการสำหรับการทำงานกับรูปแบบคอนเทนเนอร์ เช่น .vue
npm i -D webpack-blocks-vue webpack-blocks-ts
ในที่สุดคุณก็จะได้ไฟล์แบบนี้ webpack.config.js
สิ่งสำคัญที่ควรทราบ:
- เรากำลังส่งตัวเลือก
{ appendTsSuffixTo: [/\.vue$/] }
ไปยัง ts-loader เพราะไม่เช่นนั้นคอมไพเลอร์ TypeScript ก็ไม่ต้องการให้ความร่วมมือ สิ่งนี้ทำให้ไฟล์.vue
ถือเป็น.vue.ts
เช่นเดียวกับที่คอมไพเลอร์ TypeScript ชอบ - เราไม่ได้ใช้บาเบล หากคุณต้องการใช้ JSX คุณอาจต้องการใช้มัน แต่ฉันไม่ต้องการ
- เรากำลังส่ง
{ esModule: true }
ไปยัง vue-loader ตัวเลือกนี้บอกให้โหลดเดอร์ปล่อยโมดูล ES2015 แทนที่จะเป็นโมดูล CommonJS เห็นได้ชัดว่า TypeScript ไม่ชอบโมดูล CommonJS
คุณต้องแจ้งให้ TypeScript ทราบว่าไฟล์ .vue
คืออะไร และจะจัดการกับไฟล์เหล่านี้อย่างไร เพื่อจุดประสงค์นี้ เราจึงเพิ่ม vue.d.ts
file ลงในแผนผังต้นทาง คำจำกัดความนี้จะบอก TypeScript ว่าการส่งออกเริ่มต้นจากไฟล์ .vue จะเป็นอย่างไร
ตอนนี้เราเขียนโค้ดได้ไหม?
ใช่เราทำได้ ตามที่ฉันได้กล่าวไว้ในบทนำ คุณไม่สามารถเขียนโค้ดเหมือนแต่ก่อนและคาดหวังว่าสิ่งต่างๆ จะได้ผลได้ การเข้ารหัสไฟล์ .vue
สำหรับ TypeScript ต้องใช้แนวทางที่แตกต่างออกไป แต่อย่ากลัวเลย ไวยากรณ์ทางเลือกนั้นสมเหตุสมผลมาก และในความคิดของฉัน ทำให้โค้ดอ่านง่ายขึ้นมาก (ไม่ต้องพูดถึงประเภทการตรวจสอบความดี)
ก่อนอื่นคุณจะต้องเพิ่มการพึ่งพาเพิ่มเติม: vue-property-decorator
ส่วนประกอบของคุณจะมีลักษณะดังนี้:
<template> <div class="hello">Hello, {{ name }}</div> </template> <script lang="ts"> import Vue from 'vue' import { Component, Prop } from 'vue-property-decorator' @Component export default class Hello extends Vue { @Prop name: string } </script> <style scoped> .hello { font-size: 200px; font-family: sans-serif; } </style>
ฉันจะไม่ลงรายละเอียดมากเกินไปที่นี่ เพราะทั้ง vue-property-decorator และ vue-class-component ซึ่งใช้เป็นหลัก ได้รับการจัดทำเอกสารไว้ค่อนข้างดีและตรงไปตรงมาในการใช้งาน
ประเด็นหลักที่ต้องระวังก็คือสไตล์นี้จะขจัดเวทมนตร์/แผงหม้อน้ำออกไปจำนวนมาก (หรือซ่อนมันไว้อยู่แล้ว) แทนที่จะกำหนดตัวเฝ้าดูและวิธีการภายใต้วัตถุที่ซ้อนกันแล้วใช้ this
เพื่อหมายถึงวัตถุภายนอก (ซึ่งเดินทางโดยตัวตรวจสอบประเภทของ TypeScript อย่างถูกต้อง) วิธีการทั้งหมดจะถูกกำหนดไว้บนวัตถุที่ this
ถูกผูกไว้ มันทำให้ทุกอย่างเข้าใจและปฏิบัติตามได้ง่ายขึ้นเล็กน้อย ทำให้สิ่งต่าง ๆ ใกล้เคียงกับการทำงานของ JavaScript มากขึ้นเล็กน้อย
คุณจะพบตัวอย่างแบบเต็มได้ใน vue-ts-sandbox repo ของฉัน
โปรดทราบว่าแม้ว่าคุณจะไม่สนใจ TypeScript แต่คุณสามารถใช้มัณฑนากรเหล่านี้กับ Babel ได้
มันคุ้มค่าไหม?
อย่างที่คุณเห็น มันยุ่งยากมากในการทำงาน แม้ว่าในปัจจุบัน เมื่อมองย้อนกลับไปด้วยประโยชน์ของความรู้สะสมที่บันทึกไว้แล้ว ก็ยังต้องใช้เวลาสักระยะในการตั้งค่าต่างๆ คำถามก็คือว่ามันคุ้มค่าหรือไม่
ดังที่ฉันได้กล่าวไว้ในส่วน ทำไมต้องพิมพ์สคริปต์ มันเป็นสิ่งที่คุณต้องทำด้วยตัวเอง
ฉันเชื่อว่าความยุ่งยากของคำอธิบายประกอบประเภทและการกำหนดค่าบิวด์นั้นคุ้มค่าอย่างยิ่งเมื่อตัวตรวจสอบประเภทช่วยให้คุณรู้ว่าคุณได้ส่งอาร์กิวเมนต์ที่ไม่ถูกต้อง หรือลืมกำหนดบางสิ่งให้กับคุณสมบัติ หรือประเภทการส่งคืนของฟังก์ชันบางอย่างไม่เป็นเช่นนั้น สิ่งที่คุณคิดว่ามันจะเป็น คุณได้รับความคิด การประกาศอินเทอร์เฟซอย่างชัดเจนยังช่วยให้ฉันเข้าใจฐานโค้ดดีขึ้นอีกเล็กน้อย และทำให้ฉันช้าลงมากพอที่จะหลีกเลี่ยงข้อผิดพลาดที่เร่งรีบ
ตอนนี้ต้องใช้ความพยายามพิเศษเล็กน้อยเพื่อไปให้ถึงจุดนั้น แต่ลองคิดดู: การทดสอบหน่วยต้องใช้ความพยายามพิเศษเล็กน้อย (มากกว่านี้มาก!) และไม่มีใครจะโต้แย้งว่าการทดสอบหน่วยนั้นไม่คุ้มค่า ในบรรทัดเดียวกัน นี่เป็นเพียงอีกเลเยอร์หนึ่งที่มีส่วนช่วยในเรื่องคุณภาพของโค้ด นั่นคือวิธีที่ฉันมองมันต่อไป