2017-09-19 14 views
0

Pour le fichier main d'un module npm, tel que défini par le package.json, je considérais un modèle comme celui-ci:Inconvénient de la convention d'exportation ES6 et CommonJS

import Struct from './src/struct' 

module.exports = Struct 
module.exports.default = Struct 

Afin de soutenir les CommonJS et les importations de ES6:

const Struct = require('my-module') 
// or 
import Struct from 'my-module' 

Y a-t-il des inconvénients à cette convention qui pourraient causer des problèmes involontaires?

La question que je vais essayer d'aborder est d'avoir à forcer les consommateurs du paquet à coller à ES6 ou CommonJS parce que ces deux semblent plutôt peu recommandables:

const Struct = require('my-module').default 
// or 
import * as Struct from 'my-module' 

Après avoir examiné plus loin, serait de définir ma classe dans /src/struct.js comme celui-ci est préférable?

export default class Struct { 
    static get default() { 
    return Struct 
    } 
    ... 
} 
+0

Quel type est 'Struct' dans ce cas? En général, je vous recommande d'éviter d'ajouter des propriétés sur des objets qui ne sont pas définis dans ce même fichier, mais vous pouvez probablement éviter cela en fonction de ce qu'il est réellement.Etant donné que les compilateurs ajoutent généralement de la logique pour que les modules CommonJS fonctionnent automatiquement avec 'import', quel problème essayez-vous spécifiquement d'éviter? – loganfsmyth

+0

@loganfsmyth Eh bien, 'Struct' est simplement une classe avec des fonctionnalités que je voudrais empaqueter comme un module npm, donc l'ajout d'une propriété statique' default' ne semble pas très nuisible. Peut-être devrais-je le rendre non-énumérable ou quelque chose pour éviter de l'énumérer accidentellement? –

+0

Babel utilisera 'module.exports' comme export par défaut si le module importé est CommonJS, donc je ne vois pas comment' module.exports.default = Struct' aide. Est-ce que les autres bundlers ne le font pas? –

Répondre

4

Lets look at what Babel does when you do import foo from 'bar';:

'use strict'; 

var _bar = require('bar'); 

var _bar2 = _interopRequireDefault(_bar); 

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 

Vous pouvez voir que, en fonction du "type" du module importé, Babel soit importer l'exportation default, ou il importera module.exports (parce que require('bar') retours module.exports

.

Cela signifie, pour que votre module soit importable comme

const Struct = require('my-module') 
// and 
import Struct from 'my-module' 

Tout ce que vous avez à faire est

module.exports = Struct; 
0

Eh bien, puisque nodejs ne dispose toujours pas de support natif pour les modules ES6, pour l'instant il est vraiment juste une question de lisibilité du code. Mais l'OMI n'a pas besoin de supporter les modules CommonJS et ES6. Stick à un.

+0

Je me rends compte qu'il n'y a pas de support natif pour ES6, mais ce n'est pas le point. Il est extrêmement fréquent que les consommateurs utilisent les services babel, webpack, rollup, browserify et d'autres services de groupage qui ignorent les limitations du support natif en faisant passer le code source des futures spécifications. Je ne veux pas forcer les gens utilisant ces configurations à utiliser l'une des maladroites 'import * comme Struct de 'my-module'' comme je l'ai dit plus haut, car ce n'est pas une façon très classique d'utiliser' import' dans ES6 . –

1

Faire fonctionner pour un paquet casse uniformité et peut créer une confusion:

import Struct from 'my-module'; // works 
import Foo from 'another-module'; // fails 

exportations default sont généralement mis au rebut dans des emballages NPM (à moins qu'ils ont été construits à partir ES6) parce que

const Struct = require('my-module').default; 

et

const { default: Struct } = require('my-module'); 

sont lourdes et plus difficiles à lire. Alors que

import * as Struct from 'my-module'; 

est équivalent à

const Struct = require('my-module'); 

à Babel et 6 est la façon dont il devrait généralement être fait par les utilisateurs. S'ils n'ont pas encore cette habitude concernant les importations CommonJS, ils doivent probablement l'acquérir.