Si vous êtes un ingénieur front-end, vous avez probablement été dans une situation où vous avez dû commencer à implémenter une fonctionnalité avant l'API qui sert la partie back-end de celle-ci. fonctionnalité existe. Les ingénieurs se tournent souvent vers la simulation pour permettre le développement parallèle (ce qui signifie que les parties front-end et back-end de la fonctionnalité sont développées en parallèle).
Les moqueries peuvent cependant présenter certains inconvénients. La première et la plus évidente est que les simulations peuvent s’écarter de la mise en œuvre réelle, ce qui les rend peu fiables. Un deuxième problème est que les moqueries peuvent souvent être verbeuses ; Avec les simulations qui contiennent beaucoup de données, il peut être difficile de savoir de quoi se moque réellement une certaine réponse simulée.
Les données ci-dessous sont un exemple de certaines données que vous pourriez trouver dans une base de code :
type Order = { orderId: string; customerInfo: CustomerInfo; // omitted these types for brevity orderDate: string; items: OrderItem[]; paymentInfo: PaymentInfo; subtotal: number; shippingCost: number; tax: number; totalAmount: number; status: 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled'; trackingNumber: string | null; }; const mockOrders: Order[] = [ { orderId: "ORD-2024-001", customerInfo: { id: "CUST-1234", name: "Alice Johnson", email: "alice.j@email.com", shippingAddress: { street: "123 Pine Street", city: "Portland", state: "OR", zipCode: "97201", country: "USA" } }, orderDate: "2024-03-15T14:30:00Z", items: [ { productId: "PROD-789", name: "Organic Cotton T-Shirt", quantity: 2, pricePerUnit: 29.99, color: "Navy", size: "M" }, { productId: "PROD-456", name: "Recycled Canvas Tote", quantity: 1, pricePerUnit: 35.00, color: "Natural" } ], paymentInfo: { method: "credit_card", status: "completed", transactionId: "TXN-88776655" }, subtotal: 94.98, shippingCost: 5.99, tax: 9.50, totalAmount: 110.47, status: "shipped", trackingNumber: "1Z999AA1234567890" }, // Imagine more objects here, with various values changed... ];
Les données avec lesquelles je travaille quotidiennement ressemblent beaucoup à ceci. Des tableaux de commandes ou une sorte d'informations axées sur le client, comportant des valeurs imbriquées qui aident à remplir des tableaux, des fenêtres contextuelles et des cartes détaillées avec toutes sortes d'informations.
En tant qu'ingénieur chargé de maintenir des applications qui s'appuient fortement sur de telles simulations, vous pourriez vous demander « quel est cet objet particulier dans la réponse moqueuse ? ». Je me suis souvent retrouvé à parcourir des centaines d'exemples comme celui ci-dessus, sans être sûr du but de chaque objet.
Au fur et à mesure que je suis devenu plus sûr de moi en tant qu'ingénieur, je me suis chargé de résoudre le problème ci-dessus ; Et si chaque maquette pouvait afficher plus facilement son objectif ? Et si un ingénieur n’avait qu’à écrire les lignes dont il a l’intention de se moquer ?
En jouant avec du code et une bibliothèque appelée Zod, j'ai trouvé la méthode suivante appelée parse, qui tente de valider les données entrantes par rapport à un type connu :
const stringSchema = z.string(); stringSchema.parse("fish"); // => returns "fish" stringSchema.parse(12); // throws error
C'était un moment d'éclairage ; Ce petit exemple dans la documentation de Zod était exactement ce que je cherchais ! Si la méthode d'analyse pouvait accepter une valeur et la renvoyer, alors si je transmettais une valeur, je la récupérerais. Je savais aussi déjà que je pouvais définir des valeurs par défaut pour un schéma Zod. Et si passer un objet vide renvoyait un objet plein, avec ses valeurs ? Et voilà, c’est le cas ; Je pourrais définir des valeurs par défaut sur un schéma Zod et renvoyer les valeurs par défaut :
const UserSchema = z.object({ id: z.string().default('1'), name: z.string().default('Craig R Broughton'), settings: z.object({ theme: z.enum(['light', 'dark']), notifications: z.boolean() }).default({ theme: 'dark', notifications: true, }) }); const user = UserSchema.parse({}) // returns a full user object
Maintenant, j'avais un moyen de générer des objets, mais ce n'était toujours pas tout à fait ce que je cherchais. Ce que je voulais vraiment, c'était un moyen de seulement écrire les lignes exactes dont je me « moquais ». Une solution simple pourrait ressembler à :
const UserSchema = z.object({ id: z.string().default('1'), name: z.string().default('Craig R Broughton'), settings: z.object({ theme: z.enum(['light', 'dark']), notifications: z.boolean() }).default({ theme: 'dark', notifications: true, }) }); const user = UserSchema.parse({}) const overridenUser = {...user, ...{ name: "My new name", settings: {}, // I would need to write every key:value for settings :( } satisfies Partial<z.infer userschema>>} // overrides the base object </z.infer>
Cependant, cela a ses propres défauts ; Que se passe-t-il si la valeur que je souhaite remplacer est elle-même un objet ou un tableau ? Je devrais alors taper manuellement chaque ligne qui était auparavant requise pour que cette fonctionnalité continue de fonctionner et soit moquée comme prévu, ce qui va à l'encontre de l'objectif de notre solution de travail en cours.
Pendant longtemps, c'est tout ce que j'en étais, jusqu'à très récemment, lorsque j'ai eu une autre tentative d'améliorer ce qui précède. La première étape consistait à définir « l'API » ; Comment voulais-je que mes utilisateurs interagissent avec cette fonctionnalité ?
type Order = { orderId: string; customerInfo: CustomerInfo; // omitted these types for brevity orderDate: string; items: OrderItem[]; paymentInfo: PaymentInfo; subtotal: number; shippingCost: number; tax: number; totalAmount: number; status: 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled'; trackingNumber: string | null; }; const mockOrders: Order[] = [ { orderId: "ORD-2024-001", customerInfo: { id: "CUST-1234", name: "Alice Johnson", email: "alice.j@email.com", shippingAddress: { street: "123 Pine Street", city: "Portland", state: "OR", zipCode: "97201", country: "USA" } }, orderDate: "2024-03-15T14:30:00Z", items: [ { productId: "PROD-789", name: "Organic Cotton T-Shirt", quantity: 2, pricePerUnit: 29.99, color: "Navy", size: "M" }, { productId: "PROD-456", name: "Recycled Canvas Tote", quantity: 1, pricePerUnit: 35.00, color: "Natural" } ], paymentInfo: { method: "credit_card", status: "completed", transactionId: "TXN-88776655" }, subtotal: 94.98, shippingCost: 5.99, tax: 9.50, totalAmount: 110.47, status: "shipped", trackingNumber: "1Z999AA1234567890" }, // Imagine more objects here, with various values changed... ];
L'API ci-dessus permettrait à l'utilisateur de spécifier un schéma de son choix, puis de fournir les remplacements appropriés et de renvoyer un objet utilisateur ! Bien sûr, nous voudrions tenir compte correctement des tableaux ainsi que d'un seul objet. À cette fin, une simple vérification de type par rapport au type de remplacement entrant s'est avérée suffisante :
const stringSchema = z.string(); stringSchema.parse("fish"); // => returns "fish" stringSchema.parse(12); // throws error
Ce qui précède est effectivement le même code qu'avant, mais il encapsule désormais l'analyse en interne afin que les utilisateurs n'aient pas à le faire manuellement ou à connaître des informations détaillées sur la méthode d'analyse de Zods. Comme vous l'avez peut-être deviné en lisant l'instruction if/else incluse, nous avons également résolu la préservation des objets et des tableaux imbriqués grâce à l'utilisation d'une fonction de création récursive qui analyse chaque valeur et renvoie ses valeurs par défaut spécifiées dans le schéma Zod.
Ce qui précède est assez compliqué à comprendre, mais le résultat est qu'un utilisateur peut faire ce qui suit :
const UserSchema = z.object({ id: z.string().default('1'), name: z.string().default('Craig R Broughton'), settings: z.object({ theme: z.enum(['light', 'dark']), notifications: z.boolean() }).default({ theme: 'dark', notifications: true, }) }); const user = UserSchema.parse({}) // returns a full user object
En fournissant l'option de configuration verifyNestedDefaults au constructeur, un utilisateur peut conserver les paires clé-valeur dans un objet ou un tableau imbriqué ! Cela résout le problème d'un utilisateur remplaçant une clé qui n'est pas un type primitif comme une chaîne, mais plutôt un type plus complexe et conserve toutes les valeurs moins celles que nous choisissons de remplacer.
Cela a déjà été une sacrée lecture, alors terminons par le résultat de tout notre travail acharné. Revenons sur cette première simulation et comment nous pourrions l'écrire avec zodObjectBuilder. Définissons d’abord nos types et nos valeurs par défaut, et passons le schéma résultant dans le zodObjectBuilder :
const UserSchema = z.object({ id: z.string().default('1'), name: z.string().default('Craig R Broughton'), settings: z.object({ theme: z.enum(['light', 'dark']), notifications: z.boolean() }).default({ theme: 'dark', notifications: true, }) }); const user = UserSchema.parse({}) const overridenUser = {...user, ...{ name: "My new name", settings: {}, // I would need to write every key:value for settings :( } satisfies Partial<z.infer userschema>>} // overrides the base object </z.infer>
L'implémentation ci-dessus renverra un seul objet en utilisant toutes les valeurs par défaut ! Mais nous pouvons faire mieux que cela, nous pouvons maintenant (avec l'aide de quelques définitions de surcharge et d'une analyse interne) créer des tableaux d'objets, parfaits pour le cas d'utilisation des réponses API moqueuses :
const UserSchema = z.object({ id: z.string().default('1'), name: z.string().default('Craig R Broughton'), settings: z.object({ theme: z.enum(['light', 'dark']), notifications: z.boolean() }).default({ theme: 'dark', notifications: true, }) }); const user = zodObjectBuilder({ schema: UserSchema, overrides: { name: 'My new name', settings: { theme: 'dark' } } // setting is missing the notifications theme :( }); // returns a full user object with the overrides
Ce qui précède génère un tableau de commandes avec les valeurs par défaut complètes, avec des statuts de livraison remplacés ! Espérons que cela démontre comment la fonction zodObjectBuilder peut minimiser l'effort requis pour créer une nouvelle simulation basée sur un schéma de type sécurisé fiable.
Avec cette petite démonstration, nous avons atteint la fin de mon premier article :) J'espère que vous avez apprécié la lecture de ce voyage d'exploration pour améliorer la moquerie. zodObjectBuilder est toujours en cours de construction, mais il répond bien à mes besoins pour minimiser les objets simulés. Si vous souhaitez jouer avec la version actuelle, vous pouvez la trouver sur https://www.npmjs.com/package/@crbroughton/ts-utils qui inclut la fonction.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Les types de données de base JavaScript sont cohérents dans les navigateurs et Node.js, mais sont gérés différemment des types supplémentaires. 1) L'objet global est la fenêtre du navigateur et global dans Node.js. 2) Objet tampon unique de Node.js, utilisé pour traiter les données binaires. 3) Il existe également des différences dans les performances et le traitement du temps, et le code doit être ajusté en fonction de l'environnement.

JavascriptUsestwotypesofComments: unique (//) et multi-ligne (//). 1) use // forquicknotesorsings-lineexplanations.2) use // forlongErexPlanationsorcommentingoutblocksofcode.commentsShouldExplatethe'why ', notthewat', et bplacedabovovereLantCodeForCaReric

La principale différence entre Python et JavaScript est le système de type et les scénarios d'application. 1. Python utilise des types dynamiques, adaptés à l'informatique scientifique et à l'analyse des données. 2. JavaScript adopte des types faibles et est largement utilisé pour le développement frontal et complet. Les deux ont leurs propres avantages dans la programmation asynchrone et l'optimisation des performances, et doivent être décidées en fonction des exigences du projet lors du choix.

Que ce soit pour choisir Python ou JavaScript dépend du type de projet: 1) Choisissez Python pour les tâches de science et d'automatisation des données; 2) Choisissez JavaScript pour le développement frontal et complet. Python est favorisé pour sa bibliothèque puissante dans le traitement et l'automatisation des données, tandis que JavaScript est indispensable pour ses avantages dans l'interaction Web et le développement complet.

Python et JavaScript ont chacun leurs propres avantages, et le choix dépend des besoins du projet et des préférences personnelles. 1. Python est facile à apprendre, avec une syntaxe concise, adaptée à la science des données et au développement back-end, mais a une vitesse d'exécution lente. 2. JavaScript est partout dans le développement frontal et possède de fortes capacités de programmation asynchrones. Node.js le rend adapté au développement complet, mais la syntaxe peut être complexe et sujet aux erreurs.

Javascriptisnotbuiltoncorc; il est en interprétéLanguageThatrunSoninesoftenwritteninc .1) javascriptwasdesignedasalightweight, interprété de LanguageForwebbrowsers.2) EnginesevolvedFromSimpleInterpreterstoJitCompilers, typicalinc, impropringperformance.

JavaScript peut être utilisé pour le développement frontal et back-end. L'endouage frontal améliore l'expérience utilisateur via les opérations DOM, et le back-end gère les tâches du serveur via Node.js. 1. Exemple frontal: modifiez le contenu du texte de la page Web. 2. Exemple backend: Créez un serveur Node.js.

Le choix de Python ou JavaScript doit être basé sur le développement de carrière, la courbe d'apprentissage et l'écosystème: 1) le développement de carrière: Python convient à la science des données et au développement de back-end, tandis que JavaScript convient au développement frontal et complet. 2) Courbe d'apprentissage: la syntaxe Python est concise et adaptée aux débutants; La syntaxe JavaScript est flexible. 3) Ecosystème: Python possède de riches bibliothèques informatiques scientifiques, et JavaScript a un puissant cadre frontal.


Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

Version Mac de WebStorm
Outils de développement JavaScript utiles

mPDF
mPDF est une bibliothèque PHP qui peut générer des fichiers PDF à partir de HTML encodé en UTF-8. L'auteur original, Ian Back, a écrit mPDF pour générer des fichiers PDF « à la volée » depuis son site Web et gérer différentes langues. Il est plus lent et produit des fichiers plus volumineux lors de l'utilisation de polices Unicode que les scripts originaux comme HTML2FPDF, mais prend en charge les styles CSS, etc. et présente de nombreuses améliorations. Prend en charge presque toutes les langues, y compris RTL (arabe et hébreu) et CJK (chinois, japonais et coréen). Prend en charge les éléments imbriqués au niveau du bloc (tels que P, DIV),

MantisBT
Mantis est un outil Web de suivi des défauts facile à déployer, conçu pour faciliter le suivi des défauts des produits. Cela nécessite PHP, MySQL et un serveur Web. Découvrez nos services de démonstration et d'hébergement.

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

ZendStudio 13.5.1 Mac
Puissant environnement de développement intégré PHP
