How can I compile JS and JSON together? - javascript

I have a project where the prod machine specs are low so I'm trying something new and trying Gulp to compile everything into one compressed js file.
I have a config.json that's being used by main.js. What does my gulpfile.js has to look like in order to turn those two files into one js file?

You may declare a variable in JS to contain the JSON data as per following example
var arr = [
{
data1: 'mydata01',
data2: 'mydata02',
},
{
data3: 'mydata03',
data4: 'mydata04',
}
]
But this defeats the spirit and purpose of JSON which is primarily for exchanging of Data between two entities (two webpages, client-server, webpage-database, etc). This technique will make the data hardcoded in the JS with lesser flexibility to change the data dynamically.

Related

How to get all required modules from node.js as a single text file or string?

I need to get all files from some require stack and this include all requires inside the required too.
Example:
file.js
require("./b");
require("./c");
//require("./d"); // this is a comment, need to prevent that
AST
[{
path: "absolute_dir/b.js",
name: "7saf7fs6asf7" // hash
},
...]
ouput (with the AST i can get all files by his name and put them in one single file, like a bundler)
require("7saf7fs6asf7");
require("sa8d78as8d7f");
I don't know how to do this in a modular logic. PLZ help me :)

Combine javascript files and their source maps

I am struggling with the combination of multiple javascript files and their source maps.
The problem is: I use Google Closure Compiler to obfuscate two javascript files A and B, with generated source maps A.map and B.map. Since I apply different compilation options on them, so compiling A and B into a single file does not work for me. Now, I want to combine A and B to AB, and also combine A.map and B.map into AB.map.
How should I do this? Any existing tools suitable for this purpose?
There are a number of packages out there that will do the job for example with the grunt-concat-sourcemap package for node you can do the following:
grunt.initConfig({
concat_sourcemap: {
options: {},
target: {
files: {
'dest/out.js': ['src/a.js', 'src/b.js']
}
}
}
})
this will concatenate the two specified source files(in order), and write the output to dest/out.js and dest/out.js.map
here are some links to packages for grunt, gulp and plain node:
https://www.npmjs.com/package/grunt-concat-sourcemap
https://github.com/mikach/gulp-concat-sourcemap
https://www.npmjs.com/package/source-map-concat

How Do You Get Around Javascript File Order Using Gulp Or A Javascript Framework?

I'm using gulp to build a single javascript file with gulp-concat and gulp-uglify.
Original Files
//File 1
var Proj = Proj || {};
//File 2
Proj.Main = (function() {
var Method = function(){ /*Code*/ };
return { "Method":Method };
})();
//File 3
Proj.Page = (function() {
var Method = Proj.Main.Method;
return { "Method":Method };
})();
Gulp returns a bad minified file because these files are being concatenated in the wrong order. I know I can specify the order in .src([]) but I don't want to maintain the array as I add javascript files.
Is there a way to create references to these "namespaces" without having to worry about the order of the files concatenated? Or, is there a way for gulp to handle concatenation with the knowledge of these namespaces auto-magically?
EDIT:
I know I can specify the file order inside the .src([]). I want to develop without having to worry about the file order, whether it be through a gulp package or a javascript framework. Thank you for responses that help but I need a definitive "No. You cannot do this." or "Yes. Here's how..." to mark the thread as answered.
Well, one option is to try gulp-order.
Also, check out this answer to "gulp concat scripts in order?".
Basically, it mentions what you already said, about having to explicitly name the files in the order you want them to come in. I know you don't want to do that, but how else would gulp know which order you want your files in?
One thing worth pointing out, though, is that you have a group of files where the order doesn't matter, and then, say, 2 files where the order does matter, you can do something like this:
gulp.src([
'utils/*.js',
'utils/some-service.js',
'utils/something-that-depends-on-some-service'
])
gulp-concat doesn't repeat files, so everything that's not some-service.js or something-that-depends-on-some-service.js will get concatenated first, and then the last two files will be concatenated in the proper order.
Since it hasn't been mentioned, implementing webpack or browserify will absolutely solve this problem without implementing some sort of hacky feeling solution.
Here is a simple example of how to use it:
var source = require('vinyl-source-stream'), //<--this is the key
browserify = require('browserify');
function buildEverything(){
return browserify({
//do your config here
entries: './src/js/index.js',
})
.bundle()
.pipe(source('index.js')) //this converts to stream
//do all processing here.
//like uglification and so on.
.pipe(gulp.dest('bundle.js'));
}
}
gulp.task('buildTask', buildEverything);
And inside your files you use require statements to indicate which files require others.

Import Javascript object into jade

I've read and re-read the jade references and a whole bunch of stack overflow questions but I can't seem to figure this out and I think it should be really simple.
So all I want to do is have an object in a JavaScript file, and have that imported into my jade file so I can use the data from the object when generating my html page.
for example:
This would be in a JS file:
var obj = {
firstName: "bob",
lastName: "smith",
age: 109
};
And in my jade I want to do this:
h1 #{obj.firstName}, #{obj.lastName}
h2= obj.age
etc.
This is just a simple example. Any help at all would be much appreciated.
I would simply create the object in my jade but I want the object to be formatted where each item is on its own line (for readability), and jade doesn't currently support that.
On that link someone mentioned a solution that I did not understand at all: "so I accomplished what I wanted by passing in the array in grunt-contrib-jade instead of putting it directly in the template. Also allowed me to get rid of grunt-sed"
I am using codekit to compile my jade into static html, not Node.JS.
This can be accomplished if you translate your object to JSON format.
From the docs on command line arguments:
-O, --obj <path|str> JavaScript options object or JSON file containing it
Example:
user.json
{
"firstName": "bob",
"lastName": "smith",
"age": 109
}
And you would compile your template like that:
$ jade myTemplate.jade --obj user.json
or if you're using Gulp with gulp-jade:
.pipe(jade({
locals: require('user.json')
}))

Grunt Concat same file multiple times

I'd like to use grunt-contrib-concat for application frontend HTML templating purposes and this would be useful for me.
I'd like to define page partials and and concatenate them inside an output file that is going to be compiled by handlebars.
I've got everything set up, however Concat doesn't allow me to use the same file more than once.
Basically concat is filtering the sources so they don't occur more than once. The second partial1.hbs will not be concatenated.
pageconcat: {
src: [
'app/templates/partial1.hbs',
'app/templates/partial2.hbs',
'app/templates/partial1.hbs'
],
dest: 'app/result.hbs'
}
Is there any way to do this?
Update 1
After playing around with grunt's console output function, I was able to debug (of some sort) the concat plugin. Here's what I found out: The input array is deduplicated by grunt for some reason.
Update 2
The deduplication occurs in the foreach file loop that grunt uses. I've managed to bypass that (see answer). I do not know how reliable my solution is but it's a workaround and it works well if you don't put the wrong input.
You may be able to use the file array format to set up two different source sets. Something like this:
{
"files": [{
"src": [
"app/templates/partial1.hbs",
"app/templates/partial2.hbs"
],
"dest": "app/result.hbs"
}, {
"src": [
"app/result.hbs",
"app/templates/partial1.hbs"
],
"dest": "app/result.hbs"
}]
}
added "app/result.hbs" to second source set, as was pointed out in the comments.
Thanks.
Solution
After some debugging I came up with a solution. Certainly not the best, but it works fine, as it should.
I edited the concat.js plugin file inside the node_modules folder the following way:
grunt.registerMultiTask('concat', ...){
var self = this;
//several lines of code
//...
//replace f.src.filter(..) wtih
self.data.src.filter(..);
}

Categories