node.js - proyecto - npm
¿Cómo incluir scripts ubicados dentro de la carpeta node_modules? (9)
Tengo una pregunta sobre las mejores prácticas para incluir
node_modules
en un sitio web HTML.
Imagine 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?
<script src="./node_modules/bootstrap/dist/bootstrap.min.js></script>
¿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 elimine por completo la rutina de arranque local de mi archivo HTML y reemplazarlo con la versión CDN?
Como mencionó jfriend00, no debe exponer la estructura de su servidor.
Puede copiar los archivos de dependencia de su proyecto en algo como
public/scripts
.
Puede 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 dinámicamente.
var bootstrap_dir = require.resolve(''bootstrap'')
.match(/.*//node_modules//[^/]+///)[0];
app.use(''/scripts'', express.static(bootstrap_dir + ''dist/''));
Esto es lo que configuré en mi servidor
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>
Buena suerte...
Hice los cambios a continuación para INCLUIR AUTOMÁTICAMENTE los archivos en el índice html. De modo que cuando agrega un archivo en la carpeta, se recogerá 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++) { %>
<script src="<%= jsfiles[i] %>"></script>
<% } %>
No encontré ninguna solución limpia (no quiero exponer la fuente 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
}
Por lo general, no desea exponer ninguna de sus rutas internas de cómo está estructurado su servidor al mundo exterior.
Lo que puede hacer es hacer una ruta estática
/scripts
en su servidor que recupere sus archivos de cualquier directorio en el que residan. Entonces, si sus archivos están en
"./node_modules/bootstrap/dist/"
.
Luego, la etiqueta del script en sus páginas se ve así:
<script src="/scripts/bootstrap.min.js"></script>
Si estaba utilizando express con nodejs, una ruta estática es tan simple como esta:
app.use(''/scripts'', express.static(__dirname + ''/node_modules/bootstrap/dist/''));
Luego, cualquier solicitud de navegador de
/scripts/xxx.js
obtendrá automáticamente de su directorio
dist
en
__dirname + /node_modules/bootstrap/dist/xxx.js
.
Nota: Las versiones más nuevas de NPM ponen más cosas en el nivel superior, no anidadas tan profundamente, por lo que si está utilizando una versión más nueva de NPM, los nombres de ruta 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 encuentran físicamente los archivos en la unidad del servidor y
app.use()
un
app.use()
con
express.static()
para hacer una seudo ruta a esos archivos para que no exponga la organización real del sistema de archivos del servidor a el cliente.
Si no desea hacer una ruta estática como esta, entonces probablemente sea mejor simplemente copiando los scripts públicos a una ruta que su servidor web trata como
/scripts
o cualquier designación de nivel superior que desee utilizar.
Por lo general, puede hacer que esta copia sea parte de su proceso de compilación / implementación.
Si desea hacer público solo un archivo en particular en un directorio y no todo lo que se encuentra en ese directorio, puede crear manualmente rutas individuales para cada archivo en lugar de usar
express.static()
como:
<script src="/bootstrap.min.js"></script>
Y el código para crear una ruta para eso
app.get(''/bootstrap.min.js'', function(req, res) {
res.sendFile(__dirname + ''/node_modules/bootstrap/dist/bootstrap.min.js'');
});
O, si aún desea delinear rutas para scripts con
/scripts
, puede hacer esto:
<script src="/scripts/bootstrap.min.js"></script>
Y el código para crear una ruta para eso
app.get(''/scripts/bootstrap.min.js'', function(req, res) {
res.sendFile(__dirname + ''/node_modules/bootstrap/dist/bootstrap.min.js'');
});
Quiero actualizar esta pregunta con una solución más fácil. Cree 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 su directorio público. El enlace simbólico hará que los archivos existan donde se cree el enlace.
Por ejemplo, si el servidor de nodo 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 sirvan desde / path / to / app / dist
y node_modules está en / path / to / app / node_modules, luego cree 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 de:
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 / path / to / app / dist no es una ubicación segura, tal vez debido a la interferencia de un proceso de compilación con gulp o gruñido, entonces podría 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 el nodo agregar:
app.use(serveStatic(path.join(__dirname, ''newDirectoryName'')));
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'')));
Si desea una solución rápida y fácil (y tiene un trago instalado).
En mi
gulpfile.js
ejecuto una tarea simple de copiar y pegar que coloca todos 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 algunos scripts y estilos copiados (y guardados en una lista), esto debería hacer el trabajo.