Search code examples
htmlgruntjsgrunt-contrib-watchgrunt-contrib-concat

concatenating several files into single file and having one link


Let's say, I concatenate file1.js, file2.js and file3.js into one file filesaltogether.js and this new file will be copied from dev to dist of the project.

Now, how should the three links to these three files; ie <scipt src="file1.js">...<script src="file3.js"> get converted to one link to this new file filesaltogether.js not by hand in the index.html file in the dist folder of the project


Solution

  • how should the three links to these three files; ie <link href="file1.js">...<link href-"file3.js" get converted to one link to this new file filesaltogether.js...

    Firstly, <link href="file1.js"> is not a valid way to link your JavaScript files to your html documents.

    See the answer here for more info on how the <link> tag is used.

    The examples below show the correct syntax for linking JavaScript files to a html document:

    <script type="text/javascript" src="file1.js"></script>
    

    ...or without the type attribute, as the type is assumed to be JavaScript if not defined in HTML5.

    <script src="file1.js"></script>
    

    Therefore, my following answer assumes that what you really mean is how can the three <script> tags get converted to one <script> tag.

    To achieve this there is a useful grunt plugin called grunt-processhtml

    This plugin allows you to add special comments to your html markup which then get processed by Grunt. For your requirement you would add the following comments to your source .html markup:

    <!--build:js filesaltogether.js-->
    <script type="text/javascript" src="file1.js"></script>
    <script type="text/javascript" src="file2.js"></script>
    <script type="text/javascript" src="file3.js"></script>
    <!--/build-->
    

    The comment <!--build:js filesaltogether.js--> basically says replace all the proceeding script tags with one. The resultant output would be:

    <script type="text/javascript" src="filesaltogether.js"></script>
    

    You can also define the src path inside the comment. E.g.

    <!--build:js path/to/file/filesaltogether.js-->
        <script type="text/javascript" src="file1.js"></script>
        <script type="text/javascript" src="file2.js"></script>
        <script type="text/javascript" src="file3.js"></script>
    <!--/build-->
    

    would result in:

    <script type="text/javascript" src="path/to/file/filesaltogether.js"></script>
    

    In addition to adding the special comments to your html markup you will also need to add a processhtml task in your Gruntfile.js of course.

    The example below would:

    1. Concatenate the three JavaScript files and output a file named filesaltogether.js to the js folder inside the dist folder
    2. Replace the special comments inside the html file with a single <script> tag linking to the concatenated JavaScript file.

    NOTE: You will need to edit the file paths according to your project directory setup.

    module.exports = function (grunt) {
    
        grunt.initConfig({
    
            pkg: grunt.file.readJSON('package.json'),
    
            /* CONCATENATE JAVASCRIPT*/
            concat: {
                js: {
                    src: [
                        'dev/js/file1.js',
                        'dev/js/file2.js',
                        'dev/js/file3.js'
                    ],
                    dest: './dist/js/filesaltogether.js'
                }
            },
    
            /* PROCESS THE SPECIAL COMMENTS IN THE HTML */
            processhtml: {
                replaceScriptLinks: {
                    files: {
                        './dist/index.html': ['./dev/index.html'] // destination : source
                    }
                }
            }
    
        });
    
    
        grunt.loadNpmTasks('grunt-contrib-concat');
        grunt.loadNpmTasks('grunt-processhtml');
    
        grunt.registerTask('default', [
            'concat:js',
            'processhtml:replaceScriptLinks'
        ]);
    
    };
    

    Hope this helps!