npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

grunt-concat-in-order

v0.3.0

Published

Concatenates files respecting declared, required dependencies order.

Downloads

610

Readme

grunt-concat-in-order

Concatenates files respecting dependencies.

Getting Started

This plugin requires Grunt ~0.4.1

If you haven't used Grunt before, be sure to check out the Getting Started guide, as it explains how to create a Gruntfile as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:

npm install grunt-concat-in-order --save-dev

Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:

grunt.loadNpmTasks('grunt-concat-in-order');

The "concat_in_order" task

Overview

The concat_in_order task extracts declared required dependencies as well as provided modules/classes from your javascript (or any other text) files. Having this dependency graph the task will perform topological sort and concatenate file so that all modules will be put after their required dependencies.

In your project's Gruntfile, add a section named concat_in_order to the data object passed into grunt.initConfig().

grunt.initConfig({
  concat_in_order: {
    your_target: {
      options: {
          /*
          this is the default banner prepended to the resulting file
          banner: '',
          this is a default function that extracts required dependencies/module names from file content
          (getMatches - function that pick groups from given regexp)
          extractRequired: function (filepath, filecontent) {
            return this.getMatches(/require\(['"]([^'"]+)['"]/g, filecontent);
          },
          this is a default function that extracts declared modules names from file content
          extractDeclared: function (filepath, filecontent) {
            return this.getMatches(/declare\(['"]([^'"]+)['"]/g, filecontent);
          }
          */
      },
      files: {
        'build/concatenated.js': ['lib/**/*.js']
      }
    }
  }
})

Sample

Let's say you have 4 files in a lib directory

  • AUsingBaseBAndBaseA.js
/*start AUsingBaseBAndBaseA*/
framwork.require('module.BaseB');
framwork.require('module.BaseA');
framework.declare('module.UsingBaseBAndBaseA');
var forth = function fourthFunction(){};
/*end AUsingBaseBAnddBaseA*/
  • AUsingBaseA.js
/*start AUsingBaseA*/
framwork.require('module.BaseA');
var second = function secondFunction(){};
/*end AUsingBaseA*/
  • BaseA.js
/*start BaseA*/
framework.declare('module.BaseA');
var first = function firstFunction(){};
/*end BaseA*/
  • BaseBUsingBaseA.js
/*start BaseBUsingBaseA*/
framwork.require('module.BaseA');
framework.declare('module.BaseBUsingBaseA');
framework.declare('module.BaseB');
var third = function thirdFunction(){};
/*end  BaseBUsingBaseA*/

Given the above configuration the task will produce build/concatenated.js file with following content:

/*start BaseA*/
framework.declare('module.BaseA');
var first = function firstFunction(){};
/*end BaseA*/
/*start BaseBUsingBaseA*/
framwork.require('module.BaseA');
framework.declare('module.BaseBUsingBaseA');
framework.declare('module.BaseB');
var third = function thirdFunction(){};
/*end  BaseBUsingBaseA*/
/*start AUsingBaseA*/
framwork.require('module.BaseA');
var second = function secondFunction(){};
/*end AUsingBaseA*/
/*start AUsingBaseBAndBaseA*/
framwork.require('module.BaseB');
framwork.require('module.BaseA');
framework.declare('module.UsingBaseBAndBaseA');
var forth = function fourthFunction(){};
/*end AUsingBaseBAnddBaseA*/

File based

You can enable automatic addition of files with the following example. (notice the onlyConcatRequiredFiles : true) This is the same way of declaring dependencies used by juicer

files: {
    'dist/mybuild.js': ['js/src/main.js']
},
options: {
    extractRequired: function(filepath, filecontent) {
        var workingdir = path.normalize(filepath).split(path.sep);
        workingdir.pop();

        var deps = this.getMatches(/\*\s*@depend\s(.*\.js)/g, filecontent);
        deps.forEach(function(dep, i) {
            var dependency = workingdir.concat([dep]);
            deps[i] = path.join.apply(null, dependency);
        });
        return deps;
    },
    extractDeclared: function(filepath) {
        return [filepath];
    },
    onlyConcatRequiredFiles: true
}

This will declare all files as modules using their filenames. In main.js you will typically have these depend statements:

/**
 * @depend ../lib/jquery.js
 * @depend otherfile.js
 * @depend calculator/add.js
 */

You only need to specify the main.js and the other dependencies will be added automatically. As well as their dependencies etc.

If you want to add a file that isn't referenced anywhere you need to add it manually.

files: {
    'dist/mybuild.js': ['js/src/main.js', 'js/src/unReferencedButWanted.js']
},

The option onlyConcatRequiredFiles will only work if modules are declared and required with their actual filenames.

Contributing

In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using Grunt.

Release History

  • 0.1.6 - @mokkabonna updated documenation and fixed path splitting in sample
  • 0.1.4 - @mokkabonna added ability to concat only files that are required by some module