|
/** |
|
* Codemod to replace templateUrl with imported templates. |
|
* |
|
* Example: |
|
* |
|
* ``` |
|
* angular.module('myapp').component('myappDialog', { templateUrl: '/partials/dialog.html' }); |
|
* |
|
* => |
|
* |
|
* import template from '/partials/dialog.html'; |
|
* angular.module('myapp').component('myappDialog', { template }); |
|
* ``` |
|
* |
|
* References |
|
* * https://github.com/cpojer/js-codemod/blob/master/transforms/object-shorthand.js |
|
* |
|
* @author Francesco Disperati |
|
* @since 2018-01-03 |
|
*/ |
|
function transformer (file, api) { |
|
const j = api.jscodeshift; |
|
|
|
let root = j(file.source); |
|
let stats = { count: 0 }; |
|
|
|
return root |
|
.find(j.ObjectExpression) |
|
.find(j.Property) |
|
.filter(p => filterTemplateUrl(p, stats)) |
|
.forEach(p => { |
|
let templateName = getTemplateName(j, p.node); |
|
let templatePath = `../../partials/${templateName}`; |
|
|
|
addImportTemplateAtFileTop(j, root, templatePath); |
|
|
|
// Replace property with key shorthand |
|
p.value.key = 'template'; |
|
p.value.shorthand = true; |
|
}) |
|
.toSource({ |
|
quote: 'single', |
|
reuseWhitespace: false |
|
}); |
|
} |
|
|
|
function filterTemplateUrl(path, stats) { |
|
if (path.node.key.name == 'templateUrl') { |
|
stats.count += 1; |
|
// We assume there is no more than 1 template per file |
|
if (stats.count > 1) { |
|
throw new Error('too many templatUrls!'); |
|
} |
|
return true; |
|
} |
|
} |
|
|
|
/* |
|
* Extract the name of the HTML template from the passed property. |
|
* templateUrl can be a concatenation of strings literal, |
|
* so we concatenate all the literals and extract the last part. |
|
*/ |
|
function getTemplateName(j, property) { |
|
return j(property) |
|
.find(j.Literal) |
|
.nodes() |
|
.map(n => n.value) |
|
.join('') |
|
.split('/') |
|
.pop(); |
|
} |
|
|
|
function addImportTemplateAtFileTop(j, root, templatePath) { |
|
let importStatement = j.importDeclaration( |
|
[j.importDefaultSpecifier(j.identifier('template'))], |
|
j.literal(templatePath) |
|
); |
|
root.get().node.program.body.unshift(importStatement); |
|
} |
|
|
|
module.exports = transformer; |
Thanks for this! Works great! Only catch is it doesn't work with template literals.
Line 65 fails
.find(j.Literal)
.