Je voudrais exiger 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 ligne 6, vous verrez
express = require('../../')
C'est vraiment mauvais OMI. Imaginez que je souhaite rapprocher tous mes exemples de la racine d'un seul 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 root: si une chaîne commence par un $ alors elle est relative au dossier racine du projet.
Toute aide est la bienvenue, merci
Update 2
Maintenant, j'utilise require.js qui vous permet d'écrire dans un sens et fonctionne à la fois sur le client et 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/
Réponses:
Et à propos de:
Il nécessite le fichier comme s'il était requis à partir du fichier js principal, donc cela fonctionne assez bien tant que votre fichier js principal est à la racine de votre projet ... et c'est quelque chose que j'apprécie.
la source
Il y a une section vraiment intéressante dans le manuel Browserify :
la source
node_modules
dossier est qu'il rend plus difficile lerm -rf node_modules
dossier nuke ( )git clean
syntaxe, on peut toujoursrm -rf node_modules && git checkout node_modules
- assurez-vous augit stash
cas où il y aurait des changements dans lesnode_modules
sous - répertoires.J'aime créer un nouveau
node_modules
dossier pour le code partagé, puis laisser le nœud et exiger faire ce qu'il fait le mieux.par exemple:
Par exemple, si vous y êtes,
car/index.js
vous le pouvezrequire('helper')
et le nœud le trouvera!Fonctionnement de node_modules
Le nœud possède un algorithme intelligent pour résoudre les modules qui est unique parmi les plates-formes rivales.
Si vous venez
require('./foo.js')
de/beep/boop/bar.js
, node cherchera./foo.js
dans/beep/boop/foo.js
. Les chemins commençant par./
ou../
sont toujours locaux vers le fichier qui appellerequire()
.Si toutefois vous avez besoin d'un nom non relatif tel que
require('xyz')
from/beep/boop/foo.js
, le nœud recherche ces chemins dans l'ordre, s'arrêtant à la première correspondance et générant une erreur si rien n'est trouvé:Pour chaque
xyz
répertoire existant, le nœud recherchera d'abord unxyz/package.json
pour voir si un"main"
champ existe. Le"main"
champ définit quel fichier doit prendre en charge si vousrequire()
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:alors les exportations de
/beep/node_modules/xyz/lib/abc.js
seront retournées parrequire('xyz')
.S'il n'y a pas
package.json
ou pas de"main"
champ,index.js
on suppose:la source
La grande image
Cela semble "vraiment mauvais" mais donnez-lui du temps. C'est, en fait, vraiment bon. Les explicites
require()
donnent une transparence totale et une facilité de compréhension qui est comme une bouffée d'air frais pendant le cycle de vie d'un projet.Pensez-y de cette façon: vous lisez un exemple, trempez vos orteils dans Node.js et vous avez décidé que c'était "vraiment mauvais IMO". Vous êtes les leaders de la communauté Node.js, ceux qui ont passé plus d'heures à écrire et à maintenir des applications Node.js que quiconque. Quelle est la chance que l'auteur ait fait une telle erreur de débutant? (Et je suis d'accord, de mon expérience Ruby et Python, cela semble d'abord comme un désastre.)
Il y a beaucoup de battage médiatique et de contre-battage publicitaire autour de Node.js. Mais lorsque la poussière retombera, nous reconnaîtrons que les modules explicites et les packages «local first» ont été un moteur majeur de l'adoption.
Le cas commun
Bien sûr, à
node_modules
partir du répertoire actuel, la recherche du parent, puis des grands-parents, des arrière-grands-parents, etc. Les packages que vous avez installés fonctionnent donc déjà de cette façon. Habituellement, vous pouvez le fairerequire("express")
n'importe où dans votre projet et cela fonctionne bien.Si vous vous trouvez en train de charger des fichiers communs à partir de la racine de votre projet (peut-être parce que ce sont des fonctions utilitaires communes), c'est un indice important qu'il est temps de créer un package. Les packages sont très simples: déplacez vos fichiers dans
node_modules/
et mettez-package.json
y un . Voila! Tout dans cet espace de noms est accessible à partir de l'ensemble de votre projet. Les packages sont la bonne façon de placer 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 votre situation que moi.
Vous pouvez définir
$NODE_PATH
la racine de votre projet. Ce répertoire sera recherché lorsque vousrequire()
.Ensuite, vous pourriez compromettre et exiger un fichier local commun de tous vos exemples. Ce fichier commun réexporte simplement le vrai fichier dans le répertoire des grands-parents.
exemples / téléchargements / app.js (et beaucoup d'autres comme ça)
exemples / téléchargements / express.js
Maintenant, lorsque vous déplacez ces fichiers, le pire des cas est de réparer le module à une seule cale .
la source
Jetez un œil à node-rfr .
C'est aussi simple que ça:
la source
Si vous utilisez du fil au lieu de npm, vous pouvez utiliser des espaces de travail .
Disons que j'ai un dossier dont
services
je souhaite avoir plus facilement besoin:Pour créer un espace de travail Yarn, créez un
package.json
fichier dansservices folder
:Dans votre package.json principal, ajoutez:
Exécutez à
yarn install
partir de la racine du projet.Ensuite, n'importe où dans votre code, vous pouvez faire:
au lieu de quelque chose comme:
la source
À mon humble avis, la façon la plus simple est de définir votre propre fonction en tant que partie d'un
GLOBAL
objet. CréezprojRequire.js
à la racine de votre projet avec le contenu suivant:Dans votre fichier principal avant
require
tout module spécifique au projet:Après cela, cela fonctionne pour moi:
@Totty, j'ai trouvé une autre solution, qui pourrait fonctionner pour le cas que vous avez décrit dans les commentaires. La description va être
tl;dr
, donc je ferais mieux de montrer une image avec la structure de mon projet de test .la source
prj/some
deprj/other
(vient d'être testérequire('prj/some'
). Tous les modules communs de votre application peuvent y aller (par exemple, la couche de base de données). Ne fera aucune différence là où, disons, selib
trouve. Essayez de voir si cela convient.J'utilise
process.cwd()
dans mes projets. Par exemple:Il convient peut-être de noter que cela entraînera
require
un chemin absolu, même si je n'ai pas encore rencontré de problèmes avec cela.la source
Il y a une bonne discussion de cette question ici .
Je suis tombé sur le même problème architectural: vouloir un moyen de donner à mon application plus d'organisation et d'espaces de noms internes, sans:
À la fin, j'ai décidé d'organiser mon code en utilisant des conventions de dénomination de fichiers plutôt que des répertoires. Une structure ressemblerait à quelque chose comme:
Puis en code:
ou juste
et les dépendances externes sont disponibles à partir de node_modules comme d'habitude:
De cette façon, tout le code d'application est hiérarchiquement organisé en modules et disponible pour tout autre code relatif à 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'arborescence comme si elle était réellement organisée en répertoires. Mais j'aime que cela soit très explicite sur la provenance de tout le code, et qu'il n'utilise aucune «magie».
la source
../x/x
qui est déjà lisible.En supposant que la racine de votre projet est le répertoire de travail actuel, cela devrait fonctionner:
la source
config = require('./config.js');
est également valable.J'ai essayé plusieurs de ces solutions. J'ai fini par ajouter ceci en haut de mon fichier principal (par exemple index.js):
Cela ajoute la racine du projet à NODE_PATH lorsque le script est chargé. Le me permet d'exiger n'importe quel fichier dans mon projet en référençant son chemin relatif à partir de la racine du projet tel que
var User = require('models/user')
. Cette solution devrait fonctionner tant que vous exécutez un script principal dans la racine du projet avant d'exécuter quoi que ce soit d'autre dans votre projet.la source
Certaines des réponses disent que la meilleure façon est d'ajouter le code au node_module en tant que package, je suis d'accord et c'est probablement la meilleure façon de perdre le
../../../
in require mais aucun d'entre eux ne donne réellement un moyen de le faire.à 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 dans votre racine avec tous les packages que vous souhaitez,donc dans package.json, vous pouvez ajouter le
modules
(oufoo
etbar
) en tant que package sans publier ni utiliser de serveur externe comme ceci:Après cela
npm install
, vous pouvez accéder au code avecvar 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 voici comment créer un package:
https://docs.npmjs.com/getting-started/creating-node-modules
la source
Vous pouvez utiliser un module que j'ai créé, Undot . Ce n'est rien de avancé, juste une aide pour éviter ces enfers de points avec simplicité.
Exemple:
la source
Vous pouvez définir quelque chose comme ça dans votre app.js:
puis à chaque fois que vous souhaitez exiger quelque chose de la racine, peu importe où vous êtes, vous utilisez simplement requireFromRoot au lieu de vanilla require. Fonctionne assez bien pour moi jusqu'à présent.
la source
requireFromRoot = ((root) => (resource) => require(`${root}/${resource}`))(__dirname);
. J'adore la solution, mais devez-vous vraiment lier __dirname comme ça?require
cette fonction?Voici la façon dont je fais depuis plus de 6 mois. J'utilise un dossier nommé node_modules comme dossier racine dans le projet, de cette façon, il recherchera toujours ce dossier partout où j'appelle un besoin absolu:
Ceci est plus utile lorsque vous êtes imbriqué dans des dossiers et qu'il est beaucoup moins fastidieux de modifier l'emplacement d'un fichier s'il est défini de manière absolue. J'utilise seulement 2 le parent requis dans toute mon application .
la source
node_modules
dans/src
, et laisser/node_modules
aux fournisseurs de garder les choses séparées. J'ai donc/src/node_modules
pour le code local et/node_modules
pour les fournisseurs.NODE_PATH
variable d'environnementÀ mon humble avis, la façon la plus simple d'y parvenir est de créer un lien symbolique au démarrage de l'application
node_modules/app
(ou comme vous l'appelez) qui pointe vers../app
. Ensuite, vous pouvez simplement appelerrequire("app/my/module")
. Des liens symboliques sont disponibles sur toutes les principales plateformes.Cependant, vous devez toujours diviser votre contenu en modules plus petits et maintenables qui sont installés via npm. Vous pouvez également installer vos modules privés via git-url, il n'y a donc aucune raison d'en avoir un, un répertoire d'application monolithique.
la source
Dans votre propre projet, vous pouvez modifier n'importe quel fichier .js utilisé dans le répertoire racine et ajouter son chemin d'accès à une propriété de la
process.env
variable. Par exemple:Ensuite, vous pouvez accéder à la propriété partout:
la source
Une autre réponse:
Imaginez cette structure de dossiers:
tests
Ensuite, dans test.js , vous devez exiger des fichiers comme celui-ci:
et dans main.js :
Vous pouvez maintenant utiliser babel et le résolveur de module d'extension de babel avec cela. Fichier babelrc pour configurer 2 dossiers racine:
Maintenant, vous pouvez exiger des fichiers de la même manière dans les tests et dans src :
et si vous voulez utiliser la syntaxe du module es6 :
puis vous importez des fichiers dans des tests et src comme ceci:
la source
Je viens de découvrir cet article qui mentionne le chemin du module d'application . Il vous permet de configurer une base comme celle-ci:
la source
Le
examples
répertoire ne pourrait-il pas contenir unnode_modules
avec un lien symbolique vers la racine du projetproject -> ../../
permettant ainsi aux exemples d'utiliserrequire('project')
, bien que cela ne supprime pas le mappage, il permet à la source d'utiliserrequire('project')
plutôt querequire('../../')
.J'ai testé cela, et cela fonctionne avec la v0.6.18.
Liste du
project
répertoire:Le contenu de
index.js
affecte une valeur à une propriété de l'exports
objet et l'invoqueconsole.log
avec un message indiquant qu'elle était requise. Le contenu detest.js
isrequire('project')
.la source
require('project.a')
? Je pense que cela pourrait signifierrequire('project/a')
, bien que cerequire('project').a
soit également possible?node_modules
répertoire du parent le plus proche des deux fichiers et le lien serait alors le même pour les deux. Voir nodejs.org/api/…project/node_modules/project -> ../
.Si quelqu'un cherche encore un autre moyen de contourner ce problème, voici ma propre contribution à l'effort:
L'idée de base: vous créez un fichier JSON à la racine du projet qui mappe vos chemins de fichiers à des noms abrégés (ou demandez à use-automapper de le faire pour vous). Vous pouvez ensuite demander vos fichiers / modules en utilisant ces noms. Ainsi:
Il y a donc ça.
la source
Ce que j'aime faire, c'est tirer parti de la façon dont le nœud se charge à partir du répertoire node_module pour cela.
Si on essaie de charger le module "chose", on ferait quelque chose comme
Le nœud recherchera alors le répertoire 'thing' dans le répertoire 'node_module'.
Étant donné que le node_module est normalement à la racine du projet, nous pouvons tirer parti de cette cohérence. (Si node_module n'est pas à la racine, alors vous avez d'autres maux de tête auto-induits à gérer.)
Si nous allons dans le répertoire et que nous en ressortons, nous pouvons obtenir un chemin cohérent vers la racine du projet de noeud.
Ensuite, si nous voulons accéder au répertoire / happy, nous le ferions.
Bien que ce soit un peu hacky, cependant je pense que si la fonctionnalité de la façon dont charge les node_modules change, il y aura de plus gros problèmes à gérer. Ce comportement doit rester cohérent.
Pour clarifier les choses, je le fais, car le nom du module n'a pas d'importance.
Je l'ai utilisé récemment pour angular2. Je veux charger un service à partir de la racine.
la source
src/app/my.service
, vous pouvez également configurer VSC pour utiliser des importations non relatives pour les fichiers dactylographiés.J'ai écrit ce petit package qui vous permet d'exiger des packages par leur chemin relatif depuis la racine du projet, sans introduire de variables globales ni remplacer les valeurs par défaut des nœuds
https://github.com/Gaafar/pkg-require
Ça marche comme ça
la source
Je veux juste donner suite à l' excellente réponse de Paolo Moretti et de Browserify. Si vous utilisez un transpilateur (par exemple, babel, dactylographié) et que vous avez des dossiers séparés pour le code source et transpilé comme
src/
etdist/
, vous pouvez utiliser une variante des solutions commenode_modules
Avec la structure de répertoires suivante:
vous pouvez ensuite laisser babel etc transpiler le
src
répertoire versdist
répertoire.lien symbolique
En utilisant un lien symbolique, nous pouvons supprimer certains niveaux d'imbrication:
Une mise en garde avec babel --copy-files Le
--copy-files
drapeau debabel
ne gère pas bien les liens symboliques. Il peut continuer à naviguer dans le..
lien symbolique et à voir récurremment des fichiers sans fin. Une solution de contournement consiste à utiliser la structure de répertoires suivante:De cette façon, le code sous
src
seraapp
résolusrc
, alors que babel ne verra plus de liens symboliques.la source
Je cherchais exactement la même simplicité pour exiger des fichiers de n'importe quel niveau et j'ai trouvé un alias de module .
Installez simplement:
Ouvrez votre fichier package.json, ici vous pouvez ajouter des alias pour vos chemins, par exemple
Et utilisez vos alias simplement:
la source
j'ai créé un module de noeud appelé "rekiure"
il vous permet d'exiger sans utiliser de chemins relatifs
c'est super facile à utiliser
la source
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 toutes les instructions "require".
Cet objet sera ensuite transmis à tous les autres modules pour utilisation.
Par exemple
Cela nous oblige à écrire chaque module comme une fonction qui reçoit des opts, ce qui nous semble de toute façon une meilleure pratique.
puis vous vous référerez au contexte au lieu d'exiger des trucs.
var module1Ref = context.moduel1;
Si vous le souhaitez, vous pouvez facilement écrire une boucle pour faire les instructions require
Cela devrait vous faciliter la vie lorsque vous souhaitez vous moquer (tests) et résout également votre problème en cours de route tout en rendant votre code réutilisable en tant que package.
Vous pouvez également réutiliser le code d'initialisation du contexte en séparant la déclaration des beans. par exemple, votre
main.js
fichier pourrait ressembler àCette méthode s'applique également aux bibliothèques externes, pas besoin de coder en dur leurs noms à chaque fois que nous en avons besoin - cependant elle nécessitera un traitement spécial car leurs exportations ne sont pas des fonctions qui attendent du 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 cela hors de la portée de ce thread.la source
J'avais des problèmes avec ce même problème, j'ai donc écrit un package appelé include .
Incluez des poignées pour déterminer le dossier racine de votre projet en localisant votre fichier package.json, puis passez l'argument de chemin que vous lui donnez au require () natif sans tout le désordre de chemin relatif. J'imagine que ce n'est pas un remplacement de require (), mais un outil pour exiger la gestion de fichiers ou de bibliothèques non packagés / non tiers. Quelque chose comme
J'espère que cela peut être utile.
la source
Si le fichier js du point d'entrée de votre application (c'est-à-dire celui sur lequel vous exécutez réellement "node") se trouve dans le répertoire racine de votre projet, vous pouvez le faire très facilement avec le module rootpath npm . Installez-le simplement via
... puis tout en haut du fichier js du point d'entrée, ajoutez:
À partir de ce moment, tous les appels requis sont désormais relatifs à la racine du projet - par exemple
require('../../../config/debugging/log');
devientrequire('config/debugging/log');
(où le dossier de configuration se trouve à la racine du projet).la source
En termes simples, vous pouvez appeler votre propre dossier en tant que module:
Pour cela, nous avons besoin de: module global et module-app-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" est, tout ce que vous attachez à cet objet sera b disponible partout dans votre application.
Jetez maintenant un œil à cet extrait:
__dirname est le répertoire courant du nœud. Vous pouvez donner ici votre propre chemin pour rechercher le chemin du module.
la source