web-dev-qa-db-fra.com

Caractère générique ou astérisque (*) vs importation nommée ou sélective es6 javascript

Vous vous demandez simplement quel est le meilleur moyen d'utiliser import:

import * as Foo from './foo';

CONTRE:

import { bar, bar2, bar3 } from './foo';

En termes d’efficacité, par exemple, j’utilise Webpack pour regrouper tous les fichiers JavaScript. Le premier importera-t-il réellement tout, même si je ne les utilise pas dans le code principal?

Certaines références que je peux trouver sont:

Dans Guide de style Airbnb , ils ne recommandent aucun caractère générique; il y aura donc toujours un objet d'importation par défaut, et this .

17
andiwin

Si vous utilisez webpack avec l'élimination du code mort fourni par le nouvel uglify ou des rollupjs avec arborescence, les importations inutilisées seront supprimées.

Je suis partiellement d'accord avec le guide de style airbnb pour ne pas utiliser les importations génériques, bien que les importations javascripts génériques ne souffrent pas des mêmes maladies que par exemple les importations génériques pythons ou javas, à savoir qu'elle ne pollue pas la portée avec des noms de variable définis dans d'autres modules (vous ne peut y accéder que par moduleB.foo, pas foo lorsqu’on utilise import * as moduleB from ...).

À propos de l'article sur les tests: je comprends assez bien les préoccupations, mais je ne vois rien qui ne puisse être résolu là-bas. Vous pouvez simuler les importations elles-mêmes avec un chargeur de module personnalisé (un chargeur de module AMD personnalisé est littéralement de 15 lignes de code), afin de ne pas avoir à vous soucier de la portée locale du module testé.

14
Tamas Hegedus

Concernant cette partie de la question: 

Le premier importera-t-il réellement tout, même si je ne les utilise pas dans le code principal?

Voici comment cela a été compilé avec Babel 6.26:

Nommé

import { bar, bar2, bar3 } from './foo';

... devient ...

'use strict';

var _foo = require('./foo');

Wildcard

import * as Foo from './foo';

... devient ...

'use strict';

var _foo = require('./foo');

var Foo = _interopRequireWildcard(_foo);

function _interopRequireWildcard(obj) { 
    if (obj && obj.__esModule) { 
        return obj;
    } else {
        var newObj = {}; 
        if (obj != null) { 
            for (var key in obj) { 
                if (Object.prototype.hasOwnProperty.call(obj, key))
                    newObj[key] = obj[key];
            }
        }
        newObj.default = obj; 
        return newObj;
    }
}

Dans les deux cas, le fichier entier est importé via require

Avec les importations de caractères génériques, une fonction _interopRequireWildcard est définie et utilisée pour affecter toutes les exportations à la variable d'espace de nom.

Il est à noter que le code compilé ne contiendra qu'une seule définition _interopRequireWildcard et un appel à require et _interopRequireWildcard pour chaque importation.

En fin de compte, l’utilisation d’importations génériques impliquera un peu plus de traitement au moment de l’exécution et entraînera une légère augmentation de la taille du fichier js compilé.

10
idmadj

Je suis d'accord avec @Tamas.
Si vous avez besoin d'un accès complet à toutes les exportations du fichier cible, vous pouvez utiliser le import * as Foo from './foo'; Ou import foo from './foo': 

mais si vous devez utiliser une fonction ou un const spécifique, évitez plutôt "import *" et expliquez clairement ce que vous devez faire.

3
Moeen Basra

Dans la mesure où, avec une configuration WebPack moderne, les deux généreront le même JS compilé/transpilé, la valeur réelle des importations nommées correspond à son degré d’expression. En nommant vos importations, vous indiquez à quiconque ouvre le fichier qui fonctionne à partir d’un module que vous allez utiliser. Cela peut être utile, par exemple, lors de la rédaction de tests. Si vous devez vous moquer, vous avez une liste explicite d’importations à simuler. 

0
Kelly Anderson