web-dev-qa-db-fra.com

Comment inclure des scripts situés dans le dossier node_modules?

J'ai une question concernant les meilleures pratiques pour inclure node_modules dans un site Web HTML.

Imaginez que j’ai Bootstrap dans mon dossier node_modules. Maintenant, pour la version de distribution du site Web (la version en direct), comment puis-je inclure le script Bootstrap et les fichiers CSS situés dans le dossier node_modules? Est-il judicieux de laisser Bootstrap à l'intérieur de ce dossier et de procéder de la manière suivante?

<script src="./node_modules/bootstrap/dist/bootstrap.min.js></script>

Ou devrais-je ajouter des règles à mon fichier gulp pour copier ensuite ces fichiers dans mon dossier dist? Ou serait-il préférable de laisser gulp supprimer complètement le bootstrap local _ de mon fichier HTML et le remplacer par la version CDN?

246
phpheini

En règle générale, vous ne souhaitez exposer aucun de vos chemins internes pour expliquer la structure de votre serveur au monde extérieur. Vous pouvez créer une route statique /scripts sur votre serveur, qui récupère ses fichiers dans le répertoire dans lequel ils se trouvent. Ainsi, si vos fichiers se trouvent dans "./node_modules/bootstrap/dist/". Ensuite, la balise de script dans vos pages ressemble à ceci:

<script src="/scripts/bootstrap.min.js"></script>

Si vous utilisiez express avec nodejs, une route statique est aussi simple que cela:

app.use('/scripts', express.static(__dirname + '/node_modules/bootstrap/dist/'));

Ensuite, toutes les demandes de navigateur de /scripts/xxx.js seront automatiquement extraites de votre répertoire dist dans __dirname + /node_modules/bootstrap/dist/xxx.js.

Remarque: Les versions plus récentes de NPM placent plus d'éléments au niveau supérieur, non imbriqué aussi profondément. Par conséquent, si vous utilisez une version plus récente de NPM, les noms de chemin d'accès seront différents de ceux indiqués dans la question du PO et dans la réponse actuelle. Mais, le concept est toujours le même. Vous découvrez où les fichiers sont physiquement situés sur votre lecteur de serveur et vous créez une app.use() avec express.static() pour créer un pseudo-chemin d'accès à ces fichiers, de manière à ne pas exposer l'organisation réelle du système de fichiers du serveur. le client.


Si vous ne souhaitez pas créer un itinéraire statique comme celui-ci, vous feriez probablement mieux de copier les scripts publics vers un chemin que votre serveur Web considère comme étant /scripts ou une désignation de niveau supérieur que vous souhaitez utiliser. . Généralement, vous pouvez inclure cette copie dans votre processus de génération/déploiement.


Si vous souhaitez rendre un seul fichier public dans un répertoire et ne pas utiliser tout ce qui se trouve dans ce répertoire, vous pouvez créer manuellement des itinéraires individuels pour chaque fichier plutôt que d'utiliser express.static(), tels que:

<script src="/bootstrap.min.js"></script>

Et le code pour créer un itinéraire pour cela

app.get('/bootstrap.min.js', function(req, res) {
    res.sendFile(__dirname + '/node_modules/bootstrap/dist/bootstrap.min.js');
});

Ou, si vous souhaitez toujours définir les itinéraires des scripts avec /scripts, vous pouvez procéder comme suit:

<script src="/scripts/bootstrap.min.js"></script>

Et le code pour créer un itinéraire pour cela

app.get('/scripts/bootstrap.min.js', function(req, res) {
    res.sendFile(__dirname + '/node_modules/bootstrap/dist/bootstrap.min.js');
});
268
jfriend00

Je voudrais utiliser le module de chemin npm et puis faire quelque chose comme ceci:

var path = require('path');
app.use('/scripts', express.static(path.join(__dirname, 'node_modules/bootstrap/dist')));
17
Alexander Egorov

Comme mentionné par jfriend00, vous ne devez pas exposer la structure de votre serveur. Vous pouvez copier les fichiers de dépendance de votre projet dans quelque chose comme public/scripts. Vous pouvez faire ceci très facilement avec dep-linker comme ceci:

var DepLinker = require('dep-linker');
DepLinker.copyDependenciesTo('./public/scripts')
// Done
8
Marcelo Lazaroni

Le répertoire 'node_modules' peut ne pas être dans le répertoire actuel, vous devez donc résoudre le chemin de manière dynamique.

var bootstrap_dir = require.resolve('bootstrap')
                           .match(/.*\/node_modules\/[^/]+\//)[0];
app.use('/scripts', express.static(bootstrap_dir + 'dist/'));
6
Jake

Si vous voulez une solution rapide et facile (et que vous avez installé gulp).

Dans mon gulpfile.js, j'exécute une tâche de copier-coller simple qui place tous les fichiers nécessaires dans le répertoire ./public/modules/.

gulp.task('modules', function() {
    sources = [
      './node_modules/prismjs/prism.js',
      './node_modules/prismjs/themes/prism-dark.css',
    ]
    gulp.src( sources ).pipe(gulp.dest('./public/modules/'));
});

gulp.task('copy-modules', ['modules']);

L'inconvénient, c'est que ce n'est pas automatisé. Cependant, si vous avez juste besoin de quelques scripts et styles copiés (et conservés dans une liste), cela devrait faire l'affaire.

4
Jesse

Je n'ai trouvé aucune solution propre (je ne veux pas exposer la source de tous mes nœuds_modules), alors je viens d'écrire un script Powershell pour les copier:

$deps = "leaflet", "leaflet-search", "material-components-web"

foreach ($dep in $deps) {
    Copy-Item "node_modules/$dep/dist" "static/$dep" -Recurse
}
3
Timmmm

Je veux mettre à jour cette question avec une solution plus facile. Créez un lien symbolique vers node_modules.

Le moyen le plus simple d’accorder un accès public à node_modules est de créer un lien symbolique pointant sur vos node_modules à partir de votre répertoire public. Le lien symbolique sera comme si les fichiers existaient partout où le lien était créé.

Par exemple, si le serveur de noeud a du code pour servir des fichiers statiques

app.use(serveStatic(path.join(__dirname, 'dist')));

et __dirname fait référence à/path/to/app pour que vos fichiers statiques soient servis depuis/path/to/app/dist

et node_modules est dans/path/to/app/node_modules, puis créez un lien symbolique comme celui-ci sur mac/linux:

ln -s /path/to/app/node_modules /path/to/app/dist/node_modules

ou comme ceci sur windows:

mklink /path/to/app/node_modules /path/to/app/dist/node_modules

Maintenant une demande de get pour:

node_modules/some/path 

recevra une réponse avec le fichier à

/path/to/app/dist/node_modules/some/path 

qui est vraiment le fichier à

/path/to/app/node_modules/some/path

Si votre répertoire dans/path/to/app/dist n'est pas un emplacement sûr, peut-être à cause d'interférences d'un processus de construction avec gulp ou grunt, vous pouvez ajouter un répertoire distinct pour le lien et ajouter un nouvel appel serveStatic, tel que:

ln -s /path/to/app/node_modules /path/to/app/newDirectoryName/node_modules

et dans le noeud ajouter:

app.use(serveStatic(path.join(__dirname, 'newDirectoryName')));
3
curtwphillips

J'ai fait les modifications ci-dessous à AUTO-INCLUDE les fichiers dans l'index html. Ainsi, lorsque vous ajoutez un fichier dans le dossier, celui-ci est automatiquement sélectionné dans le dossier, sans que vous ayez à l'inclure dans index.html.

//// THIS WORKS FOR ME 
///// in app.js or server.js

var app = express();

app.use("/", express.static(__dirname));
var fs = require("fs"),

function getFiles (dir, files_){
    files_ = files_ || [];
    var files = fs.readdirSync(dir);
    for (var i in files){
        var name = dir + '/' + files[i];
        if (fs.statSync(name).isDirectory()){
            getFiles(name, files_);
        } else {
            files_.Push(name);
        }
    }
    return files_;
}
//// send the files in js folder as variable/array 
ejs = require('ejs');

res.render('index', {
    'something':'something'...........
    jsfiles: jsfiles,
});

///--------------------------------------------------

///////// in views/index.ejs --- the below code will list the files in index.ejs

<% for(var i=0; i < jsfiles.length; i++) { %>
   <script src="<%= jsfiles[i] %>"></script>
<% } %>
1
SuperNova

C’est ce que j’ai configuré sur mon serveur express:

// app.js
const path = require('path');
const express = require('express');
const expressApp  = express();
const nm_dependencies = ['bootstrap', 'jquery', 'popper.js']; // keep adding required node_modules to this array.
nm_dependencies.forEach(dep => {
  expressApp.use(`/${dep}`, express.static(path.resolve(`node_modules/${dep}`)));
});

<!-- somewhere inside head tag -->
<link rel="stylesheet" href="bootstrap/dist/css/bootstrap.css" />

<!-- somewhere near ending body tag -->
<script src="jquery/dist/jquery.js" charset="utf-8"></script>
<script src="popper.js/dist/popper.js" charset="utf-8"></script>
<script src="bootstrap/dist/js/bootstrap.js" charset="utf-8"></script>

Bonne chance...

0
Akash