Created
December 9, 2016 07:04
-
-
Save albertojg/8a8772f779ed9c7b8d54b758f18041c5 to your computer and use it in GitHub Desktop.
Transform import statement
This file contains hidden or 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
const fs = require('fs'); | |
const args = process.argv.slice(2); | |
const options = args | |
.reduce((result, arg) => { | |
const splittedArg = arg.split('='); | |
const key = splittedArg[0].replace('--', ''); | |
const value = splittedArg[1]; | |
result[key] = value; | |
return result; | |
}, {}); | |
const commonComponents = require(options.commonComponentsPath); | |
const components = require(options.componentsPath); | |
const componentLibrary = require(options.componentLibraryPath); | |
const mapping = { | |
components: Object.assign({}, commonComponents, components), | |
'component-library': componentLibrary | |
}; | |
// write mapping to file | |
const outputFilePath = options.outputFilePath; | |
fs.appendFileSync(outputFilePath, JSON.stringify(mapping)); |
This file contains hidden or 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
const fs = require('fs'); | |
function getComponentNamePathMapping(node) { | |
// extract the component source path | |
const sourcePath = node.value && node.value.source && node.value.source.rawValue; | |
if (!sourcePath) { | |
console.warn('Unable to find source path of node! Problematic node: ', node); | |
return; | |
} | |
// extract the component name | |
const nodeSpecifier = node.value && node.value.specifiers && node.value.specifiers[0]; | |
const name = nodeSpecifier && nodeSpecifier.exported && nodeSpecifier.exported.name; | |
// skip if name is wildcard | |
if (name === '*') { | |
console.log('Skipping node due to wildcard import name!'); | |
return; | |
} | |
return {sourcePath, name}; | |
} | |
module.exports = function(file, api, options) { | |
const jscodeshift = api.jscodeshift; | |
// options | |
const prefixPath = options.prefixPath; | |
const outputFilePath = options.outputFilePath; | |
const mapping = {}; | |
// parse source to abstract syntax tree | |
const ast = jscodeshift(file.source); | |
ast.find(jscodeshift.ExportNamedDeclaration) | |
.forEach((node) => { | |
const component = getComponentNamePathMapping(node); | |
if (component) { | |
const componentName = component.name; | |
const sourcePath = component.sourcePath.replace(/^\./, prefixPath); | |
mapping[componentName] = sourcePath; | |
} | |
}); | |
// write mapping to file | |
fs.appendFileSync(outputFilePath, JSON.stringify(mapping)); | |
// return un-modified code | |
return ast.toSource(); | |
}; |
This file contains hidden or 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
{ | |
"name": "update-import-statement", | |
"version": "1.0.0", | |
"description": "", | |
"main": "index.js", | |
"scripts": { | |
"test": "echo \"Error: no test specified\" && exit 1", | |
"update-import": "jscodeshift -v 2 -t transform-import.js", | |
"generate-path-mapper": "jscodeshift -v 2 -t generate-path-mapper.js", | |
"combine-path-mappers": "node combine-path-mappers" | |
}, | |
"author": "albertojg", | |
"license": "UNLICENSED", | |
"dependencies": { | |
"jscodeshift": "^0.3.30" | |
} | |
} |
This file contains hidden or 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
#!/bin/bash | |
root=$1; | |
TEMP_DIRECTORY="./.path-mapper"; | |
ORIGINAL_COMPONENTS_PATH="$root/components"; | |
ORIGINAL_COMMON_COMPONENTS_PATH="$root/components/Common"; | |
ORIGINAL_COMPONENT_LIBRARY_PATH="$root/component-library"; | |
COMPONENTS_MAPPER_PATH="$TEMP_DIRECTORY/components.json"; | |
COMMON_COMPONENTS_MAPPER_PATH="$TEMP_DIRECTORY/commonComponents.json"; | |
COMPONENT_LIBRARY_MAPPER_PATH="$TEMP_DIRECTORY/componentLibrary.json"; | |
IMPORT_FILE_PATH_MAPPER="$TEMP_DIRECTORY/path-mapper.json"; | |
# re-initialize temp directory if exists | |
if [ -d $TEMP_DIRECTORY ]; then | |
rm -r $TEMP_DIRECTORY; | |
fi | |
mkdir -p $TEMP_DIRECTORY; | |
# transform index file to path dictionary | |
npm run generate-path-mapper -- \ | |
"$ORIGINAL_COMPONENTS_PATH/index.js" \ | |
--prefixPath="components" \ | |
--outputFilePath=$COMPONENTS_MAPPER_PATH; | |
npm run generate-path-mapper -- \ | |
"$ORIGINAL_COMMON_COMPONENTS_PATH/index.js" \ | |
--prefixPath="components/Common" \ | |
--outputFilePath=$COMMON_COMPONENTS_MAPPER_PATH; | |
npm run generate-path-mapper -- \ | |
"$ORIGINAL_COMPONENT_LIBRARY_PATH/index.js" \ | |
--prefixPath="component-library" \ | |
--outputFilePath=$COMPONENT_LIBRARY_MAPPER_PATH; | |
# combine the list of path dictionary to a single dictionary path | |
npm run combine-path-mappers -- \ | |
--commonComponentsPath=$COMMON_COMPONENTS_MAPPER_PATH \ | |
--componentsPath=$COMPONENTS_MAPPER_PATH \ | |
--componentLibraryPath=$COMPONENT_LIBRARY_MAPPER_PATH \ | |
--outputFilePath=$IMPORT_FILE_PATH_MAPPER; | |
# transform the import | |
npm run update-import -- \ | |
$root \ | |
--pathMapper=$IMPORT_FILE_PATH_MAPPER; | |
# clean up temp directory | |
rm -r $TEMP_DIRECTORY; |
This file contains hidden or 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
function getNodeSourceRawValue(node) { | |
return node.value.source.rawValue; | |
} | |
function filterImportDeclaration(node) { | |
const sourceRawValue = getNodeSourceRawValue(node); | |
// filter to only replace import statement from 'components' or 'component-library' | |
return sourceRawValue === 'components' || sourceRawValue === 'component-library'; | |
} | |
function updateImportComponents(jscodeshift, node, pathMapper) { | |
const sourceRawValue = getNodeSourceRawValue(node); | |
const modifiedNodeSpecifiers = []; | |
const nodeSpecifiers = node.value && node.value.specifiers; | |
nodeSpecifiers.forEach((specifier) => { | |
const importedComponentName = specifier.imported.name; | |
const componentPath = pathMapper[sourceRawValue][importedComponentName]; | |
const localComponentName = specifier.local.name; | |
modifiedNodeSpecifiers.push( | |
`import ${localComponentName} from '${componentPath}';` | |
); | |
}); | |
jscodeshift(node) | |
.replaceWith(modifiedNodeSpecifiers); | |
} | |
module.exports = function(file, api, options) { | |
const jscodeshift = api.jscodeshift; | |
const pathMapper = require(options.pathMapper); | |
// parse source to abstract syntax tree | |
const ast = jscodeshift(file.source); | |
// 1. search for import node | |
// 2. filter the nodes to only those that are importing from components or component-library | |
// 3. update the import statement | |
ast.find(jscodeshift.ImportDeclaration) | |
.filter(filterImportDeclaration) | |
.forEach((node) => updateImportComponents(jscodeshift, node, pathMapper)); | |
return ast.toSource(); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You just need to put them into the same directory.