Last active
January 9, 2020 08:09
-
-
Save jmfrancois/42a3f4d57def537d935d9cc910dfce1c to your computer and use it in GitHub Desktop.
CMF Scripts to generate lazy react component from router configuration
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
#!/usr/bin/env node | |
// parse webapp using cmf.json to extract all components | |
// generate for each component the lazy one | |
// To use it just download it in your cmf webapp folder and execute it | |
const mkdirp = require('mkdirp'); | |
const fs = require('fs'); | |
const CONFIG_PATH = './lazyroutes.json'; | |
let COMPONENT_PATH_BYNAME; | |
if (fs.existsSync(CONFIG_PATH)) { | |
COMPONENT_PATH_BYNAME = require(CONFIG_PATH); | |
} | |
// use webapp convetion but accept src if no src/app | |
let SRC_PATH = './src'; | |
if (!fs.existsSync(SRC_PATH)) { | |
throw new Error('No src folder. please follow talend webapp convention'); | |
} else if (fs.existsSync('./src/app')) { | |
SRC_PATH = './src/app'; | |
} | |
function getComponentContent(name) { | |
const importPath = COMPONENT_PATH_BYNAME[name]; | |
return `import React, { Suspense } from 'react'; | |
const ${name} = React.lazy(() => import(/* webpackChunkName: "${name}" */ '${importPath}')); | |
export default function ${name}Route(props) { | |
return ( | |
<Suspense fallback={<div className="tc-loading">Loading...</div>}> | |
<${name} {...props} /> | |
</Suspense> | |
); | |
} | |
${name}Route.displayName = '${name}Route'; | |
`; | |
} | |
function getIndexContent(components) { | |
const header = components.reduce((acc, value) => { | |
acc.push(`import ${value} from './${value}';`); | |
return acc; | |
}, []); | |
const footer = components.reduce((acc, value) => { | |
acc.push(` ${value},`); | |
return acc; | |
}, []); | |
return `${header.join('\n')} | |
export { | |
${footer.join('\n')} | |
}; | |
`; | |
} | |
function rawParse(config) { | |
let components = []; | |
if (config.component) { | |
components.push(config.component); | |
} | |
if (config.indexRoute) { | |
components.push(config.indexRoute.component); | |
} | |
if (config.childRoutes) { | |
components = components.concat(...config.childRoutes.map(rawParse)); | |
} | |
return components; | |
} | |
function parseRouter() { | |
const cmf = require('./cmf.json'); | |
if (!cmf.settings.destination) { | |
throw new Error('this project do not have settings destination'); | |
} | |
const settings = require(cmf.settings.destination); | |
if (!settings.routes) { | |
throw new Error(`no router config in ${cmf.settings.destination} file`); | |
} | |
const components = rawParse(settings.routes).filter((value, index, all) => { | |
return all.indexOf(value) === index; | |
}); | |
return components; | |
} | |
function createLazyComponent(components) { | |
if (!COMPONENT_PATH_BYNAME) { | |
console.log(`no configuration file found at ${CONFIG_PATH}`); | |
} | |
const basePath = `${SRC_PATH}/lazyroutes`; | |
if (!fs.existsSync(basePath)) { | |
mkdirp.sync(basePath); | |
} | |
const notLazy = []; | |
components.forEach(name => { | |
if (!COMPONENT_PATH_BYNAME[name]) { | |
console.log(`${name} not found in ${CONFIG_PATH}`); | |
notLazy.push(name); | |
} else { | |
fs.writeFileSync(`${basePath}/${name}.js`, getComponentContent(name), {}); | |
} | |
}); | |
fs.writeFileSync(`${basePath}/index.js`, getIndexContent(components.filter(c => notLazy.indexOf(c) === -1)), {}); | |
} | |
createLazyComponent(parseRouter()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment