-
Notifications
You must be signed in to change notification settings - Fork 780
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
feat(imports): add doT
template engine
#1024
Changes from 4 commits
bbcf13a
97acbce
27edc00
e19a494
ca335f6
046d270
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
/*eslint-env node */ | ||
const UglifyJS = require('uglify-js'); | ||
const assert = require('assert'); | ||
|
||
module.exports = grunt => { | ||
grunt.registerMultiTask( | ||
|
@@ -57,28 +58,84 @@ module.exports = grunt => { | |
/** | ||
* Process a given library to unwrapped UMD module if exists, and return the factory | ||
* @param {string} libName name of the library | ||
* @param {string} sourceUrl path to the distributable of the library | ||
* @param {string} sourceCode source code for the library | ||
* @param {Object} [options] Optional options | ||
* @property {Boolean} umd Does the library contain a UMD wrapper | ||
* @property {String} global The library's global (`window.myLibrary`) | ||
*/ | ||
const processImport = (libName, sourceUrl) => { | ||
const sourceCode = grunt.file.read(sourceUrl); | ||
if (hasUmdWrapper(sourceCode)) { | ||
const processImport = (libName, sourceCode, options) => { | ||
const hasUMD = options ? options.umd : hasUmdWrapper(sourceCode); | ||
const global = options && options.global; | ||
|
||
if (hasUMD) { | ||
// If the library has a "standard" UMD wrapper, we'll remove it | ||
// and expose the library directly. | ||
unwrappedCode(sourceCode, (err, factory) => { | ||
if (err) { | ||
// running uglifyjs transform in a try block, this is to catch any errors from the transform. | ||
throw new Error(err); | ||
} | ||
writeLibrary(libName, factory); | ||
}); | ||
} else if (global) { | ||
// We wrap the library's source code in an IFFE which voids | ||
// existing globals (module, define, process, etc.) forces and | ||
// forces it to export a global. | ||
// | ||
// This method should only be used for "universal" code that | ||
// follows the same code paths for all environments (Node, | ||
// browser, etc). If there are different paths for different | ||
// envs, the UMD method should be used instead. | ||
const wrappedLibrary = ` | ||
(function (module, exports, define, require, process) { | ||
// Get a reference to the "true" global scope. This works in | ||
// ES5's "strict mode", browsers, node.js and other environments. | ||
var global = Function('return this')(); | ||
|
||
// If there was a global prior to our script, make sure we | ||
// "save" it (think "$.noConflict()"). | ||
var __old_global__ = global["${global}"]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are two There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The passed To be sure its reset, see a few LOC below. |
||
|
||
${sourceCode} | ||
|
||
// Preserve a reference to the library and remove it from | ||
// the global scope. | ||
var lib = global["${global}"]; | ||
delete global["${global}"]; | ||
|
||
// Reset a previous global when applicable. | ||
if (__old_global__) { | ||
global["${global}"] = __old_global__; | ||
} | ||
|
||
// Return the library to populate "axe.imports". | ||
return lib; | ||
})(); | ||
`; | ||
writeLibrary(libName, wrappedLibrary); | ||
} else { | ||
// assumption is that the library returns an IIFE | ||
writeLibrary(libName, sourceCode); | ||
} | ||
}; | ||
|
||
// Iterate through each library to import and process the code | ||
Object.keys(this.data).forEach(key => { | ||
processImport(key, this.data[key]); | ||
}); | ||
for (const name in this.data) { | ||
const val = this.data[name]; | ||
if (typeof val === 'string') { | ||
// Provided a path to a file with no options | ||
const sourceCode = grunt.file.read(val); | ||
processImport(name, sourceCode); | ||
} else if (typeof val === 'object') { | ||
// Provided an object with options | ||
const { file, umd, global } = val; | ||
assert(file, 'File required'); | ||
const sourceCode = grunt.file.read(file); | ||
processImport(name, sourceCode, { umd, global }); | ||
} else { | ||
grunt.fail.warn(`Unsupported generate-import: "${name}"`); | ||
} | ||
} | ||
} | ||
); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, what's the distinction between
param
andproperty
here in jsdoc?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
property
is a member of the aboveparam