Created
February 5, 2015 14:44
-
-
Save eschwartz/9876bb8166d1a98d483b to your computer and use it in GitHub Desktop.
A grunt task for when you need to use RequireJS `paths` config in a TypeScript project.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = function(grunt) { | |
var path = require('path'); | |
grunt.registerMultiTask( | |
'tsd-amd', | |
'Generates a TypeScript definition file for a set of *.ts files. ' + | |
'The output will contain declared modules for every *.ts file, ' + | |
'which are named according to their AMD ids.', | |
function() { | |
var options = this.options({ | |
// path aliases | |
paths: {}, | |
template: 'declare module "{amdId}" {\n' + | |
'\timport X = require("{requirePath}");\n' + | |
'\texport = X;\n' + | |
'}\n\n' | |
}); | |
this.files.forEach(function(fileObj) { | |
var amdModuleDeclarations = fileObj.src. | |
reduce(function(str, srcPath) { | |
var amdId = filePathToAmd(srcPath, options.paths, '.ts'); | |
var requirePath = withoutExt( | |
relativePath(fileObj.dest, srcPath), | |
'.ts' | |
); | |
return str + options.template. | |
replace('{amdId}', amdId). | |
replace('{requirePath}', requirePath); | |
}, ''); | |
grunt.file.write(fileObj.dest, amdModuleDeclarations); | |
}); | |
/** | |
* Convert a file path to an AMD module id. | |
* | |
* @param {string} filePath | |
* @param {Object} pathAliases as { 'alias-name': 'some/file/path' } | |
* @param {string} ext file extension | |
* @return {string} | |
*/ | |
function filePathToAmd(filePath, pathAliases, ext) { | |
return Object.keys(pathAliases). | |
reduce(function(amdId, alias) { | |
var path = options.paths[alias]; | |
var isMatchingAlias = amdId.indexOf(path) === 0; | |
if (isMatchingAlias) { | |
return amdId.replace(path, alias); | |
} | |
}, withoutExt(filePath, ext)); | |
} | |
function withoutExt(path, ext) { | |
return path.split(ext)[0]; | |
} | |
function relativePath(from, to) { | |
var relDir = path.relative( | |
path.dirname(from), | |
path.dirname(to) | |
); | |
return relDir ? | |
[relDir, path.basename(to)].join('/') : | |
path.basename(to); | |
} | |
} | |
) | |
; | |
}; |
Important note:
The reason I have not published a repo for this grunt task is that it is not really in "finished" form. That is to say, there are no tests and I have only used it under very specific conditions.
So use at your own risk, and consider this more of a jumping-off point than a completed library. As soon as I need to use it on another project, or I run into a use case I didn't account for, I'll probably break it off into its own project. If anyone wants to take a shot at adapting this into their own thing, I hereby grant you permission to do so.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example usage:
Let's say you have a file structure like:
running `grunt ts-amd:lib' will generate a file like this:
Which will allow you to reference your AMD modules in a RequireJS compatible (non-relative) way: