web-dev-qa-db-fra.com

Importation de modules de nœud à partir du répertoire racine à l'aide de es6 et de babel-node

J'écris une application de noeud avec es6 en utilisant babel transpiler.

J'ai 2 fichiers index.js & my-module.js sur mon répertoire racine

- index.js
- my-module.js

my-module.js

export let myFunc = () => {
  console.log('myFunc was called!!!');
}

index.js

import {myFunc} from './my-module';
myFunc();

si je lance la ligne suivante à partir de la ligne de commande, tout fonctionne comme prévu.

$ babel-node index.js >> myFunc was called!!!

mais si je supprime le point lors de l'importation de mon module:

import {myFunc} from '/my-module';
myFunc();

Je reçois une erreur:

Error: Cannot find module '/my-module'

Pourquoi ne puis-je pas importer de modules en utilisant un chemin absolu? de toute façon pour changer .babelrc config pour le supporter?

Merci

42
Gavriguy

Comme (presque) n'importe quel outil '/ x' signifie 'x' à la racine de votre système de fichiers. Babel ne regarde pas les chemins, il compile

import {myFunc} from '/my-module';

dans

var _myModule = require('/my-module');

Et noeud recherche le module.


Si vous voulez vraiment importer par rapport à la racine du projet, vous pouvez utiliser un plugin. Je recommande d'utiliser quelque chose qui ne soit pas très ambigu, et assurez-vous de le documenter pour la prochaine personne qui lira votre code!

Voici un exemple où nous utilisons un ~ signifie un parent de projet. Vous pouvez utiliser ce que vous voulez, par exemple ^ serait également bon.

Exemple d'entrée:

import {a} from '~my-module';
import {b} from '/my-module';
import {c} from './my-module';

scripts/babel-plugin-project-relative-require.js

module.exports = function (babel) {
  // get the working directory
  var cwd = process.cwd();

  return new babel.Transformer("babel-plugin-project-relative-require", {
    ImportDeclaration: function(node, parent) {
      // probably always true, but let's be safe
      if (!babel.types.isLiteral(node.source)) {
        return node;
      }

      var ref = node.source.value;

      // ensure a value, make sure it's not home relative e.g. ~/foo
      if (!ref || ref[0] !== '~' || ref[1] === '/') {
        return node;
      }

      node.source.value = cwd + '/' + node.source.value.slice(1);

      return node;
    }
  });
};

.babelrc

{
    "plugins": [
        "./scripts/babel-plugin-project-relative-require.js"
    ]
}

Sortie (si exécuté dans/tmp):

'use strict';

var _tmpMyModule = require('/tmp/my-module');

var _myModule = require('/my-module');

var _myModule2 = require('./my-module');
56
Brigand

La solution de FakeRainBrigand/Gavriguy est bonne et fonctionne bien. J'ai donc décidé de développer un plugin que vous pouvez facilement installer avec npm et utiliser un simple plugin Babel.

https://github.com/michaelzoidl/babel-root-import

J'espère que cela t'aides...

41
Michael J. Zoidl

Tout d'abord, Babel n'est qu'un transpiler de syntaxe ES2015 à ES5. Son travail consiste à transpiler ceci:

import {myFunc} from '/my-module'

dans ceci:

var _myModule = require('/my-module');

Module actuel requis effectué par Node, et comment Node le fait vous pouvez lire les détails ici: https://nodejs.org/api/modules.html#modules_file_modules)

Pour résumer, ./module désigne le chemin d'accès au module par rapport au répertoire local, /module est un chemin absolu vers le module, module déclencheurs Node pour rechercher un module dans le local node_modules répertoire et tous ascendants.

8
vtambourine