Updates
This commit is contained in:
2
lowcoder/client/packages/lowcoder-cli/.gitignore
vendored
Normal file
2
lowcoder/client/packages/lowcoder-cli/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
.out
|
||||
node_modules
|
||||
3
lowcoder/client/packages/lowcoder-cli/README.md
Normal file
3
lowcoder/client/packages/lowcoder-cli/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# lowcoder-cli
|
||||
|
||||
CLI tool used to start build and publish lowcoder component library.
|
||||
133
lowcoder/client/packages/lowcoder-cli/actions/build.js
Normal file
133
lowcoder/client/packages/lowcoder-cli/actions/build.js
Normal file
@@ -0,0 +1,133 @@
|
||||
import { execSync } from "child_process";
|
||||
import fsExtra from "fs-extra";
|
||||
import { build } from "vite";
|
||||
import { writeFileSync, existsSync, readFileSync, readdirSync } from "fs";
|
||||
import { resolve } from "path";
|
||||
import { pathToFileURL } from "url";
|
||||
import paths from "../config/paths.js";
|
||||
import "../util/log.js";
|
||||
import chalk from "chalk";
|
||||
|
||||
const { copySync } = fsExtra;
|
||||
const packageJSON = JSON.parse(readFileSync(paths.appPackageJson).toString());
|
||||
|
||||
function validPackageJSON() {
|
||||
if (!packageJSON.name) {
|
||||
return "- package name is required";
|
||||
}
|
||||
if (!packageJSON.version) {
|
||||
return "- package version is required";
|
||||
}
|
||||
if (!packageJSON.lowcoder) {
|
||||
return "- lowcoder field is required in package.json";
|
||||
}
|
||||
const lowcoder = packageJSON.lowcoder;
|
||||
if (!lowcoder.comps || Object.keys(lowcoder.comps).length === 0) {
|
||||
return "- not found any comps to build";
|
||||
}
|
||||
|
||||
const compErrors = [];
|
||||
Object.keys(lowcoder.comps).forEach((name) => {
|
||||
const compManifest = packageJSON.lowcoder.comps[name];
|
||||
if (!compManifest.icon) {
|
||||
// compErrors.push(`- comp ${name} must specify an icon`);
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!compManifest.icon.startsWith("data:") &&
|
||||
!existsSync(paths.resolveApp(compManifest.icon))
|
||||
) {
|
||||
compErrors.push(`- comp ${name}'s icon file ${chalk.cyan(compManifest.icon)} not found`);
|
||||
return;
|
||||
}
|
||||
});
|
||||
if (compErrors.length > 0) {
|
||||
return compErrors.join("\n");
|
||||
}
|
||||
}
|
||||
|
||||
function findReadmeFileName(directory) {
|
||||
const files = readdirSync(directory);
|
||||
const readmeFile = files.find(file => file.toLowerCase() === 'readme.md');
|
||||
return readmeFile ? `${directory}/${readmeFile}` : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. webpack production build
|
||||
* 2. generate package.json
|
||||
* 3. copy locales
|
||||
* 3. pack tar ball
|
||||
*/
|
||||
export default async function buildAction(options) {
|
||||
const beginTime = performance.now();
|
||||
process.env.NODE_ENV = "production";
|
||||
|
||||
const { outDir } = options;
|
||||
const err = validPackageJSON();
|
||||
if (err) {
|
||||
console.red("Invalid package.json:\n");
|
||||
console.red(err);
|
||||
console.log("");
|
||||
return;
|
||||
}
|
||||
|
||||
const compNames = Object.keys(packageJSON.lowcoder.comps);
|
||||
console.cyan(`Name : ${packageJSON.name}`);
|
||||
console.cyan(`Version : ${packageJSON.version}`);
|
||||
console.cyan(`Comps : ${compNames.length}\n`);
|
||||
compNames.forEach((i) => {
|
||||
console.log(` ${i}`);
|
||||
});
|
||||
console.log("");
|
||||
console.cyan("Building...");
|
||||
|
||||
const viteConfigURL = pathToFileURL(paths.appViteConfigJs);
|
||||
const viteConfig = await import(viteConfigURL).default;
|
||||
console.log(paths.appViteConfigJs);
|
||||
await build(viteConfig);
|
||||
|
||||
// write package.json
|
||||
packageJSON.lowcoder.entry = "index.js";
|
||||
writeFileSync(paths.appOutPackageJson, JSON.stringify(packageJSON, null, 2));
|
||||
|
||||
// copy locales
|
||||
if (existsSync(paths.appLocales)) {
|
||||
copySync(paths.appLocales, resolve(paths.appOutPath, "locales"));
|
||||
}
|
||||
|
||||
// copy icon files
|
||||
compNames.forEach((name) => {
|
||||
const compManifest = packageJSON.lowcoder.comps[name];
|
||||
if (compManifest.icon) {
|
||||
copySync(paths.resolveApp(compManifest.icon), resolve(paths.appOutPath, compManifest.icon));
|
||||
}
|
||||
});
|
||||
|
||||
// copy readme file
|
||||
const readmePath = findReadmeFileName(paths.appPath + '/src');
|
||||
if (readmePath) {
|
||||
const destinationPath = resolve(paths.appOutPath, 'readme.md');
|
||||
copySync(readmePath, destinationPath);
|
||||
console.log(`Copied README file to: ${destinationPath}`);
|
||||
} else {
|
||||
console.warn('README.md file not found.');
|
||||
}
|
||||
|
||||
if (options.publish) {
|
||||
// publish
|
||||
execSync("npm publish", {
|
||||
stdio: "inherit",
|
||||
cwd: paths.appOutPath,
|
||||
});
|
||||
} else {
|
||||
// pack
|
||||
const tarOutPath = paths.resolveApp(outDir);
|
||||
execSync(`npm pack --pack-destination ${tarOutPath}`, {
|
||||
stdio: "ignore",
|
||||
cwd: paths.appOutPath,
|
||||
});
|
||||
|
||||
console.green(`Package generated in: ${tarOutPath}`);
|
||||
}
|
||||
console.green(`Done in ${Math.round(performance.now() - beginTime)}ms!`);
|
||||
}
|
||||
109
lowcoder/client/packages/lowcoder-cli/actions/init.js
Normal file
109
lowcoder/client/packages/lowcoder-cli/actions/init.js
Normal file
@@ -0,0 +1,109 @@
|
||||
import path from "path";
|
||||
import fs from "fs-extra";
|
||||
import { spawn } from "cross-spawn";
|
||||
import paths from "../config/paths.js";
|
||||
import { createRequire } from "node:module";
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
const isUsingYarn = (process.env.npm_config_user_agent || "").indexOf("yarn") === 0;
|
||||
|
||||
function install(dependencies, registry) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let cmd = "npm";
|
||||
let args = ["install", "--no-audit", "--save", "--save-exact", "--loglevel", "error"];
|
||||
if (isUsingYarn) {
|
||||
cmd = "yarn";
|
||||
args = ["add"];
|
||||
}
|
||||
if (registry) {
|
||||
args.push("--registry", registry);
|
||||
}
|
||||
args.push(...dependencies);
|
||||
const child = spawn(cmd, args, { stdio: "inherit" });
|
||||
child.on("close", (code) => {
|
||||
if (code !== 0) {
|
||||
reject({
|
||||
command: `${cmd} ${args.join(" ")}`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function uninstall(dependencies) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let cmd = "npm";
|
||||
let args = ["uninstall"];
|
||||
if (isUsingYarn) {
|
||||
cmd = "yarn";
|
||||
args = ["remove"];
|
||||
}
|
||||
args.push(...dependencies);
|
||||
const child = spawn(cmd, args, { stdio: "inherit" });
|
||||
child.on("close", (code) => {
|
||||
if (code !== 0) {
|
||||
reject({
|
||||
command: `${cmd} ${args.join(" ")}`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* init dir with specified template name
|
||||
* 1. install template package
|
||||
* 2. update package.json
|
||||
* 3. copy template files
|
||||
* 4. install other dependencies
|
||||
* 5. uninstall template package
|
||||
*/
|
||||
export default async function initAction(options) {
|
||||
const { template, registry } = options;
|
||||
const templatePackageName = `lowcoder-cli-template-${template}`;
|
||||
|
||||
await install([templatePackageName], registry);
|
||||
console.log("template package installed");
|
||||
|
||||
const templatePackageJsonFile = require.resolve(`${templatePackageName}/package.json`);
|
||||
const templateDir = path.dirname(templatePackageJsonFile);
|
||||
const templatePackageJson = fs.readJsonSync(templatePackageJsonFile);
|
||||
const appPackageJson = fs.readJsonSync(paths.appPackageJson);
|
||||
|
||||
appPackageJson.lowcoder = templatePackageJson.lowcoder || {};
|
||||
appPackageJson.scripts = {
|
||||
start: "vite",
|
||||
build: "lowcoder-cli build",
|
||||
build_publish: "lowcoder-cli build --publish",
|
||||
};
|
||||
fs.writeFileSync(paths.appPackageJson, JSON.stringify(appPackageJson, null, 2));
|
||||
console.log("package.json updated");
|
||||
|
||||
const notCopiedFiles = ["package.json", "README.md", "README-template.md", "node_modules"];
|
||||
fs.copySync(templateDir, "./", {
|
||||
filter: (src) => notCopiedFiles.every((i) => !src.startsWith(path.join(templateDir, i))),
|
||||
});
|
||||
fs.copyFile(path.join(templateDir, "README-template.md"), "./README.md");
|
||||
console.log("template files copied");
|
||||
|
||||
const dependencies = [];
|
||||
if (template === "typescript") {
|
||||
dependencies.push("typescript");
|
||||
}
|
||||
if (dependencies.length > 0) {
|
||||
await install(dependencies, registry);
|
||||
console.log("dependencies installed");
|
||||
}
|
||||
|
||||
await uninstall([templatePackageName]);
|
||||
console.log("template package uninstalled");
|
||||
|
||||
console.log();
|
||||
console.log("Done! Now, you can run below command to start:");
|
||||
console.log(` ${isUsingYarn ? "yarn" : "npm"} start`);
|
||||
console.log();
|
||||
}
|
||||
41
lowcoder/client/packages/lowcoder-cli/client.d.ts
vendored
Normal file
41
lowcoder/client/packages/lowcoder-cli/client.d.ts
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/// <reference path="./global.d.ts" />
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
declare module "*.svg" {
|
||||
import * as React from "react";
|
||||
|
||||
export const ReactComponent: React.FunctionComponent<
|
||||
React.SVGProps<SVGSVGElement> & { title?: string }
|
||||
>;
|
||||
|
||||
// const src: string;
|
||||
// export default src;
|
||||
}
|
||||
|
||||
declare module "*.md" {
|
||||
const value: string;
|
||||
export default value;
|
||||
}
|
||||
|
||||
declare module "eslint4b-prebuilt-2";
|
||||
declare module "mq-polyfill";
|
||||
declare module "@rjsf/antd";
|
||||
declare module "really-relaxed-json";
|
||||
declare module "tui-image-editor";
|
||||
|
||||
declare var numbro: any;
|
||||
declare var uuid: any;
|
||||
declare var PUBLIC_URL: string;
|
||||
declare var REACT_APP_EDITION: string;
|
||||
declare var REACT_APP_LANGUAGES: string;
|
||||
declare var REACT_APP_COMMIT_ID: string;
|
||||
declare var REACT_APP_API_SERVICE_URL: string;
|
||||
declare var REACT_APP_NODE_SERVICE_URL: string;
|
||||
declare var REACT_APP_ENV: string;
|
||||
declare var REACT_APP_BUILD_ID: string;
|
||||
declare var REACT_APP_LOG_LEVEL: string;
|
||||
declare var REACT_APP_IMPORT_MAP: string;
|
||||
declare var REACT_APP_SERVER_IPS: string;
|
||||
declare var REACT_APP_BUNDLE_TYPE: "sdk" | "app";
|
||||
declare var REACT_APP_DISABLE_JS_SANDBOX: string;
|
||||
declare var REACT_APP_BUNDLE_BUILTIN_PLUGIN: string;
|
||||
119
lowcoder/client/packages/lowcoder-cli/config/modules.js
Normal file
119
lowcoder/client/packages/lowcoder-cli/config/modules.js
Normal file
@@ -0,0 +1,119 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import paths from "./paths.js";
|
||||
import resolve from "resolve";
|
||||
|
||||
function getAdditionalEntries() {}
|
||||
|
||||
/**
|
||||
* Get additional module paths based on the baseUrl of a compilerOptions object.
|
||||
*
|
||||
* @param {Object} options
|
||||
*/
|
||||
function getAdditionalModulePaths(options = {}) {
|
||||
const baseUrl = options.baseUrl;
|
||||
|
||||
if (!baseUrl) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
|
||||
|
||||
// We don't need to do anything if `baseUrl` is set to `node_modules`. This is
|
||||
// the default behavior.
|
||||
if (path.relative(paths.appNodeModules, baseUrlResolved) === "") {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Allow the user set the `baseUrl` to `appSrc`.
|
||||
if (path.relative(paths.appSrc, baseUrlResolved) === "") {
|
||||
return [paths.appSrc];
|
||||
}
|
||||
|
||||
// If the path is equal to the root directory we ignore it here.
|
||||
// We don't want to allow importing from the root directly as source files are
|
||||
// not transpiled outside of `src`. We do allow importing them with the
|
||||
// absolute path (e.g. `src/Components/Button.js`) but we set that up with
|
||||
// an alias.
|
||||
if (path.relative(paths.appPath, baseUrlResolved) === "") {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Otherwise, throw an error.
|
||||
throw new Error("Your project's `baseUrl` can only be set to `src` or `node_modules`.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get webpack aliases based on the baseUrl of a compilerOptions object.
|
||||
*
|
||||
* @param {*} options
|
||||
*/
|
||||
function getWebpackAliases(options = {}) {
|
||||
const baseUrl = options.baseUrl;
|
||||
|
||||
if (!baseUrl) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
|
||||
|
||||
if (path.relative(paths.appPath, baseUrlResolved) === "") {
|
||||
return {
|
||||
src: paths.appSrc,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get jest aliases based on the baseUrl of a compilerOptions object.
|
||||
*
|
||||
* @param {*} options
|
||||
*/
|
||||
function getJestAliases(options = {}) {
|
||||
const baseUrl = options.baseUrl;
|
||||
|
||||
if (!baseUrl) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
|
||||
|
||||
if (path.relative(paths.appPath, baseUrlResolved) === "") {
|
||||
return {
|
||||
"^src/(.*)$": "<rootDir>/src/$1",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function getModules() {
|
||||
// Check if TypeScript is setup
|
||||
const hasTsConfig = fs.existsSync(paths.appTsConfig);
|
||||
|
||||
let config;
|
||||
|
||||
// If there's a tsconfig.json we assume it's a
|
||||
// TypeScript project and set up the config
|
||||
// based on tsconfig.json
|
||||
if (hasTsConfig) {
|
||||
const ts = require(resolve.sync("typescript", {
|
||||
basedir: paths.appNodeModules,
|
||||
}));
|
||||
config = ts.readConfigFile(paths.appTsConfig, ts.sys.readFile).config;
|
||||
// Otherwise we'll check if there is jsconfig.json
|
||||
// for non TS projects.
|
||||
}
|
||||
|
||||
config = config || {};
|
||||
const options = config.compilerOptions || {};
|
||||
|
||||
const additionalModulePaths = getAdditionalModulePaths(options);
|
||||
|
||||
return {
|
||||
additionalModulePaths: additionalModulePaths,
|
||||
webpackAliases: getWebpackAliases(options),
|
||||
jestAliases: getJestAliases(options),
|
||||
hasTsConfig,
|
||||
};
|
||||
}
|
||||
|
||||
export default getModules();
|
||||
57
lowcoder/client/packages/lowcoder-cli/config/paths.js
Normal file
57
lowcoder/client/packages/lowcoder-cli/config/paths.js
Normal file
@@ -0,0 +1,57 @@
|
||||
import path from "node:path";
|
||||
import fs from "node:fs";
|
||||
import { currentDirName } from "../dev-utils/util.js";
|
||||
|
||||
const currentDir = currentDirName(import.meta.url);
|
||||
const appDirectory = fs.realpathSync(process.cwd());
|
||||
const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath);
|
||||
|
||||
const moduleFileExtensions = [
|
||||
"web.mjs",
|
||||
"mjs",
|
||||
"web.js",
|
||||
"js",
|
||||
"web.ts",
|
||||
"ts",
|
||||
"web.tsx",
|
||||
"tsx",
|
||||
"json",
|
||||
"web.jsx",
|
||||
"jsx",
|
||||
];
|
||||
|
||||
const resolveModule = (resolveFn, filePath) => {
|
||||
const extension = moduleFileExtensions.find((extension) =>
|
||||
fs.existsSync(resolveFn(`${filePath}.${extension}`))
|
||||
);
|
||||
|
||||
if (extension) {
|
||||
return resolveFn(`${filePath}.${extension}`);
|
||||
}
|
||||
|
||||
return resolveFn(`${filePath}.js`);
|
||||
};
|
||||
|
||||
const resolveOwn = (relativePath) => path.resolve(currentDir, "..", relativePath);
|
||||
|
||||
const paths = {
|
||||
resolveApp,
|
||||
appOutPath: resolveOwn(".out"),
|
||||
appOutPackageJson: resolveOwn(".out/package.json"),
|
||||
appPath: resolveApp("."),
|
||||
appHtml: resolveOwn("ide/index.html"),
|
||||
appRoot: resolveOwn("ide"),
|
||||
appBaseTsConfig: resolveOwn("ide/tsconfig.json"),
|
||||
appPackageJson: resolveApp("package.json"),
|
||||
appSrc: resolveApp("src"),
|
||||
appLocales: resolveApp("locales"),
|
||||
compsIndexJs: resolveModule(resolveApp, "src/index"),
|
||||
appViteConfigJs: resolveModule(resolveApp, "vite.config"),
|
||||
appTsConfig: resolveApp("tsconfig.json"),
|
||||
yarnLockFile: resolveApp("yarn.lock"),
|
||||
appNodeModules: resolveApp("node_modules"),
|
||||
appWebpackCache: resolveApp("node_modules/.cache"),
|
||||
appTsBuildInfoFile: resolveApp("node_modules/.cache/tsconfig.tsbuildinfo"),
|
||||
};
|
||||
|
||||
export default paths;
|
||||
67
lowcoder/client/packages/lowcoder-cli/config/vite.config.js
Normal file
67
lowcoder/client/packages/lowcoder-cli/config/vite.config.js
Normal file
@@ -0,0 +1,67 @@
|
||||
import react from "@vitejs/plugin-react";
|
||||
import svgrPlugin from "vite-plugin-svgr";
|
||||
import global from "rollup-plugin-external-globals";
|
||||
import { buildVars } from "../dev-utils/buildVars.js";
|
||||
import injectCss from "vite-plugin-css-injected-by-js";
|
||||
import { getLibNames, getAllLibGlobalVarNames } from "../dev-utils/external.js";
|
||||
import paths from "./paths.js";
|
||||
import { defineConfig } from "vite";
|
||||
import { readJson } from "../dev-utils/util.js";
|
||||
|
||||
const isProduction = process.env.NODE_ENV === "production";
|
||||
const packageJson = readJson(paths.appPackageJson);
|
||||
|
||||
const define = {};
|
||||
buildVars.forEach(({ name, defaultValue }) => {
|
||||
define[name] = JSON.stringify(process.env[name] || defaultValue);
|
||||
});
|
||||
|
||||
export default defineConfig({
|
||||
define: {
|
||||
...define,
|
||||
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || "development"),
|
||||
__LOWCODER_ORG__: JSON.stringify({}),
|
||||
},
|
||||
assetsInclude: ["**/*.md"],
|
||||
resolve: {
|
||||
extensions: [".mjs", ".js", ".ts", ".jsx", ".tsx", ".json"],
|
||||
},
|
||||
build: {
|
||||
target: "es2020",
|
||||
cssTarget: "chrome87",
|
||||
outDir: paths.appOutPath,
|
||||
emptyOutDir: true,
|
||||
lib: {
|
||||
formats: ["es"],
|
||||
entry: paths.compsIndexJs,
|
||||
fileName: "index",
|
||||
},
|
||||
rollupOptions: {
|
||||
external: getLibNames(),
|
||||
output: {
|
||||
chunkFileNames: "[hash].js",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
react({
|
||||
babel: {
|
||||
compact: false,
|
||||
parserOpts: {
|
||||
plugins: ["decorators-legacy"],
|
||||
},
|
||||
},
|
||||
}),
|
||||
svgrPlugin({
|
||||
svgrOptions: {
|
||||
exportType: "named",
|
||||
prettier: false,
|
||||
svgo: false,
|
||||
titleProp: true,
|
||||
ref: true,
|
||||
},
|
||||
}),
|
||||
isProduction && global(getAllLibGlobalVarNames(), { exclude: [/\.css$/] }),
|
||||
isProduction && injectCss({ styleId: `${packageJson.name}-${packageJson.version}` }),
|
||||
].filter(Boolean),
|
||||
});
|
||||
58
lowcoder/client/packages/lowcoder-cli/dev-utils/buildVars.js
Normal file
58
lowcoder/client/packages/lowcoder-cli/dev-utils/buildVars.js
Normal file
@@ -0,0 +1,58 @@
|
||||
export const buildVars = [
|
||||
{
|
||||
name: "PUBLIC_URL",
|
||||
defaultValue: "/",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_EDITION",
|
||||
defaultValue: "community",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_LANGUAGES",
|
||||
defaultValue: "",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_COMMIT_ID",
|
||||
defaultValue: "00000",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_API_SERVICE_URL",
|
||||
defaultValue: "",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_NODE_SERVICE_URL",
|
||||
defaultValue: "",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_ENV",
|
||||
defaultValue: "production",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_BUILD_ID",
|
||||
defaultValue: "",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_LOG_LEVEL",
|
||||
defaultValue: "error",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_IMPORT_MAP",
|
||||
defaultValue: "{}",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_SERVER_IPS",
|
||||
defaultValue: "",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_BUNDLE_BUILTIN_PLUGIN",
|
||||
defaultValue: "",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_BUNDLE_TYPE",
|
||||
defaultValue: "app",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_DISABLE_JS_SANDBOX",
|
||||
defaultValue: "",
|
||||
},
|
||||
];
|
||||
102
lowcoder/client/packages/lowcoder-cli/dev-utils/external.js
Normal file
102
lowcoder/client/packages/lowcoder-cli/dev-utils/external.js
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* libs to import as global var
|
||||
* name: module name
|
||||
* mergeDefaultAndNameExports: whether to merge default and named exports
|
||||
*/
|
||||
export const libs = [
|
||||
"axios",
|
||||
"redux",
|
||||
"react-router",
|
||||
"react-router-dom",
|
||||
"react-redux",
|
||||
"react",
|
||||
"react-dom",
|
||||
"lodash",
|
||||
"history",
|
||||
"antd",
|
||||
"@dnd-kit/core",
|
||||
"@dnd-kit/modifiers",
|
||||
"@dnd-kit/sortable",
|
||||
"@dnd-kit/utilities",
|
||||
{
|
||||
name: "moment",
|
||||
extractDefault: true,
|
||||
},
|
||||
{
|
||||
name: "dayjs",
|
||||
extractDefault: true,
|
||||
},
|
||||
{
|
||||
name: "lowcoder-sdk",
|
||||
from: "./src/index.sdk.ts",
|
||||
},
|
||||
{
|
||||
name: "styled-components",
|
||||
mergeDefaultAndNameExports: true,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* get global var name from module name
|
||||
* @param {string} name
|
||||
* @returns
|
||||
*/
|
||||
export const getLibGlobalVarName = (name) => {
|
||||
return "$" + name.replace(/@/g, "$").replace(/[\/\-]/g, "_");
|
||||
};
|
||||
|
||||
export const getLibNames = () => {
|
||||
return libs.map((i) => {
|
||||
if (typeof i === "object") {
|
||||
return i.name;
|
||||
}
|
||||
return i;
|
||||
});
|
||||
};
|
||||
|
||||
export const getAllLibGlobalVarNames = () => {
|
||||
const ret = {};
|
||||
libs.forEach((lib) => {
|
||||
let name = lib;
|
||||
if (typeof lib === "object") {
|
||||
name = lib.name;
|
||||
}
|
||||
ret[name] = getLibGlobalVarName(name);
|
||||
});
|
||||
return ret;
|
||||
};
|
||||
|
||||
export const libsImportCode = (exclude = []) => {
|
||||
const importLines = [];
|
||||
const assignLines = [];
|
||||
libs.forEach((i) => {
|
||||
let name = i;
|
||||
let merge = false;
|
||||
let from = name;
|
||||
let extractDefault = false;
|
||||
|
||||
if (typeof i === "object") {
|
||||
name = i.name;
|
||||
merge = i.mergeDefaultAndNameExports ?? false;
|
||||
from = i.from ?? name;
|
||||
extractDefault = i.extractDefault ?? false;
|
||||
}
|
||||
|
||||
if (exclude.includes(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const varName = getLibGlobalVarName(name);
|
||||
if (merge) {
|
||||
importLines.push(`import * as ${varName}_named_exports from '${from}';`);
|
||||
importLines.push(`import ${varName} from '${from}';`);
|
||||
assignLines.push(`Object.assign(${varName}, ${varName}_named_exports);`);
|
||||
} else if (extractDefault) {
|
||||
importLines.push(`import ${varName} from '${from}';`);
|
||||
} else {
|
||||
importLines.push(`import * as ${varName} from '${from}';`);
|
||||
}
|
||||
assignLines.push(`window.${varName} = ${varName};`);
|
||||
});
|
||||
return importLines.concat(assignLines).join("\n");
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
import { libsImportCode } from "./external.js";
|
||||
|
||||
export function globalDepPlugin(exclude = []) {
|
||||
const virtualModuleId = "virtual:globals";
|
||||
return {
|
||||
name: "lowcoder-global-plugin",
|
||||
resolveId(id) {
|
||||
if (id === virtualModuleId) {
|
||||
return id;
|
||||
}
|
||||
},
|
||||
load(id) {
|
||||
if (id === virtualModuleId) {
|
||||
return libsImportCode(exclude);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
28
lowcoder/client/packages/lowcoder-cli/dev-utils/util.js
Normal file
28
lowcoder/client/packages/lowcoder-cli/dev-utils/util.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import fs from "node:fs";
|
||||
import { dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
export function stripLastSlash(str) {
|
||||
if (str.endsWith("/")) {
|
||||
return str.slice(0, str.length - 1);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
export function ensureLastSlash(str) {
|
||||
if (!str) {
|
||||
return "/";
|
||||
}
|
||||
if (!str.endsWith("/")) {
|
||||
return `${str}/`;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
export function readJson(file) {
|
||||
return JSON.parse(fs.readFileSync(file).toString());
|
||||
}
|
||||
|
||||
export function currentDirName(importMetaUrl) {
|
||||
return dirname(fileURLToPath(importMetaUrl));
|
||||
}
|
||||
8
lowcoder/client/packages/lowcoder-cli/global.d.ts
vendored
Normal file
8
lowcoder/client/packages/lowcoder-cli/global.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
declare global {
|
||||
interface Window {
|
||||
printPerf: () => void;
|
||||
__LOWCODER_ORG__?: {};
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
||||
28
lowcoder/client/packages/lowcoder-cli/index.js
Executable file
28
lowcoder/client/packages/lowcoder-cli/index.js
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import("./util/log.js");
|
||||
import fs from "node:fs";
|
||||
import { Command } from "commander";
|
||||
import initAction from "./actions/init.js";
|
||||
import buildAction from "./actions/build.js";
|
||||
|
||||
const program = new Command();
|
||||
|
||||
const pkg = JSON.parse(fs.readFileSync("./package.json").toString());
|
||||
program.name(pkg.name).description(pkg.description);
|
||||
|
||||
program
|
||||
.command("init")
|
||||
.description("init project")
|
||||
.option("-t, --template", "template name", "typescript")
|
||||
.option("--registry [addr]", "npm registry")
|
||||
.action(initAction);
|
||||
|
||||
program
|
||||
.command("build")
|
||||
.description("build component lib")
|
||||
.option("--outDir", "where to place tar ball", "./")
|
||||
.option("--publish", "publish to npm", false)
|
||||
.action(buildAction);
|
||||
|
||||
program.parse();
|
||||
49
lowcoder/client/packages/lowcoder-cli/package.json
Normal file
49
lowcoder/client/packages/lowcoder-cli/package.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "lowcoder-cli",
|
||||
"description": "CLI tool used to start build publish lowcoder components",
|
||||
"version": "0.0.30",
|
||||
"license": "MIT",
|
||||
"bin": "./index.js",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./index.js",
|
||||
"require": "./index.js"
|
||||
},
|
||||
"./config/vite.config": {
|
||||
"import": "./config/vite.config.js",
|
||||
"require": "./config/vite.config.js"
|
||||
},
|
||||
"./client": {
|
||||
"types": "./client.d.ts"
|
||||
},
|
||||
"./actions/init.js": {
|
||||
"import": "./actions/init.js",
|
||||
"require": "./actions/init.js"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@vitejs/plugin-react": "^2.2.0",
|
||||
"axios": "^1.7.4",
|
||||
"chalk": "4",
|
||||
"commander": "^9.4.1",
|
||||
"cross-spawn": "^7.0.3",
|
||||
"fs-extra": "^10.1.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-json-view": "^1.21.3",
|
||||
"rollup-plugin-external-globals": "^0.7.1",
|
||||
"vite": "^4.5.5",
|
||||
"vite-plugin-css-injected-by-js": "^2.1.1",
|
||||
"vite-plugin-svgr": "^2.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^4.8.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"lowcoder-sdk": "*"
|
||||
},
|
||||
"keywords": [
|
||||
"lowcoder"
|
||||
]
|
||||
}
|
||||
30
lowcoder/client/packages/lowcoder-cli/util/log.js
Normal file
30
lowcoder/client/packages/lowcoder-cli/util/log.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import chalk from "chalk";
|
||||
|
||||
const colors = [
|
||||
"black",
|
||||
"red",
|
||||
"green",
|
||||
"yellow",
|
||||
"blue",
|
||||
"magenta",
|
||||
"cyan",
|
||||
"white",
|
||||
"gray",
|
||||
"redBright",
|
||||
"greenBright",
|
||||
"yellowBright",
|
||||
"blueBright",
|
||||
"magentaBright",
|
||||
"cyanBright",
|
||||
"whiteBright",
|
||||
];
|
||||
|
||||
colors.forEach((color) => {
|
||||
console[color] = (text) => {
|
||||
console.log(chalk[color](text));
|
||||
};
|
||||
});
|
||||
|
||||
export const logBug = (text) => {
|
||||
console.red(`${text}\n This maybe is a bug, you can issue a bug for us.`);
|
||||
};
|
||||
Reference in New Issue
Block a user