[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Support via Gratipay][gratipay-image]][gratipay-url]
This library will replace local file references in HTML and other files with CDN locations. This allows you to work with local copies of libraries during development, and then automate switching to your CDN version when you deploy your application.
For example, if you have a development file that looks like this:
<html>
<head>
<script type="text/javascript" src="https://github.com/OverZealous/cdnizer/raw/v3.3.0/bower_components/angular/angular.js"></script>
…
You can use cdnizer to automatically convert it to this during your build process (every change here can be customized):
<html>
<head>
<script>
function cdnizerLoad(u) {
document.write('<scr'+'ipt src="https://github.com/OverZealous/cdnizer/raw/v3.3.0/'+encodeURIComponent(u)+'"></scr'+'ipt>';
}
</script>
<script type="text/javascript" src="https://github.com/OverZealous/cdnizer/raw/v3.3.0/ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<script>if(!(angular)) cdnizerLoad("bower_components/angular/angular.js");</script>
…
If you want to use this library inside a gulp stream, gulp-cdnizer has you covered.
node_modules and bower_components, and you don't want to use node_modules, you'll need to set the nodeModules property to false in the general config, or set ignoreNodeModules to true in the per-package config.allowRev is turned off by default, since it causes too many unexpected errors.cdnizer now can load CDN data from existing *-cdn-data packages, currently google-cdn-data, cdnjs-cdn-data, and jsdelivr-cdn-data. Now you can configure common public CDNs with a single line!
Possible breaking change in 1.0
The version field has been changed in this release. Previously, it was the exact version as it existing within Bower. Now, version is the string major(.minor)?(.patch)?, with any trailing (-beta*, -snapshot*, etc) information removed. (Alpha-numeric characters that are attached to the version string, as in 1.0.0rc1, are not stripped.)
You can still access the full version string via versionFull, which is not modified at all.
First, install cdnizer:
npm install --save cdnizer
Then, use it like so:
var cdnizerFactory = require("cdnizer");
var cdnizer = cdnizerFactory({
defaultCDNBase: "//my.cdn.host/base",
allowRev: true,
allowMin: true,
files: [
// This file is on the default CDN, and will replaced with //my.cdn.host/base/js/app.js
'js/app.js',
// On Google's public CDN
{
file: 'vendor/angular/angular.js',
package: 'angular',
test: 'window.angular',
cdn: '//ajax.googleapis.com/ajax/libs/angularjs/${ version }/angular.min.js'
},
// On Firebase's public CDN
{
file: 'vendor/firebase/firebase.js',
test: 'window.Firebase',
cdn: '//cdn.firebase.com/v0/firebase.js'
}
]
});
// Load the file
var contents = fs.readFileSync('./src/index.html', 'utf8');
// Replace the file's contents
contents = cdnizer(contents);
Alternatively, you can just pass in the files array if you don't need to provide any options, and only have custom files:
var cdnizerFactory = require("cdnizer");
var cdnizer = cdnizerFactory([
{
file: 'vendor/angular/angular.js',
package: 'angular',
test: 'window.angular',
// use alternate providers easily
cdn: '//cdnjs.cloudflare.com/ajax/libs/angularjs/${ version }/angular.min.js'
},
{
file: 'vendor/firebase/firebase.js',
test: 'window.Firebase',
cdn: '//cdn.firebase.com/v0/firebase.js'
}
]);
You can also use globs to define groups of file, and dynamic filename properties:
var cdnizerFactory = require("cdnizer");
var cdnizer = cdnizerFactory([{
file: 'vendor/angular/*.js',
package: 'angular',
test: 'window.angular',
cdn: '//ajax.googleapis.com/ajax/libs/angularjs/${ version }/${ filenameMin }'
}]);
Works great on url()s in CSS files, too:
var cdnizerFactory = require("cdnizer");
var cdnizer = cdnizerFactory({
defaultCDNBase: '//my.cdn.url/',
relativeRoot: 'css',
files: ['**/*.{gif,png,jpg,jpeg}']
});
var cssFile = fs.readFileSync('./css/style.css', 'utf8');
cssFile = cdnizer(cssFile);
New in v1.0, you can use simplified strings for common public CDNs, like so:
var cdnizerFactory = require("cdnizer");
var cdnizer = cdnizerFactory([
'google:angular', // for most libraries, that's all you'll need to do!
'cdnjs:jquery',
{
cdn: 'jsdelivr:yui', // You can also use a known CDN, while…
package: 'yui3', // overriding the package name for Bower, and…
test: 'window.YUI' // providing a custom fallback test
},
// you can also specify alternate files within a package:
'jsdelivr:yui:anim-base/anim-base-min.js@3.17.2'
]);
Need multiple files from the one package on a common CDN? Here's two solutions:
// Manually list every file…
var cdnizerFactory = require("cdnizer");
var cdnizer = cdnizerFactory([
'cdnjs:angular.js:angular.min.js',
'cdnjs:angular.js:angular-touch.min.js',
'cdnjs:angular.js:i18n/angular-locale_fr-fr.js'
]);
// Or wire up a pattern:
var cdnizerFactory = require("cdnizer");
var cdnizer = cdnizerFactory([
// matches all root angular files
{
file: '**/angular/*.js',
cdn: 'cdnjs:angular.js:${ filenameMin }' // Yes, you can apply patterns to the filename!
},
// matches all i18n angular files
{
file: '**/angular/i18n/*.js',
cdn: 'cdnjs:angular.js:i18n/${ filename }' // These i18n files are not minified
}
]);
Creates a new cdnizer function that can be used to process file contents. You can either pass in a configuration object, or you can pass in an array of files if you don't need to change the default shared options.
See Usage above for examples.
Type: String
Default: '' (disabled)
Used for a default, custom CDN, usually for your own files. This will be used in the defaultCDN property to define the default path for a CDN unless overridden.
Type: String
Default: '${ defaultCDNBase }/${ filepathRel }'
This is the default pattern used for generating CDN links when one isn't provided by a specific file.
Type: String
Default: ''
If you are processing a file that references relative files, or is not rooted to the CDN, you must set relativeRoot to get correct results. This relative path will be appended to the file path and the path resolved to remove relative URLs.
For example, if you have a CSS file at style/main.css, and you reference images as ../img/foo.png, you should set relativeRoot to 'style/'. Now if your defaultCDNBase is //example/, the image will be resolved to //example/img/foo.png.
If you do not set relativeRoot when referencing relative files, your files will not match, and they will not be replaced with CDN URLs.
Type: Boolean
Default: false
Allow for file names with gulp-rev appended strings, in the form of <file>-XXXXXXXX.<ext>. If you are using the gulp-rev plugin, this will automatically match filenames that have a rev string appeneded to them. If you are not using gulp-rev, then you can disable this by setting allowRev to false, which will prevent possible errors in accidentally matching similar file names.
You can always manually configure your globs to include an optional rev string by using the form ?(<rev glob here>), such as name?(-????????).ext for appended revs.
Type: Boolean
Default: false
Allow for file names that optionally have .min inserted before the file extension (but after rev, if enabled). This allows you to use the base name for a file, and have cndizer match the minified name.
Type: String
Default:
<script>
function cdnizerLoad(u) {
document.write('<scr'+'ipt src="https://github.com/OverZealous/cdnizer/raw/v3.3.0/'+encodeURIComponent(u)+'"></scr'+'ipt>';
}
</script>
Overwrite the default fallback script. If any of the inputs has a fallback, this script is injected before the first occurrence of <link, <script, or </head> in the HTML page. Ignored for files that don't contain <head.
If you already have a script loader (such as yepnope or Modernizr), you can set this to an empty string and override the fallbackTest below to use that instead. Of course, this won't help if you are loading those scripts off a CDN and they fail!
Type: String
Default: '<script>if(!(${ test })) cdnizerLoad("${ filepath }");</script>'
Overwrite the default fallback test. Note that all options availble to options.files[].cdn below are available to this template as well, along with the options.files[].test string.
Type: String|Boolean
Default: null
If provided, this is the directory to look for node modules in. If not provided, and there's no existing bower configuration, cdnizer will fall back to node_modules.
If this is set to false, it will not look in node_modules at all.
Once the directory is determined, the script will look for files in <nodeModules>/<package>/package.json to try to determine the version of the installed component.
Type: String
Default: null
If provided, this is the directory to look for Bower components in. If not provided, cdnizer will attempt to look for the .bowerrc file, and if that is not found or does not specify a directory, it falls back to './bower_components'. If that's not found, cdnizer falls back to node_modules.
Once the directory is determined, the script will look for files in <bowerComponents>/bower.json or <bowerComponents>/.bower.json to try to determine the version of the installed component.
Type: Array
Default: []
Array of custom matchers. Use this to add extra patterns within which you would like to cdn-ize URLs, for example if you have such URLs in data-attributes. The matchers should include regular expressions with three matching groups:
Example (matches the data-src attribute in <img> tags):
matchers: [
{
pattern: /(<img\s.*?data-src=["'])(.+?)(["'].*?>)/gi,
//groups: ( leading )(url)(trailing)
fallback: false
}
]
You can also specify just a regular expression. In that case, fallback will default to false.
Equivalent example:
matchers: [
/(<img\s.*?data-src=["'])(.+?)(["'].*?>)/gi
]
Type: Array
Default: []
Future-proof option to add additional *-cdn-data packages. These packages must be in the same format as google-cdn-data. The format is to only include the leading part of the package name, for example, cdnjs-cdn-data would be included as simply 'cdnjs'.
Type: Boolean
Default: false
In some cases you may have third party of vendor libraries already loaded off a CDN or remote URL that you don't want re-written.
For example given a config like this
var cdnizerFactory = require("cdnizer");
var cdnizer = cdnizerFactory({
files: ['**/*.js', '**/*.css'],
defaultCDNBase: '//examplecdn/',
excludeAbsolute: true
});
And an index.html like this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<link href="http://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
</head>
<body>
<h1>Hello World</h1>
<script src="https://github.com/OverZealous/cdnizer/raw/v3.3.0/js/app/app.js"></script>
</body>
</html>
With this flag enabled cdnizer will avoid re-writing these kind of paths.
```html
$ claude mcp add cdnizer \
-- python -m otcore.mcp_server <graph>