web-dev-qa-db-fra.com

Comment rendre node.js required absolu? (au lieu de parent)

Je voudrais demander à mes fichiers toujours par la racine de mon projet et non par rapport au module actuel.

Par exemple, si vous regardez https://github.com/visionmedia/express/blob/2820f2227de0229c5d7f28009aa432f9f3a7b5f9/examples/downloads/app.js la ligne 6, vous verrez

express = require('../../')

C'est vraiment mauvais OMI. Imaginez que je veuille mettre tous mes exemples plus près de la racine d'un niveau. Ce serait impossible, car je devrais mettre à jour plus de 30 exemples et plusieurs fois dans chaque exemple. Pour ça:

express = require('../')

Ma solution serait d’avoir un cas particulier pour la racine: si une chaîne commence par un $, elle est relative au dossier racine du projet.

Toute aide est la bienvenue, merci

Mise à jour 2

Maintenant, j'utilise require.js qui vous permet d'écrire d'une seule manière et fonctionne aussi bien sur le client que sur le serveur. Require.js vous permet également de créer des chemins personnalisés.

Mise à jour 3

Maintenant, je suis passé à webpack + gulp et j'utilise Enhanced-require pour gérer les modules côté serveur. Voir ici la justification: http://hackhat.com/p/110/module-loader-webpack-vs-requirejs-vs-browserify/

216
Totty.js

Voici ce que je fais depuis plus de 6 mois. J'utilise un dossier nommé node_modules comme dossier racine dans le projet. De cette manière, il recherchera toujours ce dossier partout où j'appellerai une nécessité absolue:

  • node_modules
    • mon projet
      • index.js je peux exiger ("myProject/someFolder/hey.js") au lieu de require ("./ someFolder/hey.js")
      • un dossier qui contient hey.js

Ceci est plus utile lorsque vous êtes imbriqué dans des dossiers et qu'il est beaucoup moins fastidieux de changer un emplacement de fichier s'il est défini de manière absolue. Je n'utilise que 2 le besoin relatif dans mon application entière .

5
Totty.js

Et à propos de:

var myModule = require.main.require('./path/to/module');

Il nécessite le fichier comme s'il était requis à partir du fichier js principal. Il fonctionne donc assez bien tant que votre fichier js principal est à la racine de votre projet ... et c'est quelque chose que j'apprécie.

153
cronvel

Il y a une section vraiment intéressante dans le Browserify Handbook :

en évitant ../../../../../../ ..

Tout ce qui se trouve dans une application ne doit pas nécessairement appartenir au npm public et la charge de la configuration d'un npm privé ou d'un dépôt git privé reste relativement importante dans de nombreux cas. Voici quelques approches pour éviter le problème de chemins relatifs ../../../../../../../.

node_modules

Les gens s'opposent parfois à l'insertion de modules spécifiques à une application dans node_modules, car il n'est pas évident de vérifier dans vos modules internes sans archiver également les modules tiers à partir de npm.

La réponse est assez simple! Si vous avez un fichier .gitignore qui ignore node_modules:

node_modules

Vous pouvez simplement ajouter une exception avec ! pour chacun de vos modules d'application internes:

node_modules/*
!node_modules/foo
!node_modules/bar

Veuillez noter que vous ne pouvez pas unignorer un sous-répertoire, si le parent est déjà ignoré. Donc, au lieu d’ignorer node_modules, vous devez ignorer tous les répertoires à l’intérieur de node_modules avec l’astuce node_modules/*, et alors vous pouvez ajouter vos exceptions.

Désormais, n'importe où dans votre application, vous pourrez require('foo') ou require('bar') sans disposer d'un chemin relatif très grand et fragile.

Si vous avez beaucoup de modules et que vous voulez les séparer davantage des modules tiers installés par npm, vous pouvez simplement les placer tous dans un répertoire dans node_modules, tel que node_modules/app:

node_modules/app/foo
node_modules/app/bar

Maintenant, vous pourrez require('app/foo') ou require('app/bar') de n’importe où dans votre application.

Dans votre .gitignore, ajoutez simplement une exception pour node_modules/app:

node_modules/*
!node_modules/app

Si votre application avait des transformations configurées dans package.json, vous devrez créer un package.json distinct avec son propre champ de transformation dans votre répertoire de composant node_modules/foo ou node_modules/app/foo, car les transformations ne s'appliquent pas au module. limites. Cela rendra vos modules plus robustes face aux changements de configuration dans votre application et il sera plus facile de réutiliser indépendamment les packages en dehors de votre application.

lien symbolique

Une autre astuce utile si vous travaillez sur une application dans laquelle vous pouvez créer des liens symboliques sans avoir besoin de prendre en charge Windows est de créer un lien symbolique vers un dossier lib/ ou app/ dans node_modules. A la racine du projet, faites:

ln -s ../lib node_modules/app

et maintenant de n'importe où dans votre projet, vous pourrez exiger des fichiers dans lib/ en faisant require('app/foo.js') pour obtenir lib/foo.js.

chemins personnalisés

Vous verrez peut-être certains endroits parler de l'utilisation de la variable d'environnement $NODE_PATH ou de opts.paths pour ajouter des répertoires pour noeud et de navigateur pour rechercher des modules.

Contrairement à la plupart des autres plates-formes, l'utilisation d'un tableau de répertoires de chemins de style Shell avec $NODE_PATH n'est pas aussi favorable dans le nœud que l'utilisation du répertoire node_modules.

En effet, votre application est plus étroitement couplée à une configuration d'environnement d'exécution. Il y a donc davantage de pièces mobiles et votre application ne fonctionnera que si votre environnement est correctement configuré.

node et browserify prennent en charge mais découragent l'utilisation de $NODE_PATH.

124
Paolo Moretti

J'aime créer un nouveau dossier node_modules pour le code partagé, puis laisser le noeud et demander à ce qu'il fait de son mieux.

par exemple:

- node_modules // => these are loaded from your package.json
- app
  - node_modules // => add node-style modules
    - helper.js
  - models
    - user
    - car
- package.json
- .gitignore

Par exemple, si vous êtes dans car/index.js, vous pouvez require('helper') et le noeud le trouvera!

Fonctionnement de node_modules

node a un algorithme intelligent pour résoudre les modules qui est unique parmi les plates-formes rivales.

Si vous require('./foo.js') de /beep/boop/bar.js, le noeud recherchera ./foo.js dans /beep/boop/foo.js. Les chemins commençant par ./ ou ../ sont toujours locaux par rapport au fichier qui appelle require().

Si toutefois vous avez besoin d'un nom non relatif tel que require('xyz') de /beep/boop/foo.js, node recherche ces chemins dans l'ordre, en s'arrêtant à la première correspondance et en générant une erreur si rien n'est trouvé:

/beep/boop/node_modules/xyz
/beep/node_modules/xyz
/node_modules/xyz

Pour chaque répertoire xyz existant, le nœud cherchera d'abord un xyz/package.json pour voir si un champ "main" existe. Le champ "main" définit le fichier à prendre en charge si vous require() le chemin du répertoire.

Par exemple, si /beep/node_modules/xyz est la première correspondance et /beep/node_modules/xyz/package.json a:

{
  "name": "xyz",
  "version": "1.2.3",
  "main": "lib/abc.js"
}

alors les exportations de /beep/node_modules/xyz/lib/abc.js seront retournées par require('xyz').

S'il n'y a pas de champ package.json ou pas de "main", index.js est supposé:

/beep/node_modules/xyz/index.js
66
Blair Anderson

La grande image

Cela semble "vraiment mauvais" mais donnez-lui le temps. En fait, c'est vraiment bien. Les require()s explicites offrent une transparence totale et une facilité de compréhension qui s'apparente à une bouffée d'air frais au cours du cycle de vie d'un projet.

Pensez-y de cette façon: vous lisez un exemple, vous plongez dans Node.js et vous avez décidé que c’était "vraiment mauvais OMI". Vous êtes des leaders de la communauté Node.js qui doutent, des personnes qui ont passé plus de temps à écrire et à maintenir des applications Node.js que quiconque. Quelle est la chance que l'auteur ait commis une telle erreur de recrue? (Et je suis d’accord, vu mon arrière-plan Ruby et Python, il semble au début qu’il s’agisse d’un désastre.)

Il y a beaucoup de battage publicitaire et de contre-battages entourant Node.js. Mais lorsque la poussière sera retombée, nous admettrons que les modules explicites et les packages "locaux d'abord" ont été un facteur majeur d'adoption.

Le cas commun

Bien sûr, node_modules du répertoire en cours, puis le parent, puis grand-parent, arrière-grand-parent, etc. sont recherchés. Donc les paquets que vous avez installés fonctionnent déjà de cette façon. Habituellement, vous pouvez require("express") de n’importe où dans votre projet et cela fonctionne correctement.

Si vous vous retrouvez en train de charger des fichiers communs à partir de la racine de votre projet (peut-être parce que ce sont des fonctions utilitaires communes), alors c'est un indice important qu'il est temps de créer un paquet. Les paquetages sont très simples: déplacez vos fichiers dans node_modules/ et mettez-y un package.json. Voila! Tout cet espace de noms est accessible depuis votre projet entier. Les packages constituent le moyen approprié d’intégrer votre code dans un espace de noms global.

Autres solutions de contournement

Personnellement, je n’utilise pas ces techniques, mais elles répondent à votre question et, bien sûr, vous connaissez mieux que moi votre propre situation.

Vous pouvez définir $NODE_PATH à la racine de votre projet. Ce répertoire sera recherché lorsque vous aurez require().

Ensuite, vous pourriez compromettre et exiger un fichier local commun à tous vos exemples. Ce fichier commun réexporte simplement le vrai fichier dans le répertoire des grands-parents.

examples/downloads/app.js (et beaucoup d'autres comme ça)

var express = require('./express')

exemples/downloads/express.js

module.exports = require('../../')

Maintenant, lorsque vous déplacez ces fichiers, le pire des cas est de réparer le module shim.

37
JasonSmith

Regardez node-rfr .

C'est aussi simple que cela:

var rfr = require('rfr');
var myModule = rfr('projectSubDir/myModule');
19
warmsea

J'utilise process.cwd() dans mes projets. Par exemple:

var Foo = require(process.cwd() + '/common/foo.js');

Il peut être intéressant de noter que cela entraînera un require chemin absolu, bien que je n’aie pas encore rencontré de problèmes avec cela.

12
Walter Roman

En supposant que la racine de votre projet soit le répertoire de travail actuel, cela devrait fonctionner:

// require built-in path module
path = require('path');

// require file relative to current working directory
config = require( path.resolve('.','config.js') );
9
protometa

Il y a une bonne discussion sur cette question ici .

J'ai rencontré le même problème architectural: je voulais trouver un moyen de donner à mon application plus d'organisation et d'espaces de noms internes, sans:

  • mélanger des modules d'application avec des dépendances externes ou déranger avec des dépôts npm privés pour un code spécifique à l'application
  • utiliser des exigences relatives qui rendent plus difficile la refactorisation et la compréhension
  • utiliser des liens symboliques ou modifier le chemin du nœud, ce qui peut masquer les emplacements source et ne pas jouer correctement avec le contrôle de source

Finalement, j'ai décidé d'organiser mon code en utilisant des conventions de nommage de fichiers plutôt que des répertoires. Une structure ressemblerait à quelque chose comme:

  • npm-shrinkwrap.json
  • package.json
  • node_modules
    • ...
  • src
    • app.js
    • app.config.js
    • app.models.bar.js
    • app.models.foo.js
    • app.web.js
    • app.web.routes.js
    • ...

Puis dans le code:

var app_config = require('./app.config');
var app_models_foo = require('./app.models.foo');

ou juste

var config = require('./app.config');
var foo = require('./app.models.foo');

et des dépendances externes sont disponibles à partir de node_modules comme d'habitude:

var express = require('express');

De cette manière, tout le code de l'application est organisé hiérarchiquement en modules et disponible pour tous les autres codes relatifs à la racine de l'application.

Le principal inconvénient est bien sûr que dans un navigateur de fichiers, vous ne pouvez pas développer/réduire l’arbre comme s’il était réellement organisé en répertoires. Mais j'aime le fait que la provenance de tout le code soit très explicite et qu'il n'utilise pas de "magie".

9
indirectlylit

Si vous utilisez fil au lieu de npm , vous pouvez utiliser espaces de travail .

Disons que j'ai un dossier services que je souhaite demander plus facilement:

.
├── app.js
├── node_modules
├── test
├── services
│   ├── foo
│   └── bar
└── package.json

Pour créer un espace de travail Fil, créez un fichier package.json à l'intérieur du services folder:

{
  "name": "myservices",
  "version": "1.0.0"
}

Dans votre package.json principal, ajoutez:

"private": true,
"workspaces": ["myservices"]

Exécutez yarn install à partir de la racine du projet.

Ensuite, n'importe où dans votre code, vous pouvez faire:

const { myFunc } = require('myservices/foo')

au lieu de quelque chose comme:

const { myFunc } = require('../../../../../../services/foo')
8
cyberwombat

Certaines réponses disent que le meilleur moyen est d’ajouter le code au noeud_module en tant que paquet, je suis d’accord et c’est probablement le meilleur moyen de perdre le ../../../ requis, mais aucun d’entre eux ne donne réellement le moyen de le faire. alors.

à partir de la version 2.0.0, vous pouvez installer un package à partir de fichiers locaux, ce qui signifie que vous pouvez créer un dossier à la racine avec tous les packages souhaités,

-modules
 --foo
 --bar 
-app.js
-package.json

ainsi, dans package.json, vous pouvez ajouter le modules (ou foo et bar) sous forme de package sans publication ni utilisation de serveur externe, comme ceci:

{
  "name": "baz",
  "dependencies": {
    "bar": "file: ./modules/bar",
    "foo": "file: ./modules/foo"
  }
}

Après cela, vous faites npm install, et vous pouvez accéder au code avec var foo = require("foo"), comme vous le faites avec tous les autres packages.

plus d'informations peuvent être trouvées ici:

https://docs.npmjs.com/files/package.json#local-paths

et ici comment créer un paquet:

https://docs.npmjs.com/getting-started/creating-node-modules

7
Yan Mayatskiy

Vous pouvez utiliser un module que j'ai créé, ndot . Il n’ya rien d’avancé, juste une aide qui vous permet d’éviter ces enfers avec simplicité.

Exemple:

var undot = require('undot');
var User = undot('models/user');
var config = undot('config');
var test = undot('test/api/user/auth');
7
Castor

Vous pouvez définir quelque chose comme ceci dans votre app.js:

requireFromRoot = (function(root) {
    return function(resource) {
        return require(root+"/"+resource);
    }
})(__dirname);

et puis chaque fois que vous voulez demander quelque chose à la racine, peu importe où vous êtes, vous utilisez simplement requireFromRoot au lieu de l'exigence Vanilla. Cela fonctionne assez bien pour moi jusqu'à présent.

6
user1417684

J'ai essayé plusieurs de ces solutions. J'ai fini par l'ajouter en haut de mon fichier principal (par exemple, index.js):

process.env.NODE_PATH = __dirname;
require('module').Module._initPaths();

Cela ajoute la racine du projet à NODE_PATH lorsque le script est chargé. Cela me permet d'exiger n'importe quel fichier de mon projet en référençant son chemin relatif depuis la racine du projet, tel que var User = require('models/user'). Cette solution devrait fonctionner tant que vous exécutez un script principal à la racine du projet avant d'exécuter quoi que ce soit d'autre dans votre projet.

6
senornestor

Le moyen le plus simple d'y parvenir consiste à créer un lien symbolique au démarrage de l'application sur node_modules/app (ou peu importe comment vous l'appelez), qui pointe vers ../app. Ensuite, vous pouvez simplement appeler require("app/my/module"). Les liens symboliques sont disponibles sur toutes les principales plates-formes.

Cependant, vous devez toujours diviser votre contenu en modules plus petits et maintenables, installés via npm. Vous pouvez également installer vos modules privés via git-url, il n’ya donc aucune raison d’avoir un seul répertoire app monolithique.

5
Johannes Ewald

Dans votre propre projet, vous pouvez modifier tout fichier .js utilisé dans le répertoire racine et ajouter son chemin d'accès à une propriété de la variable process.env. Par exemple:

// in index.js
process.env.root = __dirname;

Ensuite, vous pouvez accéder à la propriété partout:

// in app.js
express = require(process.env.root);
4
AtraCaelus

Ce que j’aime faire, c’est d’exploiter la façon dont les nœuds se chargent à partir du répertoire node_module.

Si on essaye de charger le module "chose", on ferait quelque chose comme

require('thing');

Le noeud recherchera alors le répertoire 'chose' dans le répertoire 'noeud_module'.

Puisque le noeud_module est normalement à la racine du projet, nous pouvons tirer parti de cette cohérence. (Si node_module n'est pas à la racine, vous devez gérer d'autres maux de tête auto-induits.)

Si nous allons dans le répertoire et que nous en sortons, nous pouvons obtenir un chemin cohérent vers la racine du projet de noeud.

require('thing/../../');

Ensuite, si nous voulons accéder au répertoire/happy, nous le ferons.

require('thing/../../happy');

Bien que ce soit un peu hacky, cependant, je pense que si la fonctionnalité de la charge de node_modules change, il y aura de plus gros problèmes à résoudre. Ce comportement devrait rester cohérent.

Pour clarifier les choses, je le fais parce que le nom du module n'a pas d'importance.

require('root/../../happy');

Je l'ai utilisé récemment pour angular2. Je veux charger un service à partir de la racine.

import {MyService} from 'root/../../app/services/http/my.service';
3
justonpoints

Une autre réponse:

Imaginez cette structure de dossiers:

  • node_modules
    • lodash
  • src
    • subdir
      • foo.js
      • bar.js
    • main.js
  • teste

    • test.js

Ensuite, dans test.js , vous devez exiger des fichiers comme celui-ci:

const foo = require("../src/subdir/foo");
const bar = require("../src/subdir/bar");
const main = require("../src/main");
const _ = require("lodash");

et dans main.js :

const foo = require("./subdir/foo");
const bar = require("./subdir/bar");
const _ = require("lodash");

Maintenant, vous pouvez utiliser babel et le babel-plugin-module-resolver avec cela. babelrc fichier pour configurer 2 dossiers racine:

{
    "plugins": [
        ["module-resolver", {
            "root": ["./src", "./src/subdir"]
        }]
    ]
}

Maintenant, vous pouvez exiger des fichiers de la même manière dans tests et dans src :

const foo = require("foo");
const bar = require("bar");
const main = require("main");
const _ = require("lodash");

et si vous voulez utiliser la syntaxe du module es6 :

{
    "plugins": [
        ["module-resolver", {
            "root": ["./src", "./src/subdir"]
        }],
        "transform-es2015-modules-commonjs"
    ]
}

alors vous importez des fichiers dans des tests et src comme ceci:

import foo from "foo"
import bar from "bar"
import _ from "lodash"
3
Troopers

Le répertoire examples ne pourrait-il pas contenir un node_modules avec un lien symbolique à la racine du projet project -> ../../, permettant ainsi aux exemples d'utiliser require('project'), bien que cela ne supprime pas le mappage, il permet à la source d'utiliser require('project') plutôt que require('../../').

J'ai testé cela et ça marche avec la v0.6.18.

Liste du répertoire project:

$ ls -lR project
project:
drwxr-xr-x 3 user user 4096 2012-06-02 03:51 examples
-rw-r--r-- 1 user user   49 2012-06-02 03:51 index.js

project/examples:
drwxr-xr-x 2 user user 4096 2012-06-02 03:50 node_modules
-rw-r--r-- 1 user user   20 2012-06-02 03:51 test.js

project/examples/node_modules:
lrwxrwxrwx 1 user user 6 2012-06-02 03:50 project -> ../../

Le contenu de index.js attribue une valeur à une propriété de l'objet exports et appelle console.log avec un message indiquant qu'il était requis. Le contenu de test.js est require('project').

3
Dan D.

J'ai écrit ce petit paquet qui vous permet d'exiger des paquets par leur chemin relatif depuis la racine du projet, sans introduire de variables globales ni remplacer les valeurs par défaut des noeuds

https://github.com/Gaafar/pkg-require

Ça marche comme ça

// create an instance that will find the nearest parent dir containing package.json from your __dirname
const pkgRequire = require('pkg-require')(__dirname);

// require a file relative to the your package.json directory 
const foo = pkgRequire('foo/foo')

// get the absolute path for a file
const absolutePathToFoo = pkgRequire.resolve('foo/foo')

// get the absolute path to your root directory
const packageRootPath = pkgRequire.root()
2
Gaafar

Si quelqu'un cherche encore un autre moyen de résoudre ce problème, voici ma propre contribution à l'effort:

https://www.npmjs.com/package/use-import

L'idée de base: vous créez un fichier JSON à la racine du projet qui mappe vos chemins de fichiers sur des noms abrégés (ou obtenez se-automapper pour le faire à votre place). Vous pouvez ensuite demander à vos fichiers/modules en utilisant ces noms. Ainsi:

var use = require('use-import');
var MyClass = use('MyClass');

Donc, il y a ça.

2
Jon Stout

Si le fichier js du point d'entrée de votre application (c'est-à-dire celui sur lequel vous exécutez réellement "noeud") se trouve dans le répertoire racine de votre projet, vous pouvez le faire très facilement avec le module module rootpath npm . Il suffit de l'installer via

npm install --save rootpath

... puis tout en haut du fichier js du point d’entrée, ajoutez:

require('rootpath')();

À partir de ce moment, tous les appels requis sont désormais relatifs à la racine du projet - par exemple. require('../../../config/debugging/log'); devient require('config/debugging/log'); (où se trouve le dossier de configuration dans la racine du projet).

1
Andrew Faulkner

Je viens de trouver cet article qui mentionne app-module-path . Cela vous permet de configurer une base comme celle-ci:

require('app-module-path').addPath(baseDir);
1
Ole

En lignes simples, vous pouvez appeler votre propre dossier en tant que module:

Pour cela nous avons besoin de: module global et app-module-path

ici "App-module-path" est le module, il vous permet d'ajouter des répertoires supplémentaires au chemin de recherche du module Node.js. Et "global" signifie que tout ce que vous attachez à cet objet sera disponible partout dans votre application.

Maintenant, jetez un coup d'oeil à cet extrait:

global.appBasePath = __dirname;

require('app-module-path').addPath(appBasePath);

__dirname est le répertoire courant du noeud. Vous pouvez donner votre propre chemin ici pour rechercher le chemin du module.

1
Trojan

Nous sommes sur le point d'essayer une nouvelle façon de résoudre ce problème.

En prenant des exemples d'autres projets connus comme spring et guice, nous définirons un objet "context" qui contiendra toute l'instruction "require".

Cet objet sera ensuite transmis à tous les autres modules pour utilisation.

Par exemple

var context = {}

context.module1 = require("./module1")( { "context" : context } )
context.module2 = require("./module2")( { "context" : context } )

Cela nous oblige à écrire chaque module comme une fonction qui reçoit les options, ce qui nous semble de toute façon une meilleure pratique.

module.exports = function(context){ ... }

et ensuite vous ferez référence au contexte au lieu d’exiger des choses.

var module1Ref = context.moduel1;

Si vous le souhaitez, vous pouvez facilement écrire une boucle pour effectuer les instructions require

var context = {};
var beans = {"module1" : "./module1","module2" : "./module2" }; 
for ( var i in beans ){
    if ( beans.hasOwnProperty(i)){
         context[i] = require(beans[i])(context);
    }
};

Cela devrait vous faciliter la tâche lorsque vous voulez vous moquer (tests) et également résoudre votre problème en cours de route tout en rendant votre code réutilisable sous forme de package.

Vous pouvez également réutiliser le code d'initialisation du contexte en séparant la déclaration de beans. par exemple, votre fichier main.js pourrait ressembler à

var beans = { ... }; // like before
var context = require("context")(beans); // this example assumes context is a node_module since it is reused.. 

Cette méthode s'applique également aux bibliothèques externes. Nul besoin de coder en dur leurs noms à chaque fois que nous en avons besoin. Toutefois, un traitement spécial sera nécessaire, car leurs exportations ne sont pas des fonctions qui attendent un contexte.

Plus tard, nous pouvons également définir les beans comme des fonctions - ce qui nous permettra de require différents modules en fonction de l'environnement - mais en dehors du champ d'application de ce fil.

1
guy mograbi

J'avais des problèmes avec ce même problème, alors j'ai écrit un paquet appelé include .

Include se charge de déterminer le dossier racine de votre projet en localisant votre fichier package.json, puis passe l'argument de chemin que vous lui donnez à require () natif sans tout le désordre relatif du chemin relatif. J'imagine que ce n'est pas un remplacement de require (), mais un outil permettant de gérer des fichiers ou des bibliothèques non empaquetés/non tiers. Quelque chose comme

var async = require('async'),
    foo   = include('lib/path/to/foo')

J'espère que cela peut être utile.

1
Anthony Nichols

j'ai créé un module de noeud appelé "rekiure"

il vous permet d'exiger sans l'utilisation de chemins relatifs

https://npmjs.org/package/rekuire

c'est super facile à utiliser

1
Nadav Leshem

Je veux juste faire un suivi sur les excellente réponse de Paolo Moretti et Browserify. Si vous utilisez un transpiler (par exemple, Babel, TypeScript) et que vous avez des dossiers distincts pour le code source et le code transpilé, tels que src/ et dist/, vous pouvez utiliser une variante des solutions:

node_modules

Avec la structure de répertoire suivante:

app
  node_modules
    ... // normal npm dependencies for app
  src
    node_modules
      app
        ... // source code
  dist
    node_modules
      app
        ... // transpiled code

vous pouvez ensuite laisser babel etc transpiler le répertoire src dans le répertoire dist.

lien symbolique

En utilisant un lien symbolique, nous pouvons éliminer certains niveaux d’imbrication:

app
  node_modules
    ... // normal npm dependencies for app
  src
    node_modules
      app // symlinks to '..'
    ... // source code
  dist
    node_modules
      app // symlinks to '..'
    ... // transpiled code

Avertissement concernant babel --copy-files Le drapeau --copy-files de babel ne traite pas bien les liens symboliques. Il peut continuer à naviguer dans le lien symbolique .. et à voir de manière récusale des fichiers sans fin. Une solution de contournement consiste à utiliser la structure de répertoire suivante:

app
  node_modules
    app // symlink to '../src'
    ... // normal npm dependencies for app
  src
    ... // source code
  dist
    node_modules
      app // symlinks to '..'
    ... // transpiled code

De cette façon, le code sous src aura toujours app résolu en src, alors que Babel ne verrait plus les liens symboliques.

1
user716468

Bien que ces réponses fonctionnent , elles ne résolvent pas le problème du test npm

Si, par exemple, je crée une variable globale dans server.js, elle ne sera pas définie pour l'exécution de ma suite de tests.

Pour définir une variable globale appRoot qui évitera le problème ../../../ et sera disponible dans les tests npm start AND npm, voir:

tests Mocha avec options ou paramètres supplémentaires

Notez qu'il s'agit de la nouvelle solution officielle de moka .

0
danday74

Il y a quelque temps, j'ai créé un module pour charger des modules par rapport à des chemins prédéfinis.

https://github.com/raaymax/irequire

Vous pouvez l'utiliser au lieu d'exiger.

irequire.prefix('controllers',join.path(__dirname,'app/master'));
var adminUsersCtrl = irequire("controllers:admin/users");
var net = irequire('net');

Peut-être que ce sera utile pour quelqu'un ..

0
Mateusz Russak

Essayez d'utiliser asapp:

npm install --save asapp

https://www.npmjs.com/package/asapp

var { controller, helper, middleware, route, schema, model, APP, ROOT } = require('asapp')

controller('home') à la place require('../../controllers/home)

0
uruapanmexicansong

Si vous utilisez la syntaxe ES5, vous pouvez utiliser asapp . Pour ES6, vous pouvez utiliser babel-plugin-module-resolver en utilisant un fichier de configuration comme celui-ci:

.babelrc

{
  "plugins": [
    ["module-resolver", {
      "root": ["./"],
      "alias": {
        "app": "./app",
        "config": "./app/config",
        "schema": "./app/db/schemas",
        "model": "./app/db/models",
        "controller": "./app/http/controllers",
        "middleware": "./app/http/middleware",
        "route": "./app/http/routes",
        "locale": "./app/locales",
        "log": "./app/logs",
        "library": "./app/utilities/libraries",
        "helper": "./app/utilities/helpers",
        "view": "./app/views"
      }
    }]
  ]
}
0
uruapanmexicansong