Created
November 21, 2017 16:10
-
-
Save markogresak/cb243d96c703cf86423c2bb2a6ff03f3 to your computer and use it in GitHub Desktop.
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
/* eslint-disable no-console */ | |
// "babel-core": "^6.24.1", | |
// "glob": "^7.1.2", | |
// "lodash": "^4.17.4", | |
// "babel-plugin-syntax-dynamic-import": "^6.18.0", | |
// "babel-plugin-transform-class-properties": "^6.24.1", | |
// "babel-plugin-syntax-decorators": "^6.13.0", | |
// "babel-preset-es2015": "^6.24.1", | |
// "babel-preset-react": "^6.24.1", | |
// "babel-preset-stage-0": "^6.24.1", | |
const {transformFile} = require('babel-core'); | |
const path = require('path'); | |
const fs = require('fs'); | |
const glob = require('glob'); | |
const _ = require('lodash'); | |
const outFile = './text-nodes.txt'; | |
fs.truncateSync(outFile); | |
const syntaxDynamicImport = require('babel-plugin-syntax-dynamic-import'); | |
const transformClassProperties = require('babel-plugin-transform-class-properties'); | |
const syntaxDecorators = require('babel-plugin-syntax-decorators'); | |
const es2015 = require('babel-preset-es2015'); | |
const react = require('babel-preset-react'); | |
const stage0 = require('babel-preset-stage-0'); | |
const babelTransformOpts = { | |
babelrc: false, | |
plugins: [ | |
syntaxDynamicImport, | |
transformClassProperties, | |
syntaxDecorators, | |
], | |
presets: [ | |
es2015, | |
react, | |
stage0, | |
], | |
}; | |
const translatableTextRe = /\w/; | |
function serializeArguments(astObj) { | |
const children = _.get(astObj, 'arguments', []).slice(2); | |
const locData = { | |
start: `${_.get(astObj, 'loc.start.line')}:${_.get(astObj, 'loc.start.column')}`, | |
end: `${_.get(astObj, 'loc.end.line')}:${_.get(astObj, 'loc.end.column')}`, | |
}; | |
return _.compact(_.map(children, c => { | |
const type = _.get(c, 'type'); | |
if (type === 'StringLiteral') { | |
const val = _.get(c, 'value'); | |
if (translatableTextRe.test(val)) { | |
return { | |
...locData, | |
text: val, | |
}; | |
} | |
} | |
if (type === 'Identifier') { | |
return { | |
...locData, | |
variable: _.get(c, 'name'), | |
}; | |
} | |
return null; | |
})); | |
} | |
function getNextPaths(astObj, pathsToProcess = [], currentPath = []) { | |
return _.keys(astObj) | |
.filter(k => astObj[k] && typeof astObj[k] === 'object') | |
.map(p => [...currentPath, p]) | |
.filter(p => !pathsToProcess.includes(p) && !p.includes('_shadowedFunctionLiteral')); | |
} | |
function getTextNodes(filePath) { | |
return new Promise((resolve, reject) => { | |
console.time(`process ${filePath}`); | |
transformFile(filePath, babelTransformOpts, (err, {ast}) => { | |
if (err) { | |
reject(err); | |
return; | |
} | |
const astBody = ast.program.body; | |
const pathsToProcess = getNextPaths(astBody); | |
const textNodes = []; | |
while (pathsToProcess.length > 0) { | |
const currentPath = pathsToProcess.shift(); | |
const astObj = _.get(astBody, currentPath); | |
if (astObj && typeof astObj === 'object') { | |
if (_.get(astObj, 'callee.property.name') === 'createElement') { | |
textNodes.push(serializeArguments(astObj)); | |
} | |
pathsToProcess.push(...getNextPaths(astObj, pathsToProcess, currentPath)); | |
} | |
} | |
console.timeEnd(`process ${filePath}`); | |
resolve({ | |
filePath, | |
textNodes: _.flatten(textNodes), | |
}); | |
}); | |
}); | |
} | |
function printFileTextNodes({filePath, textNodes = []} = {}) { | |
textNodes.forEach(({start, text, variable}) => { | |
const nodeInfo = text ? `${text.replace(/[\s\n]+/g, ' ')}` : `{${variable}}`; | |
const outText = `${filePath}:${start}: ${nodeInfo}`; | |
console.log(outText); | |
fs.appendFileSync(outFile, `${outText}\n`); | |
}); | |
} | |
console.time('process all'); | |
const processFilePromises = glob.sync(path.resolve(__dirname, './src/js/components/**/*.{js,jsx}')) | |
.filter(f => !f.match(/CKEditor/)) | |
.map(getTextNodes); | |
Promise.all(processFilePromises) | |
.then(dataArr => { | |
console.log('\n\n'); | |
dataArr.forEach(printFileTextNodes); | |
}) | |
.catch(console.error.bind(console)) | |
.then(() => { | |
console.log('\n'); | |
console.timeEnd('process all'); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment