Tags

, , , ,

When working with any project, large or small, I almost always break up the source into different files in order provide clarity and maintain small working components. So you usually find a few different files under the src folder of my projects: JavaScript files, HTML files and CSS files – all of which are then embedded into a single file by the build process.


Oct. 17, 2015: Check out the quick video below from Webucator inspired by this post. Webucator is a company offering onsite and online web training. I’m not associated with them, but have watched their Yourtube videos before and found them to be useful. 


When I started to work with Grunt, one of the first functions I needed was one that allowed me to embed the content of one file into another. The function works in conjunction with the grunt copy plugin as the ‘process’ option callback function. I needed this when:

– embedding JavaScript files into HTML files
– embedding CSS files into HTML files
– embedding HTML files into other HTML files
– embedding HTML, CSS files into a JavaScript files

The widgets and plugins I create are often used by simply including a script into the page. That JavaScript file includes everything needed to provide the functionally. In the source file, I often have variables defined that will hold the content of other files. For Example: in this code sample, the content of a file called ui-template.html will replace the token show below (inside the quotes):

var uiTemplate = "//BUILD_INCLUDE('./ui-template.html')[asJsString]";

The function recognizes the following tokens:

//BUILD_INCLUDE()
/* BUILD_INCLUDE() */
<!-- BUILD_INCLUDE() -->

Just include these in the various files that need content embedded and then define a grunt copy task that uses this function as the callback to the ‘process’ option. In addition to these tokens, options can be passed along by wrapping them in square-brackets. One the options in the example above is asJsString, which essentially takes the content of the given file and formats it as a JavaScript string – ideal for embedding into JavaScript files. Right now, this is the only option supported. Note that when using it to embed content as a JavaScript string, it is assumed that the content will be embedded within double-quotes, as shown in the example above.

The name of the file to be included can also use normal Grunt template tokens, so you could do something like this:

// BUILD_INCLUDE('<%= buildDir %>/src/file1.js')

Here is the full function code, hosted as a gist at Github:

Usage Example

Here is a full example of how to use this function. Suppose you have the following files:

demo/myPlugin.html
src/myPlugin.js
src/template.html
src/styles.css
Gruntfile.js

The demo/myPlugin.html contains the following:

<script>
    //BUILD_INCLUDE('dist/myPlugin.js')
</script>

The src/myPlugin.js contains the following:

var setup = {
    template: "//BUILD_INCLUDE('src/template.html')[asJsString]",
    styles: "//BUILD_INCLUDE('src/styles.css')[asJsString]"
}; 

The above setup object will have its properties values replaced with the content of files in src/template.html and src/styles.css respectively. Note the use of asJsString option at the end of the build include string.

The Gruntfile.js includes the function below and defines a copy target similar to the following:


// includeFile function is define above this code

grunt.initConfig({
    copy: {
        build: {
            options: {
                expand: true,
                process: includeFile
            },
            files: {
                "src/myPlugin.js": "dist/myPlugin.js",
                "demo/myPlugin.html": "dist/myPlugin.html"
            }
        }
    },
});

Running grunt copy will generate a dist/myPlugin.js that includes both the HTML and the CSS file content assigned to the variables shown above. It will also generate dist/myPlugin.html that also includes the content of the dist/myPlugin.js file.

If wanting to look at a working example of this in a real project, take a look at my jquery.todoList plugin over at github. It uses this approach to build the distribution files.

Quick Video