Gulp.js get filename from .src() - javascript

I'm trying to use gulp-proceesshtml (https://github.com/julien/gulp-processhtml) to remove some unwanted code in my build version, the problem is that the task requires a filename to be given.
gulp.src('test.html').pipe(processhtml('test.html'));
But I can't figure out how this would work when I'm processing all HTML files in a folder
gulp.src('*.html).pipe(processhtml('filename here'));

Personally, it sounds like that's the wrong plugin for what you are trying to accomplish. See below.
However, because it's not clear what you are using it for, you can be able to use node-glob to process each file one-by-one:
var glob = require('glob')
// you also need event-stream for merging the streams
es = require('event-stream');
gulp.task('myTask', function() {
var files = glob.sync('*.html'),
streams;
streams = files.map(function(file) {
// add the *base* option if your files are stored in
// multiple subdirectories
return gulp.src(file, {base: 'relative/base/path'})
// may need require('path').filename(file)
.pipe(processhtml(file));
});
return es.merge.apply(es, streams);
});
This will create a single asynchronous stream out of every file that matches your initial pattern.
For simply removing some text from your files, you can use gulp-replace, like so:
var replace = require('gulp-replace');
gulp.src('*.html')
// replaces all text between
// <!-- remove-this --> and <!-- /remove-this -->
.pipe(replace(/<!--\s*remove-this\s*-->[\s\S]*?<!--\s*\/remove-this\s*-->/g, ''));

I know this question is old, but for a shorter solution you can use gulp-tap, something like this:
.pipe(tap(function(file, t) {
console.log(file.path);
}))
if you need to use the filename in other step of the pipe you can store it in a variable and use it for next step.

Related

vim NERDTreeIgnore for specific files in specific subdirectory

i am using https://github.com/MarcWeber/vim-addon-local-vimrc for setting project specific vim settings.
now i want to use NERDTreeVimIgnore to ignore javascript files only in the subdirectory src.
i tried that:
let NERDTreeIgnore = ['^src*\.js$']
but had no success.
let NERDTreeIgnore = ['\.js$']
ignores all js files but i need them ignored only in src and its recursive subdirectories.
can anyone give me a hint?
Unfortunately, it seems that the NERDTreeIgnore option only looks at the last path component (the basename of the file). This means that you won't be able to filter out particular files like that.
The only way I can think of doing this would be by using the NERDTreeAddPathFilter() function: https://github.com/scrooloose/nerdtree/blob/15445be5fb2559829ac7a1f05af5d713586e8ec9/doc/NERD_tree.txt#L1175
You could create a vim file in your nerdtree_plugin directory, for example ~/.vim/nerdtree_plugin/path_filters.vim. It would contain something like the example in the docs:
call NERDTreeAddPathFilter('MyFilter')
function! MyFilter(params)
" params is a dict containing keys: 'nerdtree' and 'path' which are
" g:NERDTree and g:NERDTreePath objects
" return 1 to ignore params['path'] or 0 otherwise
" You could do something like this, then:
let filename = fnamemodify(a:params.path.str(), ':p')
return filename =~ 'src/myproject/.*\.js'
endfunction
You may have to read up a bit in the documentation on writing functions and such, if you run into trouble.

How to concatenate two streams using gulp?

For example I have a task with next content:
function task() {
gulp.src('libs/*.js')
// some manipulations
.concat('libs.js')
gulp.src('js/*.js')
// Another manipulations
.concat('app.js')
}
What if I don't want to put this files anywhere in file system? Can I somehow concatenate libs.js and app.js inside a task?
You can use merge-stream package. Simple example:
gulp.task("do-something", function() {
var vendorScripts1 = gulp.src("libs/*.js")
.pipe(/* I want to do something*/));
var vendorScripts2 = gulp.src("js/*.js")
.pipe(/* I want to do something else here*/);
return merge(vendorScripts1 , vendorScripts2)
.pipe(/*bla bla bla*/);
});
Github example I hope it will help you.
Thanks

How to make a requirejs module with multiple files

I was wondering how to make a requirejs module with multiple files.
e.x. I require one file which then somehow gets multiple files.
I know I could do this:
define([all the other files], function () {
var mod = {},
files = [all the other files];
arguments.forEach(function (i) {
mod.[files[i]] = i;
});
return mod;
});
but I was wondering whether there was a better method?
You want a dynamic list of files(.txt,.tpl,.htm,.json), to avoid a change in JS source code to add more files.
I don't know if is there a way to do that, but you must take care about the time that will take to download all this files. I suggest you to create a json file with all files that you want to download, and iterate through this array of files using ajax to get them.
If you are try to get all module inside a directory, you need to create a js file: <package-all>.js that encapsulate an require([all files],function()); for example.
I believe that this is the only way to solve this.
first, write the modules like this,
define(function(){
return {
'mod-a' : require('modules/mod-a'),
'mod-b' : require('modules/mod-b'),
'mod-c' : require('modules/mod-c')
}
})
then use r.js to optimize the above js to blow one (r.js will combine all module file to one), or, you can write like this directly :
define('modules/mod-a', [], function(){});
define('modules/mod-b', [], function(){});
define('modules/mod-c', [], function(){});
define('mod-all', ['modules/mod-a','modules/mod-b','modules/mod-c'], function(){
return {
'mod-a' : require('modules/mod-a'),
'mod-b' : require('modules/mod-b'),
'mod-c' : require('modules/mod-c')
}
})
now, the modules 'mod-all' is the thing you wanted.

Concatenating JavaScript files using Ant

I have about 50-60 js files and there are dependencies among them so I need to maintain an order while cocatenating. Writing all the names in "files" attribute would make the build.xml messy and any addition of js files in future would need to added accordingly. So, I wanted to write the order in a separate txt file and just copy the contents using Ant following that order. Is it possible ?
You can do what you want using a resourcelist, for example:
<concat destfile="concatenated.js">
<resourcelist>
<file file="js.files.txt"/>
<filterchain>
<striplinecomments>
<comment value="#"/>
</striplinecomments>
</filterchain>
</resourcelist>
</concat>
The filterchain isn't required, but is useful as you can then include comment lines in your list-of-files.
You can use order independent declarations like these:
// in every file
if(!("myLib" in window))myLib = {};
if(!("canvas" in myLib))myLib.canvas = { .... };
//next file
if(!("myLib" in window))myLib = {};
myLib = $.extend(myLib, true, {
init: function(){},
move: function(){}
});
//in index
myLib.init();

Auto-load/include for JavaScript

I have file called common.js and it's included in each page of my site using <script />.
It will grow fast as my sites functionality will grow (I hope; I imagine). :)
Lets example I have a jQuery event:
$('#that').click(function() {
one_of_many_functions($(this));
}
For the moment, I have that one_of_many_functions() in common.js.
Is it somehow possible that JavaScript automatically loads file one_of_many_functions.js when such function is called, but it doesn't exist? Like auto-loader. :)
The second option I see is to do something like:
$('#that').click(function() {
include('one_of_many_functions');
one_of_many_functions($(this));
}
That not so automatically, but still - includes wanted file.
Is any of this possible? Thanks in an advice! :)
It is not possible to directly auto-load external javascripts on demand. It is, however, possible to implement a dynamic inclusion mechanism similar to the second route you mentioned.
There are some challenges though. When you "include" a new external script, you aren't going to be able to immediately use the included functionality, you'll have to wait until the script loads. This means that you'll have to fragment your code somewhat, which means that you'll have to make some decisions about what should just be included in the core vs. what can be included on demand.
You'll need to set up a central object that keeps track of which assets are already loaded. Here's a quick mockup of that:
var assets = {
assets: {},
include: function (asset_name, callback) {
if (typeof callback != 'function')
callback = function () { return false; };
if (typeof this.assets[asset_name] != 'undefined' )
return callback();
var html_doc = document.getElementsByTagName('head')[0];
var st = document.createElement('script');
st.setAttribute('language', 'javascript');
st.setAttribute('type', 'text/javascript');
st.setAttribute('src', asset_name);
st.onload = function () { assets._script_loaded(asset_name, callback); };
html_doc.appendChild(st);
},
_script_loaded: function (asset_name, callback) {
this.assets[asset_name] = true;
callback();
}
};
assets.inlude('myfile.js', function () {
/* do stuff that depends on myfile.js */
});
Sure it's possible -- but this can become painful to manage. In order to implement something like this, you're going to have to maintain an index of functions and their corresponding source file. As your project grows, this can be troublesome for a few reasons -- the 2 that stick out in my mind are:
A) You have the added responsibility of maintaining your index object/lookup mechanism so that your scripts know where to look when the function you're calling cannot be found.
B) This is one more thing that can go wrong when debugging your growing project.
I'm sure that someone else will mention this by the time I'm finished writing this, but your time would probably be better spent figuring out how to combine all of your code into a single .js file. The benefits to doing so are well-documented.
I have created something close to that a year ago. In fact, I have found this thread by search if that is something new on the field. You can see what I have created here: https://github.com/thiagomata/CanvasBox/blob/master/src/main/New.js
My project are, almost 100% OOP. So, I used this fact to focus my solution. I create this "Class" with the name "New" what is used to, first load and after instance the objects.
Here a example of someone using it:
var objSquare = New.Square(); // Square is loaded and after that instance is created
objSquare.x = objBox.width / 2;
objSquare.y = objBox.height / 2;
var objSomeExample = New.Stuff("some parameters can be sent too");
In this version I am not using some json with all js file position. The mapping is hardcore as you can see here:
New.prototype.arrMap = {
CanvasBox: "" + window.MAIN_PATH + "CanvasBox",
CanvasBoxBehavior: "" + window.MAIN_PATH + "CanvasBoxBehavior",
CanvasBoxButton: "" + window.MAIN_PATH + "CanvasBoxButton",
// (...)
};
But make this more automatic, using gulp or grunt is something what I am thinking to do, and it is not that hard.
This solution was created to be used into the project. So, the code may need some changes to be able to be used into any project. But may be a start.
Hope this helps.
As I said before, this still is a working progress. But I have created a more independent module what use gulp to keep it updated.
All the magic que be found in this links:
https://github.com/thiagomata/CanvasBox/blob/master/src/coffee/main/Instance.coffee
https://github.com/thiagomata/CanvasBox/blob/master/src/node/scripts.js
https://github.com/thiagomata/CanvasBox/blob/master/gulpfile.js
A special look should be in this lines of the Instance.coffee
###
# Create an instance of the object passing the argument
###
instaceObject = (->
ClassElement = (args) ->
window[args["0"]].apply this, args["1"]
->
ClassElement:: = (window[arguments["0"]])::
objElement = new ClassElement(arguments)
return objElement
)()
This lines allows me to initialize a instance of some object after load its file. As is used in the create method:
create:()->
#load()
return instaceObject(#packageName, arguments)

Categories

Resources