0.1.2 • Published 10 years ago

grunt-local2cdn v0.1.2

Weekly downloads
4
License
-
Repository
github
Last release
10 years ago

grunt-local2cdn

A Grunt plugin to convert local URLs to CDN ones in html files(or the like, e.g. .ejs,.jsp,.jade).

It gets some inspiration from grunt-cdnify(by @callumlocke)

What it does

The task looks through your specified files for URLs to modify, in the following places:

  • <img src="____">
  • <script src="____"></script>
  • <link rel="stylesheet" href="____">
  • background-image: url(____); in your CSS (including inside <style> tags in your HTML)

It will ignore web urls and images with data URI format, e.g. http://www.example.com/foo.png, data:image/png;base64,iVBORw0KGgoAAAANS...

Getting Started

This plugin requires Grunt ~0.4.0

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-local2cdn --save-dev

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

grunt.loadNpmTasks('grunt-local2cdn');

The "local2cdn" task

Overview

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

grunt.initConfig({
  local2cdn: {
    options: {
      // Task-specific options go here.
    },
    your_target: {
      // Target-specific file lists and/or options go here.
    },
  },
});

Options

options.prefix

Type: [Optional]String Default value: ''

The base url of CDN, e.g. http://cdn.bootcss.com. It will prepend to all the CDN urls in options.maps. For some special urls, you can overwrite it, see options.maps bellow.

options.maps

Type: [Required] Object|Array of Objects Default value: null

It defines the maps of local urls and cdn urls. You must specify it youself.

It supports two formats:

Simple format:

An object constituted by key/value maps, the key is the local url, and the value is the CDN url.

{
    'jquery.js': 'jquery/2.0.3/jquery.min.js',
    'bootstrap.js': 'bootstrap/3.1.1/js/bootstrap.min.js',
    'bootstrap.css': '/bootstrap/3.1.1/css/bootstrap.min.css',
    'foo.png': '/xxx/foo.png',
    'foo.jpg': '/xxx/foo.jpg',
    'foo.gif': '/xxx/foo.gif',
    'foo.tif': '/xxx/foo.tif:image'
}

Advanced format:

An array constituted by objects. You can overwrite some options(prefix, regex, separator) in each object. local and cdn properties are required, prefix, regex, separator, srcType properties are optional.

[
   {local: 'jquery.js', cdn: 'jquery/2.0.3/jquery.min.js', prefix:'//cdn.a.com', regex:true, srcType:'image'},
   {local: 'bootstrap.js', cdn: 'bootstrap/3.1.1/js/bootstrap.min.js', prefix:'http://cdn.2.org', regex:true},
   {local: 'bootstrap.css', cdn: '/bootstrap/3.1.1/css/bootstrap.min.css'},
   {local: 'foo.png', cdn: '/xxx/foo.png', prefix:'http://cdn.3.org'},
   {local: 'foo.jpg', cdn: '/xxx/foo.jpg'},
   {local: 'foo.gif', cdn: '/xxx/foo.gif'},
   {local: 'foo.tif', cdn: '/xxx/foo.tif', srcType:'image'},
   {local: '^aabbcc', cdn: '/xxx/foo.pic?123#$#image', separator:'#$#',  regex:true}
]

options.regex

Type: [Optional]Boolean Default value: false

Whether local url in options.maps supports RegExp or not. If true, the final RegExp used to match will be new RegExp(localUrl, 'ig'); If false, the final RegExp used to match will be new RegExp(escapeRegExChars(localUrl)+'\\s*$', 'ig');

The plugin will stop searching in options.maps as long as it find a match. When options.regex==false, if the localUrl in a map is the tail of the original url, it will matchs. So, you must take care of the situation:

maps:{
  ...
  'bootstrap.css': 'http://cdn.example.com/bootstrap.min.css',
  ...  
  'typeahead.bootstrap.css': 'http://cdn.example.com/typeahead.bootstrap.min.css',
  ...
}
  ...
  <link href="/libs/typeahead/typeahead.bootstrap.css" rel="stylesheet">
  ...

The original url will match bootstrap.css incorrectly, not the correct one typeahead.bootstrap.css. To avoid this, there are some solutions:

  • put the typeahead.bootstrap.css map before the bootstrap.css map;
  • change the maps to /bootstrap.css and /typeahead.bootstrap.css;
  • set options.regex to true, and change the localUrls to customed regex formats;

It can be overwrote in options.maps.

options.separator

Type: [Optional]String Default value: ':'

The plugin needs to know the source type(image,css,js) of each url. It will detect the source type from local url or CDN url by the source file extension. e.g.:

'jquery.js': 'jquery/2.0.3/jquery.min.js' --> srcType will be 'js';

'bootstrap.css': '/bootstrap/3.1.1/css/bootstrap.min.css' --> srcType will be 'css';

'foo.png': '/xxx/foo.png' --> srcType will be 'image', the plugin can detect source type from these image types:'png','gif','jpeg','jpg','ico','bmp','svg'

If there is a map: 'foo.tif': '/xxx/foo.tif', the plugin cannot detect the source type, and then you need to explicitly specify the source type of this resource, juest append separator and the type to the end of CDN url, that is 'foo.tif': '/xxx/foo.tif:image', it will works as an image url.

The plugin detect source type in this order: CDN url affix(separator+type) --> CDN url --> local url

It will stop detecting as long as it got a valid type.

When detecting, query and id locator will be ignored. e.g.:
/xxx/foo.png?v=12345 will be treat as /xxx/foo.png

It can be overwrote in options.maps.

options.converter

Type: [Optional]Function Default value: A built-in function

A function convert the oldUrl(local url) to finalUrl(usually is a cdn url). It must return a string. And it has three parameters:oldUrl, srcType, converter. The first parameter oldUrl is the origin url of the current resource; The second parameter srcType is the source type of the current resource, it is a string value of image|js|css; The third parameter converter is the built-in convert function.

If ignore, the built-in convert function will be used.

e.g.:

...
options: {
  ...
  converter: function(oldUrl, srcType, converterURL){
    if(oldUrl.indexOf('data:') === 0)
      return url; // leave data URIs untouched
    else if(oldUrl.indexOf('http') === 0)
      return url + '?12345'; // add query string to all other URLs
    else 
      return converterURL(oldUrl, srcType);
  }
  ...
}
...

Usage Examples

Example 1

local2cdn: {
  main: {
    options: {
      maps: {
        "/jquery.js": "http://libs.baidu.com/jquery/1.10.2/jquery.min.js",
        "/bootbox.js": "http://cdn.staticfile.org/bootbox.js/4.1.0/bootbox.min.js",
        "/bootstrap.js": "http://libs.baidu.com/bootstrap/3.0.3/js/bootstrap.min.js",
        "/bootstrap.css": "http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.min.css",           
        "/underscore.js": "http://cdn.staticfile.org/underscore.js/1.5.2/underscore-min.js"
      }
    },
    files: [
      {
        expand: true,
        cwd: 'test/src/',
        src: '**/*.{css,html,ejs}',
        dest: 'test/dist/'
      }
    ]
  }
}

Example 2

grunt.initConfig({
  local2cdn: {
    main: {
      options: {
        prefix: 'http://cdn.bootcss.com/',
        maps: {
            'jquery.js': 'jquery/2.0.3/jquery.min.js',
            'bootstrap.js': 'bootstrap/3.1.1/js/bootstrap.min.js',
            'bootstrap.css': '/bootstrap/3.1.1/css/bootstrap.min.css',
            'foo.png': '/xxx/foo.png',
            'foo.jpg': '/xxx/foo.jpg',
            'foo.gif': '/xxx/foo.gif',
            'foo.tif': '/xxx/foo.tif:image'
        }
      },
      files: [
        {
          expand: true,
          cwd: 'test/src',
          src: '**/*.{css,html,ejs}',
          dest: 'test/dist'
        }
      ]
    }//eof:local2cdn:main target
  }//eof:local2cdn task
});

The src file test/src/sample.html maybe like:

<html>
  <head>
    <style>
      body {
        background-image: url('foo.jpg');
        background-image: url("foo.jpg");
        background-image: url(foo.jpg);
        background-image: url('/foo.png');
        background-image: url('bar/foo.png');        
        background-image: url('http://demo.com/bar/foo.png');
        background-image: url('../foo.gif');
        background-image: url('foo/bar.jpg');
        background-image: url('data:gif; base64XQTRTWEQW');
      }
    </style>
    <!-- Bootstrap Core-->
    <link href="/libs/bootstrap/css/bootstrap.css" rel="stylesheet">
  </head>  
  <body>
    <img something src="foo.jpg" data-cc data-dd="1111">
    <img src=foo/bar.png so="what" />
    <img src="/foo.gif" something=xxx  >
    <img src="http://demo.com/bar/foo.png" something=aaa  >
    <img src="bar/foo.png" something=yyy  >    
    <img src="bar/foo.tif" />
    <!-- jquery.js -->
    <script src="/libs/jquery.js"></script>
    <script src="/libs/bootstrap/js/bootstrap.js"></script>
  </body>
</html>
 ...

and the dest file 'test/dist/sample.html' will like:

<html>
  <head>
    <style>
      body {
        background-image: url('http://cdn.bootcss.com/xxx/foo.jpg');
        background-image: url("http://cdn.bootcss.com/xxx/foo.jpg");
        background-image: url(http://cdn.bootcss.com/xxx/foo.jpg);
        background-image: url('http://cdn.bootcss.com/xxx/foo.png');
        background-image: url('http://cdn.bootcss.com/xxx/foo.png');        
        background-image: url('http://demo.com/bar/foo.png');
        background-image: url('http://cdn.bootcss.com/xxx/foo.gif');
        background-image: url('foo/bar.jpg');
        background-image: url('data:gif; base64XQTRTWEQW');
      }
    </style>
    <!-- Bootstrap Core-->
    <link href="http://cdn.bootcss.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
  </head>  
  <body>
    <img something src="http://cdn.bootcss.com/xxx/foo.jpg" data-cc data-dd="1111">
    <img src=foo/bar.png so="what" />
    <img src="http://cdn.bootcss.com/xxx/foo.gif" something=xxx  >
    <img src="http://demo.com/bar/foo.png" something=aaa  >
    <img src="http://cdn.bootcss.com/xxx/foo.png" something=yyy  >    
    <img src="http://cdn.bootcss.com/xxx/foo.tif" />
    <!-- jquery.js -->
    <script src="http://cdn.bootcss.com/jquery/2.0.3/jquery.min.js"></script>
    <script src="http://cdn.bootcss.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
  </body>
</html>

Hot CDNs:

China

International

Release History

  • 2014-04-05 v0.1.2
0.1.2

10 years ago

0.1.1

10 years ago

0.1.0

10 years ago