RE: Douleur et larmes dans Svelte 3

Au lieu de l'avant-propos


Ce message est une réponse à l'article d'hier "Pain and Tears in Svelte 3" et est apparu à la suite d'un commentaire très "gras" sur l'article original, que j'ai décidé de concevoir comme un article. Ci-dessous, j'utiliserai le mot auteur pour faire référence à l'auteur de l'article original et me permettre d'apporter quelques clarifications sur tous les points. C'est parti!



Qui est Svelte?


Quand j'ai vu le titre de l'article original, au début j'étais très content. En ce moment, je pense, je vais lire quelques critiques profondes et constructives. Et le plus important, les cas intéressants avec des pièges ne sont pas des «experts du canapé», mais des gars «qui pourraient». Après la lecture, l'enthousiasme a diminué, mais merci beaucoup à vds64_max pour l'article.

Malgré le fait que tout n'a pas fonctionné, je pense que j'ai besoin de plus d'articles décrivant les vrais problèmes et leurs solutions dans Svelte. Au moins, il n'était pas en retard sur des camarades plus éminents, tels que React ou Vue. Après tout, à la fin, les lecteurs peuvent avoir le sentiment que Svelte est trop parfait, et ce n'est certainement pas le cas.

Tutoriel


Je n'ai pas compris ce que l'auteur avait en tête dans cette partie. Le tutoriel a fonctionné et fonctionne très bien. Je suppose que l'auteur ne l'a connu que superficiellement en raison des délais de son projet et n'a pas pu comprendre le principe du travail. Il y a déjà eu des cas où les gens n'ont pas immédiatement compris la signification du didacticiel pas à pas, alors que pour que l'exemple fonctionne, vous devez effectuer une action. Essayez-le vous-même!

Kit et styles d'interface utilisateur



Trouver un kit d'interface utilisateur pour Svelte était une douleur distincte pour nous tous. Je voulais m'exclamer: "Au moins Matériel, Bootstrap ... au moins quelque chose ...".

Premièrement, loin de tous les projets, en principe, les baleines à interface utilisateur sont applicables. Deuxièmement, tous les kits d'interface utilisateur pour d'autres cadres ne fonctionnent pas bien.

Les principaux problèmes commencent lorsque le projet a une conception très confuse et personnalisée, et les baleines ont généralement encore des moyens limités pour la personnalisation. Si nous parlons du panneau d'administration, je conviens qu'avoir un kit d'interface utilisateur est utile, mais tout le monde n'écrit pas le panneau d'administration, et le profit de Svelte pour le backoffice ne sera pas aussi perceptible.

Le lien peut également être trouvé avec d'autres baleines UI pour Svelte.

Du fait que Svelte fonctionne avec le DOM «d'une manière différente», MaterialUI a commencé à sortir toutes sortes de choses désagréables liées à la façon dont les composants d'interface utilisateur ajoutés via js à dom sont affichés. Par exemple, un simple spinner est affiché toutes les deux fois:

Je n'ai pas compris ce que signifie le début de la phrase et comment exactement «d'une manière différente» Svelte travaille avec le DOM, mais en général toute la thèse sonne, du moins, pas sérieusement. Si vous essayez d'intégrer une bibliothèque tierce qui fonctionne avec le DOM dans l'un des cadres (React / Vue / Angular / Ember) qui contrôlent le DOM, vous obtiendrez exactement les mêmes questions. Immédiatement, on a le sentiment que l'auteur n'a jamais fait cela.

De plus, Svelte dispose d'un merveilleux mécanisme appelé actions , grâce auquel l'intégration avec tout DOM tiers est réduite à l'écriture d'une petite fonction. Il semble que l'auteur n'ait pas lu le dock jusqu'à ce moment. Eh bien, ça arrive.

Par exemple, une implémentation de MDCSlider en 2 minutes: REPL


Dites-moi, s'il vous plaît, où est-ce beaucoup plus facile?

Stylisation


Avec les styles, tout est très clair, nous remplissons tous les styles comme dans Vue. Vous écrivez le style et tout va bien, puis vous écrivez un composant d'interface utilisateur (puisque vous n'avez pas UIKit) qui devrait prendre les paramètres d'accessoires, par exemple la largeur et la hauteur, et le faites logiquement comme ceci:
...
Et ... non, dans le style, vous ne pouvez pas insérer de variables.

Pour autant que je sache, dans Vue, l'état ne peut pas être utilisé à l'intérieur des styles de composants non plus, et dans React, il n'y a aucun travail avec les styles prêts à l'emploi.

Bien que je puisse comprendre le désir d'utiliser la dynamique dans les styles, mais il y a un certain nombre de raisons pour lesquelles cela ne devrait pas être fait:

  • Dès qu'une partie de l'état du composant apparaît dans les styles, ces styles doivent être dupliqués pour CHAQUE instance du composant. Présentez immédiatement une liste de 1000 articles au design complexe. En avons-nous besoin?
  • L'utilisation de la dynamique dans css provoque de nombreux redessins inutiles et est extrêmement inefficace.

Autres façons d'utiliser des styles dynamiques dans Svelte:

  • Modification des classes à l'aide de la directive class:
  • Utilisation de styles en ligne avec l'attribut style
  • Utilisation des propriétés personnalisées CSS (variables)
  • Utilisation de solutions css-in-js comme Emotion (cet article )

Et puisque Vue a été mentionné, comparons l'utilisation des styles dynamiques en ligne:

<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

En général, je ne vois aucune différence particulière, mais pour une raison quelconque, l'auteur pense que tout est bon dans Vue, mais pas dans Svelte. C'est étrange.

Soit dit en passant, à l'aide de déclarations réactives, il est assez pratique de rassembler tous les styles dynamiques en un seul endroit:

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

Habituellement, cela suffit pour 99% des cas, et le reste est résolu en utilisant des thèmes et / ou des propriétés personnalisées CSS .

Routage et routeurs


En général, Svelte est un cadre d'interface utilisateur et il est agnostique pour un routeur. De plus, l'API Svelte externe facilite l'intégration de n'importe quel routeur indépendant en quelques minutes et lignes de code. Par exemple, 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> 

C'est dur? L'auteur n'a rencontré que des problèmes avec une implémentation spécifique, un routeur spécifique. Ce qui, en plus, pour le moins, n'est pas le meilleur de Svelte, car il copie le React Router avec tous ses problèmes. Vous pouvez trouver de nombreux autres routeurs ici .

Erreurs


Contrairement à React, qui ne vous laissera tout simplement pas créer un bundle et criera fortement à propos d'une erreur, Svelte collectera parfaitement tout avec une erreur. En même temps, si vous avez oublié quelque chose, installez ou installez npm, tout ira bien et affichera simplement un écran blanc (Incidemment, c'était le cas dans les premières versions de React).

React ne collecte rien pour vous. Collectionneur collectionne. Dans ce cas, je pense que l'auteur a travaillé avec Rollup et l'a probablement fait pour la première fois. Il me semble qu'il est logique d'étudier l'outil que vous allez utiliser ou de ne pas l'utiliser. J'ajouterai de moi-même que ce sur quoi l'auteur écrit n'est pas observé dans Svelte. Certains problèmes au moins ne se posent pas plus souvent que dans d'autres cadres. Très probablement, pour d'autres cadres, l'auteur a déjà tout configuré et travaillé, mais ici, il était tout simplement trop paresseux pour le faire.

Il y a une supposition que l'auteur voulait aussi dire travailler avec des accessoires, ce qui dans Svelte est effectué par le biais d'exportations à partir du composant, mais même ici, un avertissement sera toujours affiché si vous essayez de lancer des accessoires non définis par le composant:


Svelte a juste besoin d'une convention de nommage


Vous rencontrerez ce problème assez souvent - en l'absence d'une convention de dénomination.

J'ai vraiment aimé cette phrase, car elle peut être utilisée pour n'importe quel projet / bibliothèque / langage de programmation. La ruse ici est que de la même manière, vous rencontrerez cela partout. Par exemple, dans le même React:

 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» />; } } 

En général, tout est pareil et vous devrez en quelque sorte "comprendre" ce qui est refk sur l'élément, et quel est l'objet pour travailler avec le backend ou le flag de téléchargement. Il semblerait que si vous avez une équipe qui ne s'est pas réunie hier, tous ces problèmes devraient être résolus depuis longtemps.

En général, bien sûr, si votre projet et votre équipe n'ont pas de convention de dénomination, Svelte ne vous aidera pas. Certaines choses que j'utilise dans mes projets:

 <!--  ,      --> <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> 

De plus, mes composants ont généralement un «budget» de 200 lignes de code avec les styles. Si un peu plus - pas effrayant. S'il est beaucoup plus grand, je crée un dossier pour le composant et commence à déplacer des pièces vers des fichiers séparés à l'aide de svelte-preprocess , en commençant par les styles. Dans ce cas, le collecteur est configuré pour que les importations ne changent pas.

Qu'est-ce qui a changé où et qui l'a fait?




En conséquence, vous écrivez des composants rapidement, mais il peut être très difficile de comprendre ce qu'un junior a écrit dans ce «Venegret» quelques jours plus tard alors qu'il avait déjà oublié (parfois même son nom). Pour cette raison, il sera impossible de comprendre ce qu'il y a à l'intérieur sans une organisation claire du code au sein du projet ou de l'équipe.

Une thèse amusante, et surtout, applicable à nouveau en général à n'importe quel cadre et projet. De plus, la syntaxe des hooks dans React moderne, si chère au créateur de Vue qu'il a même décidé de l'implémenter de toute urgence dans Vue 3, aura toutes les mêmes collisions:

 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>); } 

vs

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

Comme vous pouvez le voir, tout est pareil, seulement 2 fois plus de gribouillis.

Je plaisante, bien sûr, rien n'est clair. De plus, l'état n'est même pas clair ou n'est-ce qu'une variable auxiliaire. Dans React, cela est décidé par l'État, ce qui apporte au moins une certaine clarté.

En fait, il est inutile de «comprendre» quelle variable d'état de composant est utilisée dans le modèle, et laquelle n'est nécessaire que pour que le script fonctionne. Dans Svelte, il n'y a pas de séparation du tout, les variables y vivent généralement - elles existent dans leurs propres étendues, certaines ont une étendue de composants entière, d'autres vivent dans la même fonction ou un autre bloc de code. Rien de nouveau ou d'inattendu. Il est important de comprendre une seule chose: le DOM est recalculé uniquement lorsque la partie associée de l'état change.

Par exemple, dans le même React, si vous faites:

 this.setState({ foo: 1 }) 

et bien que foo ne soit PAS utilisé dans le modèle, le mécanisme VDOM ne pourra pas comprendre cela de quelque façon que ce soit et produira un nouveau rendu / réconciliation. Le saviez-vous? Par conséquent, il est probablement important dans React de comprendre ce qui est utilisé dans les modèles et ce qui ne l'est pas. Chez Svelte, nous sommes libérés de tels troubles.

En conséquence, je ne peux que faire écho à l'auteur - si votre projet et votre équipe n'ont pas une organisation claire, vous aurez des problèmes avec n'importe quel outil, sur n'importe quel projet. En fait, un exemple du projet de l’auteur en est une preuve directe.

Lier le point


Bien sûr, cela est dû au collectionneur. L'auteur ne devrait pas être aussi frivole au sujet du nouvel outil. Par défaut, Svelte est livré avec Rollup, qui prend en charge beaucoup moins de fonctionnalités que Webpack, mais il collecte des bundles plus optimisés et plus natifs. Toute fonctionnalité supplémentaire peut être personnalisée à l'aide de plugins. Si vous n'avez pas envie de prendre un bain de vapeur, vous pouvez prendre le modèle officiel pour Webpack , ou tout autre de la communauté , car il y en a beaucoup.

Pourquoi avez-vous besoin de Svelte?


Dans ce paragraphe, je serai plus bref - pour tout nouveau projet pour lequel React ou Vue suffit. Cela n'a aucun sens de comparer avec Angular ou Ember, car ce sont des cadres d'une échelle différente.

Sur la base de ce dernier, je ne comprends vraiment pas pourquoi les responsables de Svelte vont prendre en charge TypeScript? Nous aimons Svelte juste pour «tirer sur les jambes» et TypeScript, à mon avis, est comme des pistes tout-terrain pour la voiture de sport Svelte. Et vous savez, après avoir travaillé avec Svelte, j'ai réalisé à quel point JS a changé ces dernières années, et que ce n'est plus JS.

Svelte donne la possibilité de travailler dans le même JS ancien et lampe, sans PropTypes, Flow et TypeScript.

Je ne peux pas être en désaccord avec cette affirmation. En fait, TS n'est pas vraiment nécessaire dans Svelte. Bien qu'il soit partiellement pris en charge à l'aide de préprocesseurs (sans modèles taypechek), mais en général, il s'agit plus d'un appendice que sans lequel vous ne pouvez pas écrire de bons composants.

Pourquoi ne vaut-il pas la peine d'utiliser Svelte?


  1. Si votre projet est déjà écrit sur un autre framework et fonctionne assez bien. Pas besoin de l'exécuter et de le réécrire.
  2. Même au point 1, il y a une fenêtre d'opportunité - vous pouvez réécrire certains des composants "lourds" sur Svelte. Le projet deviendra plus facile et les composants fonctionneront plus rapidement. Vous n'avez pas besoin de tout réécrire.
  3. Si vous écrivez une entreprise, Angular ou Ember est probablement le meilleur choix. Svelte, tout comme React et Vue, n'est pas toujours un bon choix pour cela.
  4. Si vous avez besoin d'une prise en charge de TypeScript de première classe .
  5. Si vous développez exclusivement des solutions standard et avez l'habitude d'assembler des projets à partir de composants standard.
  6. Accord encore plus faible que ses camarades plus expérimentés. Si cela est essentiel, cela vaut la peine d'attendre, ou rejoignez notre communauté et développez le réglage ensemble.)))

***

En général, malheureusement, la plupart des conclusions de l'article original sont basées sur de fausses hypothèses et des lecteurs trompeurs. Étant donné que je n'ai pas vu l'auteur dans la communauté russophone de Svelte dans Telegram @sveltejs (1K + participants), je conclus que l'auteur et son équipe n'ont pas fait suffisamment d'efforts pour maîtriser un nouvel outil inconnu. Je pense que si les gars venaient d'ajouter à la salle de chat, la plupart des problèmes auraient pu être évités. Pour le moment, il semble que les gars aient tiré des conclusions hâtives, mais c'est leur affaire personnelle.

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


All Articles