Skip to content

Instantly share code, notes, and snippets.

@jmfrancois
Last active January 9, 2020 08:09
Show Gist options
  • Save jmfrancois/42a3f4d57def537d935d9cc910dfce1c to your computer and use it in GitHub Desktop.
Save jmfrancois/42a3f4d57def537d935d9cc910dfce1c to your computer and use it in GitHub Desktop.
CMF Scripts to generate lazy react component from router configuration
#!/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