My current Grunt implementation uses grunt-includes to wrap all of my pages in the header/footer code. What I am looking for is a way to add dynamic bits to the header and footer to load CSS/JS as well as add classes to the body tag, but I need them to be based on the name of the file requesting the include during the grunt-includes task.
I could get everything done I needed to if I could simply get grunt-includes to pass the name of the requesting file into the included file. In reading the documentation for grunt-includes I can see that there appears to be some kind of template for {{fileName}} and {{file}} but I can't seem to get these to work.
Just to clarify, what I am looking for is, when running grunt-includes via grunt, if a file named myFile.html has the line include "global/myHeader.html", myFile or myFile.html gets passed into global/myHeader.html as it is concatenated onto myFile.html.
Can somebody please point me in the right direction here? I've been spinning my wheels for two days.
My includes function that I am currently using is as follows:
includes: {
files: {
src: ['sources/*.html'], // Source files
dest: 'app', // Destination directory
flatten: true,
cwd: '.',
options: {
silent: true,
}
}
},
The template setting goes in the options object of the files object. This is the only place where {{file}} and {{fileName}} can be used. This means if you wan't to "pass" these into the requested files you either have to put the entire string in the template (not recommended), or pass just the file name into a hidden tag and use JavaScript to handle whatever dynamics you needed.
I recommend using grunt template for this instead:
http://gruntjs.com/api/grunt.template
Related
I am learning node.js
for example, I try
var server = require("./myserver.js");
and
var server = require("./myserver");
Both of these two casework.
what if I have another file with the same name?
e.g myserver.json, myserver.node
, will it always search .js at first?
From one of the answerers in my previous question,
he mentions
only load the .json file if you explicitly add the .json extension to the require-call. So if you leave the extension, it always loads the .js file.
will this rule also suit to .node file?
If the exact filename is not found, then Node.js will attempt to load the required filename with the added extensions: .js, .json, and finally .node. You can check node_js docs for detailed explanation. https://nodejs.org/api/modules.html#modules_file_modules
Yes, If you will not provide the extension of the file, Then, it will first look at the JS file, since JS is by default
A bit about what I'm trying to achieve.
I'm building dev library that shows the list of files. And I want to set file color depending on when file was changed.
So, as a result of generation, I want an array like this:
[
{
lastChange: '2009-06-29T11:11:55Z',
fileContents: {name: 'VmSome'},
},
// ...
]
This is meant to work in browser environment. Meaning all file related information should be included into bundle.
Current progress
At the moment I'm not quite sure whether that's even possible.
I'm getting a list of files via webpack require.context:
require.context('./tree', true, /.js$/)
This gives me access to file content and path. But not to anything else.
Thanks for your attention.
I would first try modifying webpack-file-list-plugin. As of now, it creates a JSON that gives all files packed, their name and some more info... You could definitely add your code to fetch more information to the JSON.
https://github.com/object88/webpack-file-list-plugin/blob/master/src/index.js
I have a Jade file index.jade and I have a dir public\js that contains a few js script files.
views
index.jade
public
js
a.js
b.js
...
Is there a way to automatically and programmatically include them all as scripts in the index.jade?
script(src='/js/a.js')
script(src='/js/b.js')
...
Yes, you can do that. Before we get into the solution let's talk about why it's better to NOT do it.
Jade/pug compiles all of the templates into an in-memory JavaScript function so when your users request a page it's very fast as there's no disk access required. Disk access is usually the slowest part of a web request, and it's why there are so many caching and CDN solutions out there. When you read the file system for these files every request in to that page will be scanning the disk multiple times, first to read the directory then to insert the files to the output.
Will these script files really be changing so often that you need to incur this disk access on every request? If you have so many script files that it's inconvenient to add them individually then you could probably group the script tags into a single template and use inheritance or mixins to help you.
With that, said if you still really want to do it this way here's how to do it...
You need to read the files in your route and pass the array to the template:
var fs = require('fs');
fs.readdir(path, function(err, files) {
// you should use a loop with a regex like ([^\/]+$) here to strip out the directory names
// this will be specific to your server's file system setup
res.render('<viewname>', scripts);
}
Then in the template:
each script in scripts
script(src= script)
I have a full aplication working with Typescript and RequireJs, it is working perfectly. I have now download WebEssentials and it is generating the minified script files. WebEssentials generates separated *.min.js files with the same name as the original script file.
How can I tell RequireJs to load my minified files instead of my original script files ?
Thanks in advance
You can use path config to override module paths. You can even fall back to non minified files:
requirejs.config({
enforceDefine: true,
paths: {
jquery: [
'lib/jquery.min',
'lib/jquery'
]
}
});
There may be a more general way to use min files that I don't know about!
You can create a simple customized version of require which will conditionally append '.min.js' to all module file requests that would normally just receive the '.js' appendage. Consider the following:
//Establish a new 'useMinified' boolean in your initial config.
require.config({ useMinified: true });
Then, edit the require.js library file and modify the 'nameToUrl' function as below:
//Join the path parts together, then figure out if baseUrl is needed.
url = syms.join('/');
//new statement
var extension = config.useMinified ? '.min.js' : '.js';
//customized statement
url += (ext || (/^data\:|\?/.test(url) || skipExt ? '' : extension));
url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url;
There isn't any magic to this. You have a few options though
Use the RequireJS optimizer to generate min files for you. Very configurable.
Use the --out compiler option to concatenate all your files into one and minify that
Create a script/batch file to copy your app somewhere else, rename all .min.js files to .js and overwrite the non-min'd ones. Or some other mix but you get the gist
Use the paths config like Steve mentioned. OK for small apps, less than ideal for large.
For the best performance you should look into the optimizer and determine if the single-script approach is the right decision or multiple smaller libraries is a better approach. I doubt that loading each .min.js file is the ideal solution for you.
Is it possible to inject runtime information in to a require.js "data main" script and use to build paths? More explanation...
In my node.js app.js I dynamically find the path to the configured 'theme' like this:
var themePath = require('./conf/config.js').config.theme.full_path;
and later in the require.js data main script, I'd like to prepend this theme path when defining paths. So assuming I've set my requirejs data-main="xxx" and the following is the xxx file, I'd like to do something like the following:
require.config({
baseUrl: "/js/",
paths: {
"templates" : DYNAMIC_THEME_PATH + '/templates',
"views" : DYNAMIC_THEME_PATH + '/views'
}
});
I'm not sure 1. how I can "see" the themePath from within this require.js data main file, and 2. is this even possible?
EDIT - My solution
So the real challenge I was having was getting a runtime variable discovered on the server in to the require.js data main script. In node land, global doesn't correspond to the window on the client side (of course) because the javascript isn't in to the browser yet .. duh. So I don't see how you can get this discoverable in the client side script.
Ok, so what I WAS able to do was inject the discovered theme path in the ejs, then, dynamically load the data main script with that prepended like:
<script data-main="<%= theme_path %>/main" src="../js/libs/require-jquery.js"></script>
Of course this means I have to have the data main script in the theme directory which wasn't my initial plan; however, it does have the advantage that I can then use relative paths to load my path/to/templates path/to/views, etc. etc.
Lastly, I sort of hate when folks answer they're own questions .. so I'm going to leave this up in hopes that someone can either give me a better recommendation or better explain this and they can get the credit ;)