Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for a wrapper 'template'. #14

Open
sorahn opened this issue Oct 9, 2013 · 3 comments
Open

Support for a wrapper 'template'. #14

sorahn opened this issue Oct 9, 2013 · 3 comments

Comments

@sorahn
Copy link

sorahn commented Oct 9, 2013

I'm not entirely sure how it might be implemented, but I was wondering if it would be possible to make a kind of wrapper template file that would have a specific markup block for content in the middle that could get replaced.

window.myApp = (function () {
  'use strict';
  // some other content

  <%= wrapper.content %>
  // in my case, it's a concated set of files
})();
@stephanebachelier
Copy link

Not sure if I understand correctly but for this scenario, I think you can use grunt-contrib-concat to concatenate your set of files and then wrap the result.

And don't forget that you can use a function for the wrapper option. I use it to replace some string. An example below, where I wrap one file with a commonJS-like wrapper.

  wrap: {
      options: {
        separator: '\n',
        indent: '\t',
        header: 'window.require.define({"FILEPATH": function (exports, require, module) {',
        footer: '\n}});',
        wrapper: function(filepath, options) {
          var matches = filepath.match(new RegExp('\/scripts\/(.*).js$'));
          var path = matches ? matches[1] : filepath;
          return [options.header.replace(/FILEPATH/, path), options.footer];
        }
      },
      module: {
        files: [{
          expand: true,
          cwd: 'scripts',
          src: ['**/*.js'],
          dest: 'scripts'
        }]
      }

In this case I wrap each *.js file from scripts dir. But it's easy to wrap a concatenation of files.

@sorahn
Copy link
Author

sorahn commented Oct 23, 2013

Oh, interesting, I bet I could do something clever with having grunt read a file, for "header" then just having a function match a replacement inside that header, then just return that for the wrapper.

@rudylattae
Copy link

Hope I'm not late to the party. I am also interested in being able to reference a file that will be used as the wrapper or rather "container" for some lump of code.

My specific use case is a current project where I'm creating a library that would be shipped in a few different ways to allow usage in different js environments. In this case I would prefer to not include multiple headers/footers in my Gruntfile. Actually I think it would even help remove the need for the banner in the Gruntfile as well.

I can understand that it's not really high on anyone's radar considering there is a way to do this with the header/footer options in grunt-wrap and the banner/footer options in concat. I just want to separate concerns a little better and also properly lint my "wrapping" js files.

Here is an example of the option I need (I think this is what @drbrts wants as well.

Gruntfile.js

pkg: grunt.file.readJSON('package.json'),
meta: {
  banner: '/*! <%%= pkg.title || pkg.name %> - v<%%= pkg.version %> - ' +
        '<%%= grunt.template.today("yyyy-mm-dd") %>\n' +
        '* Copyright (c) <%%= grunt.template.today("yyyy") %> <%%= pkg.author.name %>;'
},

wrap: {
  options: {
    separator: '\n'
  },
  window: {
    src: ['src/*.js'],
    dest: 'dist/<%= pkg.name %>.js',
    options: {
      template: 'wrap/window.js' 
    }
  },
  amd: {
    src: ['src/*.js'],
    dest: 'dist/<%= pkg.name %>.js',
    options: {
      template: 'wrap/amd.js' 
    }
  }

  // ... more "environment" targets here
}

Some additional context. This is what a possible project setup could be:

my-micro-lib-project/
  src/
    core.js
    otherStuff.js
  wrap/
    amd.js
    common.js
    harmony.js
    window.js
  Gruntfile.js

And if we looked into a few of the wrapper files we see:

window.js

<%= meta.banner %>
window.<%= pkg.name %> = (function () {
  'use strict';

  // ** MARKER ** //

  // "export" public API
  return myLibNamespace

})();

amd.js

<%= meta.banner %>
(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(['b'], factory);
  } else {
    // Browser globals
    root.<%= pkg.name %> = factory(root.b);
  }
}(this, function (b) {

  // ** MARKER ** //;

  // "export" public API
  return myLibNamespace
}));

harmony.js

<%= meta.banner %>

// ** MARKER ** //;

// "export" public API
export myLibNamespace

Not looking to jump the gun, but I gave this a bit of thought and here's a naive pseudo-implementation that I imagine could make this feature a reality:

grunt.registerMultiTask('log', 'Log stuff.', function() {
  grunt.log.writeln(this.target + ': ' + this.data);
});

grunt.registerMultiTask('wrap', 'Wrap files.', function () {

  // <snip> do regular pre-wrap stuff

  var wrap = function (filepath, options) {
    var template = options.template;

    if (typeof template !== 'undefined') {
      var raw = grunt.file.read(template),  // read the template contents
          processed = grunt.template.process(template) // process it

      // `processed` is now available to be used as the container in which 
      // the spcified files would be injected. The spot where file contents 
      // are injected into would be marked like so: "// ** MARKER ** //"
    }

    // <snip> function based wrapping etc.
  };
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants