¿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 distribución del sitio web (la versión en vivo), ¿cómo incluiría el script 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?

  

¿O tendría que agregar reglas a mi archivo gulp que luego copiar esos archivos en mi carpeta dist? ¿O sería mejor dejar que Gulp de algún modo elimine por completo el bootstrap local de mi archivo HTML y lo reemplace con la versión CDN?

Por lo general, no desea exponer ninguna de sus rutas internas de cómo su servidor está estructurado para el mundo exterior. Lo que sí puede hacer es crear una ruta estática /scripts en su servidor que obtenga sus archivos del directorio en el que residan. Por lo tanto, si sus archivos están en "./node_modules/bootstrap/dist/" . Entonces, la etiqueta de script en sus páginas se ve así:

  

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

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

Luego, todas las solicitudes de navegador de /scripts/xxx.js se /scripts/xxx.js automáticamente de su directorio dist .

Nota: Las versiones más recientes de NPM ponen más cosas en el nivel superior, no anidadas tan profundas, por lo que si está utilizando una versión más nueva de NPM, los nombres de las rutas serán diferentes a los indicados en la pregunta del OP y en la respuesta actual. Pero, el concepto sigue siendo el mismo. Averigua dónde se ubican físicamente los archivos en la unidad del servidor y app.use() una app.use() con express.static() para crear una pseudopaso a esos archivos para no exponer la organización del sistema de archivos del servidor real a el cliente.


Si no quiere hacer una ruta estática como esta, entonces probablemente sea mejor simplemente copiar las secuencias de comandos públicas a una ruta que su servidor web trate como /scripts o cualquier designación de nivel superior que quiera usar. Por lo general, puede hacer que esta copia sea parte de su proceso de comstackción / implementación.

Usaría el módulo path npm y luego haría algo como esto:

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

Como mencionó jfriend00, no debes exponer la estructura de tu servidor. Puede copiar los archivos de dependencia de su proyecto a algo así como public/scripts . Puedes hacer esto muy fácilmente con dep-linker como este:

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

El directorio ‘node_modules’ puede no estar en el directorio actual, por lo que debe resolver la ruta de forma dinámica.

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

Quiero actualizar esta pregunta con una solución más fácil. Crea un enlace simbólico a node_modules.

La forma más fácil de otorgar acceso público a node_modules es crear un enlace simbólico que apunte a sus node_modules desde dentro de su directorio público. El enlace simbólico hará que los archivos existan siempre que se cree el enlace.

Por ejemplo, si el servidor de nodos tiene código para servir archivos estáticos

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

y __dirname se refiere a / path / to / app para que sus archivos estáticos se publiquen desde / path / to / app / dist

y node_modules está en / path / to / app / node_modules, luego crea un enlace simbólico como este en mac / linux:

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

o como esto en Windows:

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

Ahora una solicitud de obtención para:

 node_modules/some/path 

recibirá una respuesta con el archivo en

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

que es realmente el archivo en

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

Si su directorio en / ruta / a / app / dist no es una ubicación segura, tal vez debido a la interferencia de un proceso de comstackción con gulp o gruñido, entonces puede agregar un directorio separado para el enlace y agregar una nueva llamada serveStatic como:

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

y en nodo agregar:

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

No encontré ninguna solución limpia (no quiero exponer el origen de todos mis node_modules) así que simplemente escribí un script de Powershell para copiarlos:

 $deps = "leaflet", "leaflet-search", "material-components-web" foreach ($dep in $deps) { Copy-Item "node_modules/$dep/dist" "static/$dep" -Recurse } 

Hice los cambios a continuación para incluir automáticamente los archivos en el índice html. De modo que cuando agregue un archivo en la carpeta, se extraerá automáticamente de la carpeta, sin tener que incluir el archivo en 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++) { %>  < % } %> 

En mi aplicación Angular 2, tengo esto en mi archivo Index.html:

   

Aquí está el archivo completo:

 < !DOCTYPE html>    TripMate - PPS                Loading...   

Si quieres una solución rápida y fácil (y tienes gulp instalado).

En mi gulpfile.js , ejecuto una sencilla tarea de copiar y pegar que coloca los archivos que pueda necesitar en el directorio ./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']); 

La desventaja de esto es que no está automatizado. Sin embargo, si todo lo que necesita son unos pocos scripts y estilos copiados (y guardados en una lista), esto debería hacer el trabajo.