Skip to content
This repository has been archived by the owner on Apr 7, 2022. It is now read-only.

Commit

Permalink
feat(scripts/start): add on-demand modules build when start
Browse files Browse the repository at this point in the history
provide args when start the apps (development) `yarn start --module my_module1,my_module2,`. This
arguments will only works on development environment. This script refer modules name from
`src/_route/route.js` and we recommend you to give module folder names (@page/<module_name>),
variable names in `/src/_route/path.js` and `/src/_route/module.js` the same name with the
corresponding conventions

re #1
  • Loading branch information
martinock committed Apr 26, 2019
1 parent 04c1bec commit 43e426e
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ profile
packages/**/*.md
**/*.DS_Store
.cache-loader
*.development.js
*.development.ts
9 changes: 8 additions & 1 deletion packages/treats/alias.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,14 @@ const CORE_PATH = path.resolve(__dirname),
useTypescript = isTSFileExists(),
//Filesystem hooks scan
resolvedAlias = Object.keys(RESOLVER).reduce((accumulator, key) => {
if (process.env.NODE_ENV !== "test") {
if (
process.env.NODE_ENV === "development" &&
(key === "BUILD_ROUTE_PATH" || key === "BUILD_ROUTE_MODULE_PATH")
) {
accumulator[`@@${key}@@`] = useTypescript
? RESOLVER[key].developmentTypescript
: RESOLVER[key].development;
} else if (process.env.NODE_ENV !== "test") {
accumulator[`@@${key}@@`] = selectPath(useTypescript, RESOLVER[key]);
} else {
accumulator[`@@${key}@@`] = RESOLVER[key].default;
Expand Down
3 changes: 3 additions & 0 deletions packages/treats/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,5 +132,8 @@
"workbox-webpack-plugin": "4.1.0",
"yargs": "12.0.1",
"yarn-install": "1.0.0"
},
"devDependencies": {
"babel-plugin-transform-es2015-modules-commonjs": "6.26.2"
}
}
6 changes: 5 additions & 1 deletion packages/treats/resolver.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const path = require("path"),
ROOT_PATH = process.cwd();

/**
/**
* Treats filesystem hooks with 3 config [custom, customTypescript, default].
* custom or customTypescript will be used when you define them on your projects
*/
Expand All @@ -19,11 +19,15 @@ const RESOLVER = {
BUILD_ROUTE_PATH: {
custom: path.resolve(ROOT_PATH, "./src/_route/route.js"),
customTypescript: path.resolve(ROOT_PATH, "./src/_route/route.ts"),
development: path.resolve(ROOT_PATH, "./src/_route/route.development.js"),
developmentTypescript: path.resolve(ROOT_PATH, "./src/_route/route.development.ts"),
default: path.resolve(__dirname, "./default/_route/route.js")
},
BUILD_ROUTE_MODULE_PATH: {
custom: path.resolve(ROOT_PATH, "./src/_route/module.js"),
customTypescript: path.resolve(ROOT_PATH, "./src/_route/module.ts"),
development: path.resolve(ROOT_PATH, "./src/_route/module.development.js"),
developmentTypescript: path.resolve(ROOT_PATH, "./src/_route/module.development.ts"),
default: path.resolve(__dirname, "./default/_route/module.js")
},
BUILD_SERVER_TEMPLATE_PATH: {
Expand Down
13 changes: 12 additions & 1 deletion packages/treats/scripts/start
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const chalk = require("chalk"),
checkTypescript = require("./util/checkTypescript"),
generateTSConfig = require("./util/generateTSConfig"),
isTSFileExists = require("./util/isTSFileExists"),
setupDevModules = require("./util/setup-dev-modules"),
clean = require("./clean"),
RESOLVER = require("../resolver"),
WebpackDevServerUtils = require("react-dev-utils/WebpackDevServerUtils"),
Expand Down Expand Up @@ -143,6 +144,12 @@ const start = argv => {
const useTypescript = isTSFileExists();
checkTypescript(useTypescript);

//Setup routes & modules for development on-demand modules bundling
if ((!argv.env || argv.env === "development")) {
logger("log", "Generating on-demand modules");
setupDevModules(useTypescript, argv.module);
}

getProcessForPort(userPort);
WebpackDevServerUtils.choosePort("localhost", userPort).then(resolvedPort => {
if(resolvedPort !== null) {
Expand All @@ -156,7 +163,11 @@ const start = argv => {
}

const entryFiles = Object.keys(RESOLVER).reduce((accumulator, key) => {
const buildPath = useTypescript ? RESOLVER[key].customTypescript : RESOLVER[key].custom;
let buildPath = useTypescript ? RESOLVER[key].customTypescript : RESOLVER[key].custom;
if (process.env.NODE_ENV === "development" &&
(key === "BUILD_ROUTE_PATH" || key === "BUILD_ROUTE_MODULE_PATH")) {
buildPath = useTypescript ? RESOLVER[key].developmentTypescript : RESOLVER[key].development;
}
accumulator.push(buildPath);
return accumulator;
}, []),
Expand Down
120 changes: 120 additions & 0 deletions packages/treats/scripts/util/setup-dev-modules.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
const fs = require("fs-extra"),
ROOT_PATH = process.cwd(),
path = require("path"),
alias = require("../../alias"),
logger = require("./logger"),
babel = require("@babel/core");

/**
* Generate on-demand routes for development.
* @param {boolean} useTypescript is projects contain Typescript
* @param {string} modules user chosen modules
*
* @author Martino Christanto Khuangga
*/
const setupDevModules = (useTypescript, modules) => {
const routePath = alias["@@BUILD_ROUTE_PATH@@"],
appPaths = alias["@@BUILD_ROUTE_PATH@@"].replace("route.", "path."),
modulePath = alias["@@BUILD_ROUTE_MODULE_PATH@@"],
devRoutePath = path.resolve(
ROOT_PATH,
`./src/_route/route.development.${useTypescript ? "ts" : "js"}`
),
devModulePath = path.resolve(
ROOT_PATH,
`./src/_route/module.development.${useTypescript ? "ts" : "js"}`
),
onDemandModules = modules ? modules.split(",") : [];

//Write the whole files if user doesn't provide on-demand modules
if (onDemandModules.length === 0) {
fs.copyFileSync(routePath, devRoutePath);
fs.copyFileSync(modulePath, devModulePath);
return;
}

logger("log", `Transpiling _route/path.${useTypescript ? "ts" : "js"}`);

//Transpile _route/route.(js|ts) and _route/path(js|ts) to CommonJS
const routesCode = fs.readFileSync(routePath),
pathCode = fs.readFileSync(appPaths),
parsedRouteAst = babel.parse(routesCode),
parsedPathAst = babel.parse(pathCode),
{ code: newPathCode } = babel.transformFromAstSync(parsedPathAst, pathCode, {
plugins: ["transform-es2015-modules-commonjs"]
});

logger(
"warn",
`Rewriting temporary _route/path.${useTypescript ? "ts" : "js"}. Do not stop the process`
);
fs.writeFileSync(appPaths, newPathCode);

const { code } = babel.transformFromAstSync(parsedRouteAst, routesCode, {
plugins: ["transform-es2015-modules-commonjs"]
});

logger("log", `Generating development on-demand routes: ${modules}`);
fs.writeFileSync(devRoutePath, code);

let finalRoutesContent = "",
finalModulesContent = "",
importedPathStrings = "";

const currentRoutes = require(devRoutePath).default,
finalRoutes = currentRoutes.filter(route => onDemandModules.indexOf(route.name) !== -1),
moduleObject = {},
modifiedRoutes = [];

//Generating required modules variable names
finalRoutes.forEach((route, index) => {
finalModulesContent += `import ${route.name.charAt(0).toUpperCase()}${route.name.slice(
1
)} from "@page/${route.name}";\n`;
moduleObject[`[${route.name.toUpperCase()}]`] = `${route.name
.charAt(0)
.toUpperCase()}${route.name.slice(1)}`;
importedPathStrings += `${route.name.toUpperCase()}${
index < finalRoutes.length - 1 ? ", " : ""
}`;

modifiedRoutes.push({
...route,
path: route.name.toUpperCase()
});
});

finalModulesContent += `\nimport { ${importedPathStrings} } from "./path";\n\n`;
finalModulesContent += `const module = ${JSON.stringify(
moduleObject,
(key, value) => value,
4
).replace(new RegExp("\"|'", "g"), "")}`;
finalModulesContent += "\n\nexport default module;\n";
fs.writeFileSync(devModulePath, finalModulesContent);

finalRoutesContent += `import { ${importedPathStrings} } from "./path";\n\n`;
finalRoutesContent += `const route = ${JSON.stringify(
modifiedRoutes,
(key, value) => {
if (key === "path") {
return `@@${value}@@`;
}
return value;
},
4
).replace(new RegExp("\"@@|'@@|@@\"|@@'", "g"), "")};`;
finalRoutesContent += "\n\nexport default route;\n";

fs.writeFileSync(devRoutePath, finalRoutesContent);

logger(
"warn",
`Revert back _route/path.${useTypescript ? "ts" : "js"}. Do not stop the process`
);
fs.writeFileSync(appPaths, pathCode);

logger("debug", "On-demand routes generated!");
};

module.exports = setupDevModules;

0 comments on commit 43e426e

Please sign in to comment.