javascript - node - requirejs jquery
requiere una carpeta completa (5)
¿Es posible "requerir" una carpeta completa utilizando requireJS.
Por ejemplo, tengo una carpeta de comportamientos con un montón de archivos de comportamiento js. Realmente me gustaría poder simplemente usar require ([''behaviors / *''], function () {...}); para cargar todo en esa carpeta en lugar de tener que mantener esa lista actualizada. Una vez comprimidos y optimizados, tendría todos esos archivos agrupados, pero para el desarrollo es más fácil trabajar con ellos individualmente.
Escribí una biblioteca para resolver este problema. Finalmente, alguien más vino y mejoró mi biblioteca, aquí está:
https://github.com/smartprocure/directory-metagen
Puede usar mi lib con Gulp o lo que sea: genera metadatos para su proyecto y RequireJS puede usar esos metadatos para requerir los archivos deseados del sistema de archivos.
El uso de esta biblioteca producirá un módulo RequireJS que se verá así:
define(
[
"text!app/templates/dashboardTemplate.ejs",
"text!app/templates/fluxCartTemplate.ejs",
"text!app/templates/footerTemplate.ejs",
"text!app/templates/getAllTemplate.ejs",
"text!app/templates/headerTemplate.ejs",
"text!app/templates/homeTemplate.ejs",
"text!app/templates/indexTemplate.ejs",
"text!app/templates/jobsTemplate.ejs",
"text!app/templates/loginTemplate.ejs",
"text!app/templates/overviewTemplate.ejs",
"text!app/templates/pictureTemplate.ejs",
"text!app/templates/portalTemplate.ejs",
"text!app/templates/registeredUsersTemplate.ejs",
"text!app/templates/userProfileTemplate.ejs"
],
function(){
return {
"templates/dashboardTemplate.ejs": arguments[0],
"templates/fluxCartTemplate.ejs": arguments[1],
"templates/footerTemplate.ejs": arguments[2],
"templates/getAllTemplate.ejs": arguments[3],
"templates/headerTemplate.ejs": arguments[4],
"templates/homeTemplate.ejs": arguments[5],
"templates/indexTemplate.ejs": arguments[6],
"templates/jobsTemplate.ejs": arguments[7],
"templates/loginTemplate.ejs": arguments[8],
"templates/overviewTemplate.ejs": arguments[9],
"templates/pictureTemplate.ejs": arguments[10],
"templates/portalTemplate.ejs": arguments[11],
"templates/registeredUsersTemplate.ejs": arguments[12],
"templates/userProfileTemplate.ejs": arguments[13]
}
});
Entonces puedes requerir módulos en tu front-end así:
var footerView = require("app/js/jsx/standardViews/footerView");
sin embargo, como puedes ver, esto es demasiado detallado, así que la forma mágica es así:
nombra la dependencia anterior como todas las vistas!
ahora puedes hacer
var allViews = require(''allViews'');
var footerView = allViews[''standardViews/footerView''];
Hay dos ventajas al requerir directorios completos:
(1) en producción, con el optimizador r.js, puede apuntar a una dependencia (módulo A) y luego puede rastrear fácilmente todas las dependencias de A que representan un directorio completo
(2) en desarrollo, puede requerir directorios enteros por adelantado y luego usar la sintaxis síncrona para requerir dependencias porque sabe que ya se han cargado
disfrutar de "RequireJS-Metagen"
https://github.com/smartprocure/directory-metagen
Mientras que JavaScript en el navegador no puede (y no debería) ver el sistema de archivos, creé una tarea Grunt que hará esto. Actualmente, todavía estoy trabajando en ello, aquí y allá, pero puedes echarle un vistazo.
https://npmjs.org/package/require-wild
npm install require-wild
En su caso, todo lo que tendría que hacer es configurar los ajustes de la tarea.
grunt.initConfig({
requireWild: {
app: {
// Input files to look for wildcards (require|define)
src: ["./**/*.js"],
// Output file contains generated namespace modules
dest: "./namespaces.js",
// Load your require config file used to find baseUrl - optional
options: { requireConfigFile: "./main.js" }
}
}
});
grunt.loadNpmTasks("require-wild");
grunt.registerTask(''default'', [''requireWild'']);
A continuación, ejecute la tarea de gruñido. Su archivo será generado. Modifique su main.js
para cargar namespaces.js
require([''namespaces''], function () { ... });
De este modo, ahora los módulos bajo src
pueden usar dependencias con la coincidencia de patrón glob de grunt.
require([''behaviors/**/*''], function (behaviors) { }
Esta ideología asume que tienes una estructura de archivos significativa.
Sé que esto es viejo, pero me gustaría compartir mi solución:
Para esta solución necesitas JQuery.
1) Cree un script de bash que enumere todos los archivos js en "MyDirectory /", y guárdelo en "directoryContents.txt" :
#!/bin/bash
#Find all the files in that directory...
for file in $( find MyDirectory/ -type f -name "*.js" )
do
fileClean=${file%.js} #Must remove .js from the end!
echo -n "$fileClean " >> MyDirectory/directoryContents.txt
done
- El archivo se verá así:
MyDirectory / FirstJavascriptFile MyDirectory / SecondJavascriptFile MyDirectory / ThirdJavascriptFile
- Problema con mi guión! Pone un "" extra al final, ¡eso ensucia las cosas! Asegúrese de eliminar el espacio en exceso al final de directoryContents.txt
2) Luego en su código JS del lado del cliente:
- hacer una solicitud "GET" para recuperar el archivo de texto
- Para cada entrada (dividida por el espacio), ''requiera'' ese archivo:
.
$.get( "MyDirectory/directoryContents.txt", {}, function( data ) {
var allJsFilesInFolder = data.split(" ");
for(var a=0; a<allJsFilesInFolder.length; a++)
{
require([allJsFilesInFolder[a]], function(jsConfig)
{
//Done loading this one file
});
}
}, "text");
Estaba teniendo un problema con este código que no terminaba antes de mi otro código, así que aquí está mi respuesta extendida:
define([''''], function() {
return {
createTestMenu: function()
{
this.loadAllJSFiles(function(){
//Here ALL those files you need are loaded!
});
},
loadAllJSFiles: function(callback)
{
$.get( "MyDirectory/directoryContents.txt", {}, function( data ) {
var allJsFilesInFolder = data.split(" ");
var currentFileNum = 0;
for(var a=0; a<allJsFilesInFolder.length; a++)
{
require([allJsFilesInFolder[a]], function(jsConfig)
{
currentFileNum++;
//If it''s the last file that needs to be loaded, run the callback.
if (currentFileNum==allJsFilesInFolder.length)
{
console.log("Done loading all configuration files.");
if (typeof callback != "undefined"){callback();}
}
});
}
}, "text");
}
}
});
Lo que terminé haciendo fue que cada vez que mi servidor Node arranca, ejecutará el script bash, llenando directoryContents.txt. Luego, el lado de Mi cliente simplemente lee directoryContents.txt para la lista de archivos, y requiere cada uno en esa lista.
¡Espero que esto ayude!
javascript en el navegador no tiene acceso al sistema de archivos, por lo que no puede escanear un directorio en busca de archivos. Si está creando su aplicación en un lenguaje de scripting como php o ruby, podría escribir un script que escanee el directorio y agregue los nombres de los archivos a la llamada require ().
Realmente no hay una manera de hacer esto conceptualmente sobre la marcha (que yo sepa).
Sin embargo, hay algunos trabajos alrededor:
Use grunt
y concat
y luego solo requiera a ese gigante ... Lo sé, un poco tonto.
Lo que creo que es una mejor solución ... use una jerarquía de requisitos como tal:
require(''/js/controllers/init'', function(ctrls){
ctrls(app, globals);
});
// /js/controllers/init.js
define(''js/controllers/index'', ''js/controllers/posts'', function(index, posts){
return function protagonist(app, globals){
var indexModule = index(app, globals);
var indexModule = posts(app, globals);
return app || someModule;
};
});
// /js/controllers/index.js
define(''js/controllers/index'', ''js/controllers/posts'', function(index, posts){
return function protagonist(app, globals){
function method1(){}
function method2(){}
return {
m1: method1,
m2: method2
};
};
});
Tenga en cuenta que la función " protagonist
". Eso le permite inicializar los módulos antes de su uso, por lo que ahora puede pasar en un '' sandbox
'', en este caso, la app
y los globals
.
De manera realista, no /js/controllers/index.js
... Probablemente debería ser algo como /js/controllers/index/main.js
o /js/controllers/index/init.js
para que haya una directorio adyacente a (hermano de) /js/controllers/init.js
llamado "índice". Esto hará que sus módulos sean escalables a una interfaz determinada, simplemente puede intercambiar módulos y mantener su interfaz igual.
¡Espero que esto ayude! ¡Feliz codificación!