


Style de programmation de développement JavaScript moderne Guide Idiomatic.js Version chinoise_javascript Compétences
Le style que vous choisissez pour votre projet doit répondre aux normes les plus élevées. Placez-le comme description dans votre projet et créez un lien vers ce document comme garantie de cohérence, de lisibilité et de maintenabilité du style de code.
1. Vierge
1. Ne mélangez jamais les espaces et les tabulations.
2. Démarrez un projet et avant d'écrire du code, choisissez l'indentation douce (espaces) ou la tabulation (comme méthode d'indentation) et utilisez-la comme ligne directrice la plus élevée.
a). Pour plus de lisibilité, je recommande toujours de concevoir des retraits de 2 lettres de largeur dans vos éditeurs — cela équivaut à deux espaces ou deux espaces au lieu d'une tabulation.
3. Si votre éditeur le prend en charge, veuillez toujours activer le paramètre « Afficher les caractères invisibles ». Les avantages sont :
a) Assurer la cohérence
b) Supprimer les espaces en fin de ligne
c) Supprimer les espaces sur les lignes vides
d). >
2. Embellir la grammaire
A. Parenthèses, accolades, sauts de ligne// Cela facilite la lisibilité
// 2.A.1.1
// Exemples de syntaxe merdique
while(condition) itération ;
for(var i=0;i //2.A.1.1
// Utiliser des espaces pour améliorer la lisibilité
// Déclaration
}
// Déclaration
}
}
// Meilleure approche :
var i,
longueur = 100;
}
// Ou...
var i = 0,
longueur = 100;
}
var prop ;
pour ( prop dans l'objet ) {
// Déclaration
}
// Déclaration
} else {
// Déclaration
}
// Variable
var foo = "bar",
num = 1,
undef;
//Identificateur littéral :
var array = [],
object = {};
// Utiliser un seul `var` dans une portée (fonction) permet d'améliorer la lisibilité
// et de garder votre liste de déclarations organisée (vous permet également d'économiser quelques frappes au clavier)
var foo = "";
var bar = "";
var qux;
var foo = "",
bar = "",
quux;
var // Commentaires sur ces variables
foo = "",
bar = "",
quux;
// Les instructions `var` doivent toujours être en haut de leurs portées respectives (fonctions)
// Fonctionne également avec les constantes d'ECMAScript 6
fonction foo() {
var bar = "",
qux;
}
function foo() {
var bar = "",
qux;
}
// 2.B.2.1
// Déclaration de fonction nommée
function foo( arg1, argN ) {
// Utilisation
foo( arg1, argN );
// Déclaration de fonction nommée
function square( number) {
return number * number;
}
carré( 10 );
// Style de passage de continuation très peu naturel
callback( number * number );
}
square( 10, function( square ) {
});
// 2.B.2.3
var square = function( number) {
// Renvoie un contenu précieux et pertinent
return number * number;
} ;
// Expression de fonction avec identifiant
// et a l'identifiant sur la pile
var factorial = function factorial ( number ) {
if ( number return 1;
}
renvoie le numéro * factorial( number-1 );
// 2.B.2.4
fonction FooBar( options ) {
this.options = options;
// Utilisation
fooBar.options;
// 2.C.1.1
// Fonction avec rappel
foo(function() {
// Remarque : les parenthèses et `function` dans le premier appel de fonction Il y a pas d'espaces
});
// La fonction accepte `array` comme paramètre, sans espaces
foo([ "alpha", "beta" ]);
// 2.C.1.2
// La fonction accepte `object` comme paramètre, sans espaces
foo({
a: "alpha",
b: "beta"
});
// La fonction accepte le littéral `string` comme paramètre, sans espaces
foo("bar");
//Il n'y a aucun espace à l'intérieur des parenthèses utilisé pour le regroupement
if ( !("foo" in obj) ) {
}
D. La cohérence gagne toujours
Dans les sections 2.A-2.C, l'espace blanc est proposé comme approche recommandée basée sur un objectif simple et supérieur : l'unité. Il convient de noter que les préférences de formatage telles que « espace blanc interne » doivent être facultatives, mais qu'un seul type doit exister dans le code source de l'ensemble du projet.
// 2.D.1.1
if (condition) {
// Déclaration
}
pendant que (condition) {
// Déclaration
}
pour (var i = 0; i // Déclaration
}
if (true) {
// Déclaration
} else {
// Déclaration
}
Citations
Peu importe que vous choisissiez des guillemets simples ou des guillemets doubles, ils ne font aucune différence dans l'analyse en JavaScript. Ce qu’il faut absolument faire respecter, c’est la cohérence. Ne mélangez jamais deux types de devis dans un même projet, choisissez-en un et soyez cohérent.
F. Fin de ligne et ligne vierge
Laisser un espace blanc détruira la distinction et rendra l'utilisation des modifications illisible. Pensez à inclure un hook de pré-validation pour supprimer automatiquement les espaces à la fin des lignes et dans les lignes vides.
3. Détection de type (à partir des directives de style jQuery Core)
A. Types directs (types réels, types réels)
Chaîne :
typeof variable == = "string"
Numéro :
typeof variable = == "number"
Booléen :
typeof variable === "booléen"
Objet :
typeof variable === "object"
Array :
Array.isArray( arrayLikeObject )
(si possible)
Noeud :
elem.nodeType === 1
null :
variable === null
Nul ou non défini :
variable = = nul
non défini :
Variables globales :
type de variable = == " non défini"
Variable locale :
variable === non défini
Attribut :
object.prop === non défini
object.hasOwnProperty( prop )
"prop" dans l'objet
Type de conversion (type forcé, types contraints)
Considérez la signification de ceci...
Donné HTML :
//3.B.1.1
// `foo` a reçu la valeur `0` et le type est `number`
var foo = 0;
// typeof foo;
// "numéro"
...
// Dans le code suivant, vous devez mettre à jour `foo` pour donner la nouvelle valeur obtenue dans l'élément d'entrée
foo = document.getElementById("foo-input").value;
// Si vous testez maintenant `typeof foo`, le résultat sera `string`
// Cela signifie que votre instruction if pour détecter `foo` a une logique similaire à celle-ci :
if ( foo === 1 ) {
importantTask();
}
// `importantTask()` ne sera jamais exécuté même si `foo` a une valeur "1"
//3.B.1.2
// Vous pouvez intelligemment utiliser l'opérateur unaire / - pour convertir le type afin de résoudre le problème :
foo = document.getElementById("foo-input").value;
// ^ L'opérateur unaire convertit l'opérande de son côté droit en `number`
// typeof foo;
// "numéro"
if ( foo === 1 ) {
importantTask();
}
// `importantTask()` sera appelé
Pour les castings, voici quelques exemples :
// 3.B.2.1
var number = 1,
string = "1",
bool = false;
numéro ;
// 1
numéro "";
// "1"
chaîne;
// "1"
chaîne ;
// 1
chaîne ;
// 1
chaîne;
// 2
bool;
// faux
booléen;
// 0
bool "";
// "faux"
// 3.B.2.2
var number = 1,
string = "1",
bool = true;
string === nombre;
// false
string === nombre "";
// vrai
string === nombre;
// vrai
bool === nombre;
// faux
bool === nombre;
// vrai
bool === string;
// false
bool === !!string;
// true
// 3.B.2.3
var array = [ "a", "b", "c" ];
!!~array.indexOf("a");
//true
!!~array.indexOf("b");
//true
!!~array.indexOf("c");
//true
!!~array.indexOf("d");
// false
// Il convient de noter que les éléments ci-dessus sont "inutilement intelligents"
// Utilisez une solution claire pour comparer les valeurs renvoyées
// Comme indexOf :
if ( array.indexOf( "a" ) >= 0 ) {
// ...
}
// 3.B.2.3
var num = 2,5;
parseInt( num, 10 );
// Equivalent à...
~~num;
numéro>> 0;
numéro>>> 0;
//Le résultat est toujours 2
// Gardez toujours à l'esprit que les valeurs négatives seront traitées différemment...
var nég = -2,5;
parseInt( neg, 10 );
// Equivalent à...
~~nég;
nég>> 0;
// Le résultat est toujours -2
// Mais...
nég>>> 0;
//Le résultat est 4294967294
4.Opération de comparaison
// 4.1.1
// Lorsque vous jugez simplement si un tableau a une longueur, utilisez plutôt ceci :
if ( array.length > 0 ) ...
// ...Pour déterminer l'authenticité, veuillez utiliser ceci :
if (array.length) ...
// 4.1.2
// Pour juger simplement si un tableau est vide, utilisez plutôt ceci :
if (array.length === 0) ...
// ...Pour déterminer l'authenticité, veuillez utiliser ceci :
if ( !array.length ) ...
// 4.1.3
// Lorsque vous jugez simplement si une chaîne est vide, utilisez plutôt ceci :
if ( string !== "" ) ...
// ...Pour déterminer l'authenticité, veuillez utiliser ceci :
if (string) ...
// 4.1.4
// Pour juger simplement si une chaîne est vide, utilisez plutôt ceci :
if ( string === "" ) ...
// ...Pour déterminer l'authenticité, veuillez utiliser ceci :
if ( !string ) ...
// 4.1.5
// Lorsque vous jugez simplement si une référence est vraie, utilisez plutôt ceci :
if ( foo === true ) ...
// ... jugez comme vous pensez et profitez des avantages des fonctions intégrées :
if ( foo ) ...
// 4.1.6
// Lorsque vous jugez simplement si une référence est fausse, utilisez plutôt ceci :
if ( foo === false ) ...
// ...convertissez-le en vrai en utilisant un point d'exclamation
if ( !foo ) ...
// ...Il est à noter que : ceci correspondra à 0, "", null, undefined, NaN
// Si vous _devez_ être faux de type booléen, veuillez l'utiliser comme ceci :
si ( foo === false ) ...
// 4.1.7
// Si vous souhaitez calculer une référence, elle peut être nulle ou indéfinie, mais elle n'est pas fausse, "" ou 0,
// Au lieu d'utiliser ceci :
if ( foo === null || foo === non défini ) ...
// ...profitez des avantages du casting de type ==, comme ceci :
if ( foo == null ) ...
// N'oubliez pas que l'utilisation de == fera correspondre `null` à `null` et `undefined`
// mais pas `false`, "" ou 0
null == undefined
Jugez toujours de la valeur la meilleure et la plus précise, ce qui précède est une ligne directrice et non un dogme.
// 4.2.1
/ / Instructions d'opération de conversion et de comparaison de type
// `===` en premier, `==` en second (sauf si une comparaison vaguement typée est requise)
// `===` n'effectue jamais de conversion de type, ce qui signifie :
"1" === 1;
// faux
// `==` convertira le type, ce qui signifie :
"1" == 1;
// vrai
// 4.2.2
// Booléen, Vrai & Faux
// Booléen :
vrai, faux
// Vrai :
"foo", 1
// Pseudo :
"", 0, nul, indéfini, NaN, vide 0
5. Style pratique
// 5.1.1
// Un module pratique
(function( global) {
var Module = (function() {
var data = "secret";
return {
// Ceci est une valeur booléenne
bool: true,
bool: true,
// Une chaîne
chaîne: "une chaîne",
/ / Un tableau
array : [ 1, 2, 3, 4 ],
// Un objet
object : {
lang : "en-Us"
},
getData : function() {
data = valeur );
. }
};
})();
// Quelques autres apparaîtront ici
// Transformez votre module en objet global
})( ceci );
// 5.2.1
(fonction( global ) {
fonction Ctor( foo ) {
this.foo = foo;
renvoie ceci ;
}Ctor.prototype.getFoo = function() {
return this.foo;
};
Ctor.prototype.setFoo = function( val ) {
return ( this.foo = val );
};
// Au lieu d'utiliser `new` pour appeler le constructeur, vous pouvez faire ceci :
var ctor = function( foo ) {
return new Ctor( foo );
// Transforme notre constructeur en objet global
global.ctor = ctor;
6. Nommer
A. Vous n'êtes pas un compilateur/compresseur humain, alors essayez de le devenir.
Le code suivant est un exemple de dénomination extrêmement mauvaise :
// 6.A.1.1
// Exemple de code mal nommé
function q(s) {
return document.querySelectorAll(s);
}
var i,a=[],els=q("#foo");
for( i=0;i
Vous avez sans aucun doute écrit un tel code - j'espère qu'il n'apparaîtra plus jamais à partir d'aujourd'hui.
Voici un code pour la même logique, mais avec une dénomination plus robuste et appropriée (et une structure lisible) :
// 6.A.2.1
// Exemple de code de dénomination amélioré
function query( selector ) {
return document.querySelectorAll( selector );
}
var idx = 0,
elements = [],
matches = query("#foo"),
length = matches.length;
for ( ; idx elements.push( matches[ idx ] );
}
Quelques conseils de dénomination supplémentaires :
// 6.A.3.1
// Chaîne nommée
`dog` est une chaîne
// 6.A.3.2
// Tableaux nommés
`['dogs']` est un tableau
contenant la `dog string// 6.A.3.3
// Fonctions, objets, instances nommés, etc.
camlCase ; fonction et déclaration var
// 6.A.3.4
// Constructeurs nommés, prototypes, etc.
PascalCase; fonction constructeur
// 6.A.3.5
// Expressions régulières nommées
rDesc = //;
// 6.A.3.6
// Tiré du guide de style de la bibliothèque de fermeture de Google
functionNamesLikeThis;
variableNamesLikeThis;
ConstructorNamesLikeThis;
EnumNamesLikeThis;
methodNamesLikeThis;
SYMBOLIC_CONSTANTS_LIKE_THIS;
Faire face à ça
En plus d'utiliser le célèbre call and apply, préférez toujours .bind( this ) ou un équivalent fonctionnel de celui-ci. Créez une déclaration BoundFunction pour les appels ultérieurs, en utilisant des alias uniquement lorsqu'il n'y a pas de meilleure alternative.
// 6.B.1
fonction Appareil (opts) {
this.value = null;
// Créer un nouveau flux asynchrone, qui sera appelé en continu
stream.read( opts.path, function( data ) {
// Utilisez stream pour renvoyer la dernière valeur des données et mettre à jour la valeur de l'instance
this.value = data;
}.bind(this) );
// Contrôler la fréquence de déclenchement des événements
setInterval(function() {
// Émettre un événement contrôlé
this.emit("event");
}.bind(this), opts.freq || 100 );
}
// Supposons que nous ayons hérité de l'émetteur d'événements (EventEmitter) ;)
Lorsque cela ne fonctionne pas, une fonctionnalité équivalente à .bind est disponible dans la plupart des bibliothèques JavaScript modernes.
// 6.B.2
// Exemple : lodash/underscore, _.bind()
function Device( opts ) {
this.value = null;
stream.read( opts.path, _.bind(function( data ) {
this.value = data;
}, ceci) );
setInterval(_.bind(function() {
this.emit("événement");
}, ceci), opts.freq || 100 );
}
// Exemple : jQuery.proxy
function Device( opts ) {
this.value = null;
stream.read( opts.path, jQuery.proxy(function( data ) {
this.value = data;
}, ceci) );
setInterval( jQuery.proxy(function() {
this.emit("événement");
}, ceci), opts.freq || 100 );
}
// Exemple : dojo.hitch
function Device( opts ) {
this.value = null;
stream.read( opts.path, dojo.hitch( this, function( data ) {
this.value = data;
}) );
setInterval( dojo.hitch( this, function() {
this.emit("événement");
}), opts.freq || 100 );
}
Fournissez un candidat pour créer un alias de celui-ci avec soi comme identifiant. Ceci est très bogué et doit être évité si possible.
// 6.B.3
function Device( opts ) {
var self = this;
this.value = null;
stream.read( opts.path, function( data ) {
self.value = data;
});
setInterval(function() {
self.emit("event");
}, opts.freq || 100 );
}
C. Utilisez cetArg
Plusieurs méthodes de prototype dans ES 5.1 ont une balise thisArg spéciale intégrée, utilisez-la autant que possible
// 6.C.1
var obj;
obj = { f : "foo", b : "bar", q : "qux" };
Object.keys( obj ).forEach(function( key ) {
// |ceci| est maintenant `obj`
console.log( this[ clé ] );
}, obj ); //
//Imprimez-le...
// "foo"
// "bar"
// "qux"
thisArg est dans Array.prototype.every, Array.prototype.forEach, Array. prototype Il peut être utilisé dans .some, Array.prototype.map et Array.prototype.filter.
7. Divers
Les idées et concepts qui seront expliqués dans cette section ne sont pas des dogmes. Au lieu de cela, cela encourage la curiosité à l'égard des pratiques existantes pour tenter de fournir de meilleures solutions pour les tâches générales de programmation JavaScript.
A. Évitez d'utiliser switch, le traçage des méthodes modernes mettra sur liste noire les fonctions avec des expressions switch.
Il semble que les instructions switch aient été considérablement améliorées dans les dernières versions de Firefox et de Chrome. http://jsperf.com/switch-vs-object-literal-vs-module
Il est à noter que les améliorations peuvent être vues ici : https://github.com/rwldrn/idiomatic.js/issues/13
// 7.A.1.1
// Exemple d'instruction Switch
switch( foo ) {
case "alpha":
alpha();
break;
case "beta":
beta();
break;
default :
//Branche par défaut
break;
}
// 7.A.1.2
// Une façon de prendre en charge la composition et la réutilisation est d'utiliser un objet pour stocker des "cas",
// Utiliser une fonction pour déléguer :
cas var, délégant;
// La valeur de retour est à titre d'illustration uniquement
cases = {
alpha: function() {
// Instruction
// Une valeur de retour
return [ "Alpha", arguments .length ];
},
bêta : function() {
// Déclaration
// Une valeur de retour
return [ "Beta", arguments.length ];
} ,
_default: function() {
// Instruction
// Une valeur de retour
return [ "Default", arguments.length ];
}
};
délégué = fonction() {
var args, clé, délégué ;
// Convertir `argument` en tableau
args = [].slice.call( arguments );
// Extraire la première valeur de `argument`
key = args.shift();
// Appeler la branche par défaut
délégué = cases._default;
// Déléguer les méthodes de l'objet
if ( cases.hasOwnProperty( key ) ) {
délégué = cases[ key ];
}
// La portée de arg peut être définie sur une valeur spécifique,
// Dans ce cas, |null| convient
return délégué.apply( null, args );
};
// 7.A.1.3
// Utilisation de l'API en 7.A.1.2 :
délégué( "alpha", 1, 2, 3, 4, 5 );
// [ "Alpha", 5 ]
// Bien sûr, la valeur de la clé `case` peut être facilement modifiée en n'importe quelle valeur
var caseKey, someUserInput;
// Est-il possible qu'il s'agisse d'une forme de saisie ?
someUserInput = 9;
if ( someUserInput > 10 ) {
caseKey = "alpha";
} else {
caseKey = "beta";
}
// Ou...
caseKey = someUserInput > 10 ? "alpha" : "bêta";
// Alors...
délégué( caseKey, someUserInput );
// [ "Beta", 1 ]
// Bien sûr que vous pouvez le faire de cette façon...
délégué();
// [ "Par défaut", 0 ]
B. Renvoyer la valeur plus tôt améliore la lisibilité du code sans grande différence de performances
// 7.B.1.1
// Mauvais :
function returnLate( foo ) {
var ret;
if ( foo ) {
ret = "foo";
} else {
ret = "quux";
}
return ret;
>
// D'accord :
fonction returnEarly( foo ) {
if ( foo ) {
return "foo";
}
return "quux";
}
8. Objets natifs et hôtes (Remarque : en fait, j'ai toujours pensé que les objets hôtes ne devaient pas être traduits, je vais donc les traduire selon la façon dont ils sont écrits dans les livres ordinaires)
Le principe le plus fondamental est :
Ne faites rien de stupide, les choses iront mieux.
Pour renforcer cette idée, regardez cette démo :
« Tout est permis : extensions natives » par Andrew Dupont (JSConf2011, Portland, Oregon)
http://blip.tv/jsconf/jsconf2011-andrew-dupont-everything-is-permit-extending-built-ins-5211542
9. Remarques
Les commentaires sur une seule ligne placés au-dessus du code sont préférés
Plusieurs lignes sont également possibles
Les commentaires de fin de ligne doivent être évités !
La méthode JSDoc est également bonne, mais elle prend plus de temps
10. Utiliser une seule langue
Les programmes ne doivent être écrits que dans la même langue, quelle que soit la langue spécifiée par le responsable du programme (ou l'équipe).
Annexe
La virgule d'abord
Tous les projets qui utilisent ce document comme guide de style de base n'autorisent pas le formatage du code avec des virgules de début, sauf indication contraire ou demande explicite de l'auteur.

Python convient plus aux débutants, avec une courbe d'apprentissage en douceur et une syntaxe concise; JavaScript convient au développement frontal, avec une courbe d'apprentissage abrupte et une syntaxe flexible. 1. La syntaxe Python est intuitive et adaptée à la science des données et au développement back-end. 2. JavaScript est flexible et largement utilisé dans la programmation frontale et côté serveur.

Python et JavaScript ont leurs propres avantages et inconvénients en termes de communauté, de bibliothèques et de ressources. 1) La communauté Python est amicale et adaptée aux débutants, mais les ressources de développement frontal ne sont pas aussi riches que JavaScript. 2) Python est puissant dans les bibliothèques de science des données et d'apprentissage automatique, tandis que JavaScript est meilleur dans les bibliothèques et les cadres de développement frontaux. 3) Les deux ont des ressources d'apprentissage riches, mais Python convient pour commencer par des documents officiels, tandis que JavaScript est meilleur avec MDNWEBDOCS. Le choix doit être basé sur les besoins du projet et les intérêts personnels.

Le passage de C / C à JavaScript nécessite de s'adapter à la frappe dynamique, à la collecte des ordures et à la programmation asynchrone. 1) C / C est un langage dactylographié statiquement qui nécessite une gestion manuelle de la mémoire, tandis que JavaScript est dynamiquement typé et que la collecte des déchets est automatiquement traitée. 2) C / C doit être compilé en code machine, tandis que JavaScript est une langue interprétée. 3) JavaScript introduit des concepts tels que les fermetures, les chaînes de prototypes et la promesse, ce qui améliore la flexibilité et les capacités de programmation asynchrones.

Différents moteurs JavaScript ont des effets différents lors de l'analyse et de l'exécution du code JavaScript, car les principes d'implémentation et les stratégies d'optimisation de chaque moteur diffèrent. 1. Analyse lexicale: convertir le code source en unité lexicale. 2. Analyse de la grammaire: générer un arbre de syntaxe abstrait. 3. Optimisation et compilation: générer du code machine via le compilateur JIT. 4. Exécuter: Exécutez le code machine. Le moteur V8 optimise grâce à une compilation instantanée et à une classe cachée, SpiderMonkey utilise un système d'inférence de type, résultant en différentes performances de performances sur le même code.

Les applications de JavaScript dans le monde réel incluent la programmation côté serveur, le développement des applications mobiles et le contrôle de l'Internet des objets: 1. La programmation côté serveur est réalisée via Node.js, adaptée au traitement de demande élevé simultané. 2. Le développement d'applications mobiles est effectué par le reactnatif et prend en charge le déploiement multiplateforme. 3. Utilisé pour le contrôle des périphériques IoT via la bibliothèque Johnny-Five, adapté à l'interaction matérielle.

J'ai construit une application SAAS multi-locataire fonctionnelle (une application EdTech) avec votre outil technologique quotidien et vous pouvez faire de même. Premièrement, qu'est-ce qu'une application SaaS multi-locataire? Les applications saas multi-locataires vous permettent de servir plusieurs clients à partir d'un chant

Cet article démontre l'intégration frontale avec un backend sécurisé par permis, construisant une application fonctionnelle EdTech SaaS en utilisant Next.js. Le frontend récupère les autorisations des utilisateurs pour contrôler la visibilité de l'interface utilisateur et garantit que les demandes d'API adhèrent à la base de rôles

JavaScript est le langage central du développement Web moderne et est largement utilisé pour sa diversité et sa flexibilité. 1) Développement frontal: construire des pages Web dynamiques et des applications à une seule page via les opérations DOM et les cadres modernes (tels que React, Vue.js, Angular). 2) Développement côté serveur: Node.js utilise un modèle d'E / S non bloquant pour gérer une concurrence élevée et des applications en temps réel. 3) Développement des applications mobiles et de bureau: le développement de la plate-forme multiplateuse est réalisé par réact noral et électron pour améliorer l'efficacité du développement.


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

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

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.

Adaptateur de serveur SAP NetWeaver pour Eclipse
Intégrez Eclipse au serveur d'applications SAP NetWeaver.

VSCode Windows 64 bits Télécharger
Un éditeur IDE gratuit et puissant lancé par Microsoft

SublimeText3 version anglaise
Recommandé : version Win, prend en charge les invites de code !

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