RE: الألم والدموع في Svelte 3

بدلا من المقدمة


هذا المنشور هو استجابة لمقال الأمس "الألم والدموع في Svelte 3" وظهر نتيجة لتعليق "سمين" للغاية على المقال الأصلي ، والذي قررت تصميمه كنشرة. أدناه ، سأستخدم كلمة المؤلف للإشارة إلى مؤلف المقال الأصلي ، واسمحوا لي أن أقدم بعض التوضيحات في جميع النقاط. دعنا نذهب!



من هو Svelte؟


عندما رأيت عنوان المقال الأصلي ، كنت في البداية سعيدًا جدًا. أعتقد الآن ، أنني سأقرأ بعض الانتقادات العميقة والبناءة. والأهم من ذلك ، الحالات المثيرة للاهتمام مع المزالق ليست من "خبراء الأريكة" ، ولكن من الرجال "الذين يستطيعون". بعد القراءة ، تقلص الحماس ، ولكن بفضل vds64_max الكثير لهذه المقالة.

على الرغم من حقيقة أنه لم ينجح كل شيء ، أعتقد أنني بحاجة إلى المزيد من المقالات التي تصف المشكلات الحقيقية وحلولها في Svelte. على الأقل أنه لم يتخلف عن المزيد من الرفاق البارزين ، مثل React أو Vue. بعد كل شيء ، في النهاية ، قد يشعر القراء بأن Svelte مثالية للغاية ، وهذا بالتأكيد ليس هو الحال.

البرنامج التعليمي


لم أفهم ما كان يفكر فيه المؤلف في هذا الجزء. عملت البرنامج التعليمي ويعمل كبيرة. أفترض أن المؤلف فقط كان يعرفه بشكل سطحي فقط بسبب المواعيد النهائية لمشروعه ولم يستطع فهم مبدأ العمل. كانت هناك بالفعل حالات لم يدرك فيها الأشخاص على الفور معنى البرنامج التعليمي خطوة بخطوة ، وعندما تحتاج إلى تنفيذ المثال ، عليك القيام ببعض الإجراءات. جربه بنفسك!

عدة واجهة المستخدم والأساليب



كان العثور على طقم واجهة مستخدم لـ Svelte بمثابة ألم منفصل لنا جميعًا. أردت أن أصرخ: "على الأقل مادة ، Bootstrap ... على الأقل شيء ...".

أولاً ، بعيدًا عن جميع المشاريع ، من حيث المبدأ ، يمكن استخدام حيتان واجهة المستخدم. ثانياً ، لا تعمل جميع مجموعات واجهة المستخدم لأطر العمل الأخرى بشكل جيد.

تبدأ المشاكل الرئيسية عندما يكون للمشروع تصميم مشوش ومخصص للغاية ، وعادة ما يكون للحيتان وسائل محدودة للتخصيص. إذا كنا نتحدث عن لوحة المشرف ، فأنا أوافق على أن وجود مجموعة من أدوات واجهة المستخدم مفيد ، لكن ليس كل شخص يكتب لوحة المشرف ، ولن يكون الربح من Svelte for backoffice ملحوظًا.

يمكن العثور على الرابط أيضًا مع الحيتان الأخرى لواجهة المستخدم الخاصة بـ Svelte.

نظرًا لحقيقة أن Svelte يعمل مع DOM "بشكل مختلف" في MaterialUI ، فقد بدأوا في الخروج بكل أنواع الأشياء السيئة المتعلقة بكيفية عرض مكونات واجهة المستخدم التي تمت إضافتها عبر js إلى dom. على سبيل المثال ، يتم عرض سبينر بسيط كل مرة:

لم أفهم ما تعنيه بداية الجملة وكيف يعمل Svelte بالضبط "بطريقة مختلفة" مع DOM ، ولكن بشكل عام ، تبدو الرسالة كاملة ، على الأقل ، غير جدية. إذا حاولت دمج ليب طرف ثالث يعمل مع DOM في أي من الأطر (React / Vue / Angular / Ember) التي تتحكم في DOM ، فستحصل على نفس الأسئلة بالضبط. هناك على الفور شعور بأن المؤلف لم يفعل هذا أبدًا.

علاوة على ذلك ، لدى Svelte آلية رائعة تسمى إجراءات ، يتم من خلالها تقليل التكامل مع أي طرف ثالث DOM إلى كتابة وظيفة صغيرة. يبدو أن المؤلف لم يقرأ قفص الاتهام حتى هذه اللحظة. حسنا ، هذا يحدث.

على سبيل المثال ، تطبيق MDCSlider في دقيقتين: REPL


قل لي ، من فضلك ، أين هو أسهل بكثير؟

أسلوب


مع الأنماط ، يكون كل شيء واضحًا للغاية ، فنحن نوفر كل الأنماط كما في Vue تكتب النمط وكل شيء على ما يرام ، ثم تكتب أحد مكونات واجهة المستخدم (بما أنك لا تملك UIKit) والتي يجب أن تأخذ معلمات الدعائم ، على سبيل المثال العرض والارتفاع ، وتفعل ذلك بشكل منطقي مثل هذا:
...
و ... لا ، في النمط لا يمكنك إدراج متغيرات.

بقدر ما أعرف ، في Vue ، لا يمكن استخدام الحالة داخل أنماط المكونات أيضًا ، وفي React لا يوجد أي عمل مع أنماط خارج المربع على الإطلاق.

على الرغم من أنني أستطيع أن أفهم الرغبة في استخدام الديناميكيات في الأنماط ، إلا أن هناك عدة أسباب لعدم القيام بذلك:

  • بمجرد ظهور جزء من حالة المكون في الأنماط ، يجب تكرار هذه الأنماط لكل مثيل للمكون. قدم على الفور قائمة من 1000 عنصر مع تصميم معقد. هل نحن في حاجة إليها؟
  • استخدام الديناميات في المغلق يسبب الكثير من عمليات إعادة الرسم غير الضرورية وغير فعال للغاية.

طرق بديلة لاستخدام الأنماط الديناميكية في Svelte:

  • تغيير الفئات باستخدام توجيه الفصل الدراسي:
  • باستخدام الأنماط المضمنة مع سمة النمط
  • استخدام خصائص css المخصصة (المتغيرات)
  • استخدام حلول css-in-js مثل Emotion (هذه المقالة )

ومنذ ذكر Vue ، دعونا نقارن استخدام الأنماط المضمّنة الديناميكية:

<button v-on:click="fontSize++">Increase font size</button> <button v-on:click="fontSize--">Decrease font size</button> <p v-bind:style="{ fontSize: fontSize + 'px' }">Font size is: {{ fontSize }}</p> 

 <button on:click={e => fontSize++}>Increase font size</button> <button on:click={e => fontSize--}>Decrease font size</button> <p style="font-size: {fontSize + 'px'}">Font size is: {fontSize}</p> 

REPL

بشكل عام ، لا أرى أي اختلافات خاصة ، لكن لسبب ما يعتقد المؤلف أن كل شيء جيد في Vue ، ولكن ليس في Svelte. هذا غريب.

بالمناسبة ، بمساعدة التصريحات التفاعلية ، من السهل جدًا جمع كل الأنماط الديناميكية في مكان واحد:

 <div {style}>....</div> <script> let fontSize = 10; let color = 'red'; let width = 50; $: style = ` font-size: ${fontSize}px; color: ${color}; width: ${width}px; `; </script> 

عادةً ما يكون هذا كافيًا لـ 99٪ من الحالات ، ويتم حل الباقي باستخدام سمات و / أو خصائص css مخصصة .

التوجيه وأجهزة التوجيه


بشكل عام ، Svelte هو إطار عمل لواجهة مستخدم وهو غير ملائم لجهاز التوجيه. علاوة على ذلك ، فإن Svelte api الخارجي يجعل من السهل دمج أي جهاز توجيه مستقل في بضع دقائق وسطور من التعليمات البرمجية. على سبيل المثال ، page.js :

 import page from 'page'; import App from './App.svelte'; const app = new App({ target: document.body }); page('/posts', ctx => { //     dynamic import & code-splitting app.$set({ ctx, page: import('./Posts.svelte') }); }); page('/', ctx => { app.$set({ ctx, page: import('./Home.svelte') }); }); page.start(); export default app; 

 <nav> <a href="/">Home</a> <a href="/posts">Posts</a> </nav> <main> {#await page} <p>Loading...</p> {:then comp} <svelte:component this={comp.default || comp} {...ctx} /> {/await} </main> <script> export let page = null, ctx = null; </script> 

هل هو صعب؟ واجه المؤلف فقط مشاكل مع تطبيق معين ، وجهاز توجيه معين. والذي ، بالإضافة إلى ذلك ، بعبارة ملطفة ، ليس أفضل ما هو متاح لـ Svelte ، لأنه ينسخ جهاز React Router بكل مشاكله. يمكنك العثور على العديد من أجهزة التوجيه الأخرى هنا .

أخطاء


على عكس React ، التي ببساطة لن تسمح لك بإنشاء حزمة وسوف تصرخ بشدة حول خطأ ما ، سوف تقوم Svelte بجمع كل شيء مع وجود خطأ. في الوقت نفسه ، إذا نسيت شيئًا ما ، وقمت بتثبيت أو تثبيت npm ، فسيكون كل شيء على ما يرام وسيظهر فقط شاشة بيضاء (بالمناسبة ، كان هذا هو الحال في الإصدارات الأولى من React).

الرد لا يجمع أي شيء بالنسبة لك. جامع يجمع. في هذه الحالة ، أجد أن المؤلف قد عمل مع Rollup وعلى الأرجح فعل ذلك للمرة الأولى. يبدو لي أنه من المنطقي إما أن تدرس الأداة التي ستستخدمها أو لا تستخدمها. سأضيف من نفسي أن ما يكتبه المؤلف لا يتم ملاحظته في Svelte. على الأقل لا تنشأ بعض المشكلات أكثر من الأطر الأخرى. على الأرجح ، بالنسبة إلى الأطر الأخرى ، قام المؤلف بالفعل بإعداد كل شيء وعمله ، ولكنه كان هنا كسول جدًا جدًا في القيام بذلك.

هناك افتراض بأن المؤلف يعني أيضًا العمل مع الدعائم ، والذي يتم تنفيذه في Svelte من خلال الصادرات من المكون ، ولكن حتى هنا سيتم دائمًا عرض تحذير إذا حاولت رمي ​​الدعائم التي لم يحددها المكون:


Svelte فقط يحتاج اصطلاح التسمية


سوف تواجه هذه المشكلة في كثير من الأحيان - مع عدم وجود اصطلاح التسمية.

أحببت هذه العبارة حقًا ، لأنه في جوهرها يمكن استخدامها لأي لغة / مشروع / مكتبة / لغة برمجة. الماكرة هنا هي أنه بنفس الطريقة ستواجه هذا في كل مكان. على سبيل المثال ، في نفس الرد:

 class MyComponent extends React.Component { constructor(props) { super(props); this.dialog = null; this.loading = false; this.pins = []; this.stitch = null; } render() { return <dialog ref={el=> this.dialog = el} class="mdl-dialog» />; } } 

بشكل عام ، كل شيء هو نفسه ، وسوف تحتاج إلى "فهم" بطريقة أو بأخرى ما هو refk على العنصر ، وما هو الكائن للعمل مع الخلفية أو علامة التنزيل. يبدو أنه إذا كان لديك فريق لم يجتمع بالأمس ، فيجب حل كل هذه المشكلات منذ فترة طويلة.

بشكل عام ، بالطبع ، إذا لم يكن لدى مشروعك وفريقك اصطلاح تسمية ، فلن يساعدك Svelte. بعض الأشياء التي أستخدمها في مشاريعي:

 <!--  ,      --> <Modal {open}> <!--      --> <!--  ,     ,      --> <form on:submit|preventDefault={save}> <!--  ,   --> <input bind:value={firstName} placeholder="First name"> <input bind:value={lastName} placeholder="Last name"> <input bind:value={birthDay} use:asDatepicker placeholder="Birthday"> <button bind:this={btnEl}>Save</button> </form> </Modal> <button on:click={e => open = true}>Open</button> <!--   --> <script> //     //  -  ,     import Modal from '~/components/Modal'; //     `as`,   `use:as<something>` import asDatepicker from '~/actions/datepicker'; //    -  observerable,    cycle/rx import user$ from '~/stores/user'; import { saveUser } from '/api'; //     let firstName = '', lastName = '', birthDay = ''; let open = false; let btnEl; //           let refs = {}; //       async function save() { const patch = { firstName, lastName, birthDay }; await saveUser(patch); $user$ = { ...$user$, ...patch }; } //          export { open, save }; </script> <!--   --> <style> /* ... */ </style> 

بالإضافة إلى ذلك ، عادة ما تحتوي مكوناتي على "ميزانية" تبلغ 200 سطر من الشفرة إلى جانب الأنماط. إذا كان أكثر من ذلك بقليل - وليس مخيفا. إذا كان حجمه أكبر بكثير ، فأنا أقوم بإنشاء مجلد للمكون وأبدأ بنقل الأجزاء لفصل الملفات باستخدام svelte-preprocess ، بدءًا من الأنماط. في هذه الحالة ، يتم تكوين أداة التجميع بحيث لا تتغير الواردات.

ما الذي تغير أين ومن فعل ذلك؟




نتيجة لذلك ، تكتب المكونات بسرعة ، ولكن قد يكون من الصعب للغاية فهم ما كتبه صغار في "Venegret" بعد بضعة أيام عندما نسي بالفعل (حتى في بعض الأحيان اسمه). لهذا السبب ، سيكون من المستحيل فهم ما بداخله دون تنظيم واضح للرمز داخل المشروع أو الفريق.

أطروحة مضحك ، والأهم من ذلك ، تنطبق مرة أخرى بشكل عام على أي إطار ومشروع. علاوة على ذلك ، فإن تركيب الخطافات في React الحديثة ، المحبوب من قِبل مُبدع Vue ، حتى أنه قرر تنفيذه بشكل عاجل في Vue 3 ، سيكون له نفس التصادمات:

 import React, { useState, useCallback } from 'react'; function MyComponent() { const [ loading, setLoading ] = useState(false); const [ status, setStatus ] = useState(0); const [ pins, setPins ] = useState([]); const ReloadPins = useCallback(async () => { setLoading(true); setPins(await getAllPins()); setStatus(0); }); return (<div></div>); } 

مقابل

 <div></div> <script> let loading = false; let status = 0; let pins = []; async function ReloadPins() { loading = true; pins = await getAllPins(); status = 0; } </script> 

كما ترون ، كل شيء هو نفسه ، فقط 2 مرات أكثر من الشخبطة.

مجرد مزاح ، بالطبع ، لا يوجد شيء واضح. علاوة على ذلك ، فإن الدولة ليست واضحة أو أنها مجرد متغير إضافي. في React ، يتم تحديد ذلك من قِبل الحالة ، الأمر الذي يضفي الوضوح على الأقل بطريقة ما.

في الواقع ، لا يوجد أي معنى في "فهم" أي متغير لحالة المكون يتم استخدامه في القالب ، وهو أمر ضروري فقط لكي يعمل البرنامج النصي. في Svelte ، لا يوجد مثل هذا الفصل على الإطلاق ، عادةً ما تعيش المتغيرات حياة JS هناك - توجد في نطاقاتها الخاصة ، بعضها له نطاق مكون كامل ، والبعض الآخر يعيش داخل وظيفة واحدة أو كتلة أخرى من التعليمات البرمجية. لا شيء جديد أو غير متوقع. من المهم فهم شيء واحد فقط - يتم إعادة حساب DOM فقط عندما يتغير الجزء المرتبط بالحالة.

على سبيل المثال ، في نفس الرد ، إذا كنت تفعل:

 this.setState({ foo: 1 }) 

وعلى الرغم من عدم استخدام foo في القالب ، فلن تتمكن آلية VDOM من فهم هذا بأي شكل من الأشكال وستنتج rerender / توفيق. هل تعلم عن ذلك؟ لذلك ، ربما يكون من المهم في React فهم ما يتم استخدامه في القوالب وما هو غير ذلك. في Svelte ، نحن أحرار من هذا الاضطراب.

ونتيجة لذلك ، لا يمكنني هنا أن أكرر للمؤلف فقط - إذا لم يكن لدى مشروعك وفريقك منظمة واضحة ، فستواجه مشكلات مع أي أداة ، في أي مشروع. في الواقع ، مثال على مشروع المؤلف هو دليل مباشر على ذلك.

ربط غرزة


بالطبع ، هذا يرجع إلى المجمع. المؤلف لا ينبغي أن تكون تافهة جدا حول الأداة الجديدة. بشكل افتراضي ، يأتي Svelte مزودًا بميزة Rollup ، التي تدعم ميزات أقل بكثير من ميزات Webpack ، ولكنها تجمع حزم أكثر دقة وأكثر. يمكن تخصيص أي وظائف إضافية باستخدام المكونات الإضافية. إذا كنت لا ترغب في أخذ حمام بخار ، فيمكنك أخذ القالب الرسمي لـ Webpack ، أو أي قالب آخر من المجتمع ، نظرًا لوجود الكثير منهم.

لماذا تحتاج Svelte؟


في هذه الفقرة ، سأكون أكثر إيجازًا - بالنسبة إلى أي مشاريع جديدة تكون React أو Vue كافية لها. لا معنى للمقارنة مع الزاوي أو Ember ، لأن هذه هي أطر من نطاق مختلف.

بناءً على الأخير ، لا أفهم حقًا سبب قيام مشرفي Svelte بتقديم دعم TypeScript؟ نحن نحب Svelte لمجرد "إطلاق النار على الساقين" و TypeScript في رأيي مثل مسارات جميع التضاريس لسيارة Svelte الرياضية. كما تعلمون ، بعد أن عملت مع Svelte ، أدركت مدى تغير JS في السنوات الأخيرة ، وأنه لم يعد JS.

يوفر Svelte الفرصة للعمل في نفس JS القديم والمصباح ، دون PropTypes ، Flow و TypeScript.

لا أستطيع أن أتعارض مع هذا البيان. في الواقع ، ليست هناك حاجة حقا TS في Svelte. على الرغم من وجود دعم جزئي له بمساعدة من المعالجات المسبقة (بدون قوالب taypechek) ، إلا أنه بشكل عام يكون أكثر من ملحق لا يمكنك بدونه كتابة مكونات جيدة.

لماذا لا يستحق استخدام Svelte؟


  1. إذا كان مشروعك مكتوبًا بالفعل على إطار آخر ويعمل جيدًا بشكل معقول. لا حاجة لتشغيل وإعادة كتابته.
  2. حتى في النقطة 1 ، هناك فرصة سانحة - يمكنك إعادة كتابة بعض المكونات "الثقيلة" على Svelte. سيصبح المشروع أسهل ، وستعمل المكونات بشكل أسرع. ليس عليك إعادة كتابة كل شيء.
  3. إذا كنت تكتب مؤسسة ما ، فمن المحتمل أن يكون Angular أو Ember هو الخيار الأفضل. Svelte ، تمامًا مثل React و Vue ، ليس دائمًا خيارًا جيدًا لهذا الغرض.
  4. إذا كنت بحاجة إلى دعم Typescript من الدرجة الأولى .
  5. إذا قمت بتطوير حلول قياسية حصريًا وكنت معتادًا على تجميع المشاريع من مكونات جاهزة.
  6. لا يزال ضبط أضعف من الرفاق أكثر خبرة. إذا كان هذا أمرًا بالغ الأهمية ، فإن الأمر يستحق الانتظار ، أو الانضمام إلى مجتمعنا وتطوير التوليف معًا.)))

***

بشكل عام ، لسوء الحظ ، تستند معظم الاستنتاجات الواردة في المقالة الأصلية إلى افتراضات خاطئة وقراء مضللون. نظرًا لأنني لم أر المؤلف في مجتمع Svelte الناطق باللغة الروسية في Telegramsveltejs (1K + المشاركين) ، استنتج أن المؤلف وفريقه لم يبذلوا ما يكفي من الجهد لإتقان أداة جديدة غير معروفة. أعتقد أنه إذا تمت إضافة اللاعبين إلى غرفة الدردشة ، فربما كان من الممكن تجنب معظم المشكلات. في الوقت الحالي ، يبدو أن الرجال توصلوا إلى استنتاجات متسرعة إلى حد ما ، ولكن هذه هي أمورهم الشخصية.

Source: https://habr.com/ru/post/ar469411/


All Articles