¿Cómo incluir scripts ubicados dentro de la carpeta node_modules?

Tengo una pregunta sobre las mejores prácticas para incluir node_modules en un sitio web HTML.

Imagina que tengo Bootstrap dentro de mi carpeta node_modules. Ahora, para la versión de producción del sitio web, ¿cómo puedo incluir el script de Bootstrap y los archivos CSS ubicados dentro de la carpeta node_modules? ¿Tiene sentido dejar Bootstrap dentro de esa carpeta y hacer algo como lo siguiente?

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

¿O tendría que añadir reglas a mi archivo gulp que luego copiar esos archivos en mi carpeta dist? ¿O sería mejor dejar que gulp de alguna manera elimine completamente el bootstrap local de mi archivo HTML y lo reemplace con la versión CDN?

Solución

Normalmente, usted no quiere exponer ninguna de sus rutas internas de cómo está estructurado su servidor al mundo exterior. Lo que puede hacer es crear una ruta estática /scripts en su servidor que obtenga sus ficheros de cualquier directorio en el que residan. Así, si sus archivos están en "./node_modules/bootstrap/dist/". Entonces, la etiqueta script en sus páginas sólo se parece a esto:

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

Si estabas usando express con nodejs, una ruta estática es tan simple como esto:

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

Entonces, cualquier petición del navegador desde /scripts/xxx.js será automáticamente obtenida de tu directorio dist en __dirname + /node_modules/bootstrap/dist/xxx.js.

Nota: Las versiones más recientes de NPM poner más cosas en el nivel superior, no anidada tan profundamente por lo que si usted está usando una versión más reciente de NPM, a continuación, los nombres de ruta será diferente de lo indicado en la OP's pregunta y en la respuesta actual. Pero el concepto sigue siendo el mismo. Averigua dónde se encuentran físicamente los archivos en la unidad de disco de tu servidor y haz un app.use() con express.static() para hacer una pseudo-ruta a esos archivos de modo que no estés exponiendo la organización real del sistema de archivos del servidor al cliente.


Si no quiere hacer una ruta estática como esta, entonces probablemente sea mejor que copie los scripts públicos a una ruta que su servidor web trate como /scripts o cualquier otra designación de nivel superior que quiera usar. Normalmente, puedes hacer que esta copia forme parte de tu proceso de compilación/despliegue.


Si quieres hacer público sólo un fichero en particular en un directorio y no todo lo que se encuentra en ese directorio con él, entonces puedes crear manualmente rutas individuales para cada fichero en lugar de usar express.static() como:

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

Y el código para crear una ruta para que

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

O, si quieres seguir delineando rutas para scripts con /scripts, podrías hacer esto:

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

Y el código para crear una ruta para que

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

Yo usaría la ruta npm módulo y luego hacer algo como esto:

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

El directorio 'node_modules' puede no estar en el directorio actual, por lo que debe resolver la ruta dinámicamente.

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