How do I require a library so that it works inside Jade.
Like if I want to be able to use CircularJSON in Jade
script var object = #{CircularJSON.stringify(object)}
I would basically need to define the function from that library into Jade
- var CircularJSON = function(e,t){function l(e,t,o){var u=[],...//whole function
which would be impractical and possibly impossible for much more complex libraries.
Is there a way to somehow simply require it instead?
var myLib = require('../mylib');
response.render("index.jade", {
lib : myLib
});
index.jade now has the myLib object. Now just use as you would anywhere else.
Just require it in node and pass it to the template in the locals. locals can include functions as well entire modules, objects and scalar data.
I like to take an approach similar to Peter Lyons and Zhifeng Hu (in another post), but instead of requiring everything into locals, I just require "require", then I can pull things in as needed in my templates.
app.use((req, res, next) => { res.locals.require = require; next() })
and then in Jade/Pug
- const moment = require('moment')
div Created at: #{moment(data.createdAt).fromNow()}
Basically the same thing, but I can keep the require code in the template where it's used.
Related
I have a bunch of js script files that use require to require the same series of libraries, etc.'
let path = require('path');
let _ = require('underscore');
I want to put all these requirements into a separate library file that I can then reuse amongst the files that need them. I though I could do something like this:
var common = function() {
this.requireFiles = function() {
let path = require('path');
let _ = require('underscore');
...
}
};
export.common = common;
However, when I want to include this library in those files that use all these same files, it does not work. I am trying something like this:
let CommonTools = require('../server_libs/commonFiles').common;
let commonFiles = new CommonTools();
migration.requireFiles();
This give me an error that _ is not a function, when I want to use the underscore methods. Any hints as to where I should look for better understanding on this topic?
I personally do not recommend making a common module. The node.js module mentality is to just require() in what a module needs. Yes, it seems like a little extra/redundant typing in each module, but it makes each module self describing and does not build any unnecessary dependencies between modules leading to the simplest module sharing or reuse options. Modules are cached by the require() sub-system so it doesn't really cost you at runtime to just require() in each module as you need them. This is pretty much the node.js way.
That said, if you really want to make a common module, you can do it like this:
common.js
module.exports = {
_: require('underscore');
path: require('path');
}
otherModule.js
const {_, path} = require('common.js');
// can now call underscore methods _.each()
// can now call path methods path.join()
This uses destructing assignment to get properties from the common.js exports and assign them to a module-scoped variable and to do it for multiple properties in one statement. It still requires you to list each property you want defined in this module (which helps self describe what you're doing).
This also assume you're using require() and module.exports. If you're using the newer import and export keywords, then you can modify the syntax accordingly, but still use the same concept.
We have require implemented in our web app and is working a treat. The change up now is that we have some javascript that is dynamically created at runtime on the client. Is there a way with require to directly inject a string of javascript directly into the require() function.
Currently we have:
require([moduleToLoad], function(mod){ //DO SOMETHING}});
Want something like (forgive the syntax because just writing it out):
var jsString = "define(['Text!something.htm'], function (control_Template) { //MODULE LOADED JAVASCRIPT}))";
require(jsString, function(mod){ //DO SOMETHING}});
Does anyone know how and if we can accomplish this?
Thanks
You can use named modules syntax in your string for defining the AMD module. Eval this string and then require the module using the name you have provided.
Define module like following
eval("define('runtimemodule', ['Text!something.htm'], function(){ return 'template here' })")
Require module like following
require(["runtimemodule"], function(mod){
console.log(mod); //logs "tempalte here"
});
I have a node toplevel myapp variable that contains some key application state - loggers, db handlers and some other data. The modules downstream in directory hierarchy need access to these data. How can I set up a key/value system in node to do that?
A highly upticked and accepted answer in Express: How to pass app-instance to routes from a different file? suggests using, in a lower level module
//in routes/index.js
var app = require("../app");
But this injects a hard-coded knowledge of the directory structure and file names which should be a bigger no-no jimho. Is there some other method, like something native in JavaScript? Nor do I relish the idea of declaring variables without var.
What is the node way of making a value available to objects created in lower scopes? (I am very much new to node and all-things-node aren't yet obvious to me)
Thanks a lot.
Since using node global (docs here) seems to be the solution that OP used, thought I'd add it as an official answer to collect my valuable points.
I strongly suggest that you namespace your variables, so something like
global.myApp.logger = { info here }
global.myApp.db = {
url: 'mongodb://localhost:27017/test',
connectOptions : {}
}
If you are in app.js and just want to allow access to it
global.myApp = this;
As always, use globals with care...
This is not really related to node but rather general software architecture decisions.
When you have a client and a server module/packages/classes (call them whichever way you like) one way is to define routines on the server module that takes as arguments whichever state data your client keeps on the 'global' scope, completes its tasks and reports back to the client with results.
This way, it is perfectly decoupled and you have a strict control of what data goes where.
Hope this helps :)
One way to do this is in an anonymous function - i.e. instead of returning an object with module.exports, return a function that returns an appropriate value.
So, let's say we want to pass var1 down to our two modules, ./module1.js and ./module2.js. This is how the module code would look:
module.exports = function(var1) {
return {
doSomething: function() { return var1; }
};
}
Then, we can call it like so:
var downstream = require('./module1')('This is var1');
Giving you exactly what you want.
I just created an empty module and installed it under node_modules as appglobals.js
// index.js
module.exports = {};
// package.json too is barebones
{ "name": "appGlobals" }
And then strut it around as without fearing refactoring in future:
var g = require("appglobals");
g.foo = "bar";
I wish it came built in as setter/getter, but the flexibility has to be admired.
(Now I only need to figure out how to package it for production)
I ran into an issue with my Nodejs application.
I have two different apps that are using shared library, which is located so that it is found one level up in node_modules. So i have this structure ./app1/app.js, ./app2/app.js and ./node_modules/shared.libs/index.js.
shared.libs in its turn has some other modules installed, like mongoose, redis etc. Plus some mogoose models with additional functions in them. All are exported from index.js like this:
exports.async = require('async');
exports.config = require('./config');
exports.utils = require('./lib/utils');
And then in apps i import them like this:
var libs = require('shared.libs');
var config = libs.config;
So after this code i can use config which is coming from that shared library.
This part was and is working just fine. But now i need to put additional layer on top of this library (read: provide more unified interface for both apps).
What i tried to do is to add some functions into index.js of shared library and then export the whole object with these functions. But whenever i try to call previously imported (by var libs = require('shared.libs');) object it says that libs is not defined.
What am i doing wrong here?
I generally want to keep other code the same, so i won't need to go over replacing require part everywhere, but at the same time provide additional functionality from shared library which will be available from that imported libs object.
this should definitely work:
module.exports = {
async: require('async'),
config: require('./config'),
utils: require('./lib/utils'),
foo: function () {
return 'bar';
}
};
reference like:
var libs = require('shared.libs');
console.log(libs.async);
console.log(libs.config);
console.log(libs.utils);
console.log(libs.foo);
console.log(libs.foo());
What makes me wonder is one of your comments above, that you get an error libs is not defined. That looks like you should have other unnoticed errors before.. during the the initialization of your shared.libs module..
I am building a little node app and using Express with Jade and Stylus to render some basic HTMl pages.
I was curious if there is a way for me to pass some variables INTO the .styl file that are generated from Node? I am well aware that i can define variables inside of the .styl file but I have a need to be more dynamic. Specifically i was looking for an easy way to store some colors in the db, have node grab those values, then insert those into the .styl file so that when the page is rendered these variables are passed in. It seems like this should be do-able but i am lacking on the details. Any help is appreciated. Thanks!
Thanks to #ebohlman as his advice was close to what i ultimately implemented.
basically i was trying to figure out how to do this on top of the Connect Middleware and here is what i came up with:
when doing app.configure i used the custom compile compile function (key 'compile') like so:
app.use(require('stylus')
.middleware({
src: app.root + '/app/public',
compile: compile
})
);
then i created a couple of functions:
var stylus = require('stylus');
var mylib = function(style){
style.define('themeColor1', function(){
//call to the db that returns a color
color = 'blue';
color = color ? color : 'orange';
return new stylus.nodes.Literal(color);
});
};
var compile = function(str, path) {
return stylus(str)
.use(mylib);
};
then inside of the .styl file i do:
background-color themeColor1();
the ternary operator in the themeColor1 function allows for easy defaults and an override. It took me a bit to figure out the API based upon the examples but it seems like this COULD be a solution others would want to know how to do. If anyone has any downfalls of this approach please let me know.
You can use the Stylus API's define() function to set Stylus variables and make JS functions available to it.