Skip to main content
Version: Next

Frontend Component Template Generation Principle - Node Version

Image

CreateService Function Description​

CreateService is a service function for automatically generating frontend component modules (widgets). The core process is as follows:

Path Initialization​

  • Get paths like src/, template/, menu.ts, widgets in the project.

Template Copy​

  • Use otiai10/copy to copy the template folder to src/ to generate a temporary widget folder.

File Content and Name Replacement​

  • Traverse the temporary directory and replace keywords like MyPluginName in the file with the actual component name.
  • Rename the corresponding file name at the same time.

Directory Move and Cleanup​

  • Delete intermediate process paths;
  • Migrate the temporary widget directory to the widgets/ directory.
  • Build and append new menu items and mappings to the menu.ts file;
  • Automatically generate structures that comply with TypeScript type declarations.

Build Record Append​

  • Write the component ID to the .build.local or .build.prod file according to the type for subsequent tracking of build status.
const { replaceFileContent, replaceFileName } = require("./file-replace");
const fs = require("fs-extra");
const path = require("path");
const Log = require("./Log");
const slash = require("slash");

/**
* Capitalize first letter of string
*
* @param string String to process
* @returns String with capitalized first letter
*/
function capitalizeFirstLetter(string) {
return string.replace(/\b\w/g, function (char) {
return char.toUpperCase();
});
}
/**
* Decapitalize first letter of string
*
* @param string String to process
* @returns Processed string
*/
function decapitalizeFirstLetter(string) {
return string.replace(/\b\w/g, function (char) {
return char.toLowerCase();
});
}

function regExpGenerater(str) {
return new RegExp(`${str}`, "g");
}

function merge(strArr = []) {
return strArr.map((str) => regExpGenerater(str));
}

async function createWidget(currentPath, { widgetName, entityName }) {
// Copy component first
// Need to be in component root directory
// Execute command
const bakPath = path.join(__dirname, "../src/bak");
const upWidgetName = capitalizeFirstLetter(widgetName);
const lowWidgetName = decapitalizeFirstLetter(widgetName);

const upEntityName = capitalizeFirstLetter(entityName);
const lowEntityName = decapitalizeFirstLetter(entityName);
// Replace content
try {
fs.removeSync(slash(bakPath));
const globBakPath = slash(bakPath + "/**/*");

fs.copySync(slash(path.join(__dirname, "../src/MyPluginName")), bakPath);
await replaceFileContent(
globBakPath,
merge(["MyPluginName", "myPluginName", "MyEntityName", "myEntityName"]),
[upWidgetName, lowWidgetName, upEntityName, lowEntityName]
);
Log.success("Content replaced successfully, replacing component name...");
await replaceFileName(globBakPath, "MyPluginName", upWidgetName);
await replaceFileName(globBakPath, "myPluginName", lowWidgetName);
await replaceFileName(globBakPath, "MyEntityName", upEntityName);
await replaceFileName(globBakPath, "myEntityName", lowEntityName);

// Move to target directory
fs.copySync(
bakPath,
slash(path.resolve(process.cwd(), "./src/widgets/" + widgetName)),
{
overwrite: true,
}
);
Log.success("Component created successfully");
fs.removeSync(bakPath);
} catch (err) {
console.error(err);
}
}

/**
* Create component
*/
module.exports = createWidget;