This commit is contained in:
robin
2022-12-01 21:48:35 +08:00
commit 879cd36baf
69 changed files with 5265 additions and 0 deletions
+163
View File
@@ -0,0 +1,163 @@
/*
* @Author : djkloop
* @Date : 2020-08-15 17:21:22
* @LastEditors : djkloop
* @LastEditTime : 2021-10-04 19:33:38
* @Description : 头部注释
* @FilePath : /form-create2/tools/lib/build.ts
*/
import chalk from 'chalk';
import ora from 'ora';
import dayjs from 'dayjs';
import fs from 'fs';
import { exit } from 'process';
import shell from 'shelljs';
import createBuildComponents from './components';
import createBuildPackages from './packages';
import { blue, getFolderNames, getSingleComponentPaths, getSinglePackagePaths, red, targets as getAllTargetsPath, yellow } from './utils'
let spinner
const log = console.log
const context = process.cwd()
async function buildAllComponents(paths: string[] = []) {
let componentsPathsObject = Object.create(null)
paths.forEach((comPath: string) => {
const [name, cname] = comPath.split('/')
const componentsPaths = getSingleComponentPaths('components', name, cname)
if (!componentsPathsObject[name]) {
componentsPathsObject[name] = componentsPaths[name]
} else {
componentsPathsObject[name] = [...componentsPathsObject[name], ...componentsPaths[name]]
}
});
await createBuildComponents(componentsPathsObject)
await exit();
}
async function createBuildTask(args: any) {
const isAll = args.all || Object.keys(args).length === 0
const isComponentsAll = args?.components?.includes('all')
const isPackagesAll = args?.packages?.includes('all')
let tips = '';
if (isAll) {
tips = 'build all components and all packages'
} else if (isComponentsAll) {
tips = 'build all components'
} else if (isPackagesAll) {
tips = 'build all packages'
} else {
tips = ' build task time' + ' ' + dayjs().format('YYYY-MM-DD HH:mm:ss') + '\n'
}
yellow(tips, true)
blue(' ---------------------- start ----------------------\n', true)
/// not all components
if (!isComponentsAll && args?.components?.length) {
const libs = args?.components
if (libs.length === 1) {
/// 先切包名
const lib = libs[0];
/// 单包下存在多个包
if (lib.includes('*') || !lib.includes('/')) {
/// xxx/*
const [name] = !lib.includes('/') ? [lib] : lib.split('/')
const _p = getFolderNames('components', name)
buildAllComponents(_p)
} else {
const [name, cname] = lib.split('/')
const componentsPaths = getSingleComponentPaths('components', name, cname)
await createBuildComponents(componentsPaths)
await exit();
}
} else {
const compsPaths = args?.components;
const allPaths = compsPaths.filter(cp => cp.includes('*') || !cp.includes('/'));
const fixPaths = compsPaths.filter(cp => !cp.includes('*') && cp.includes('/'));
let _all_ = [...fixPaths]
if (allPaths.length) {
allPaths.forEach(allp => {
const [name] = !allp.includes('/') ? [allp] : allp.split('/')
const _p = getFolderNames('components', name)
_all_ = [..._all_, ..._p]
});
}
buildAllComponents(_all_)
}
}
if (!isPackagesAll && args?.packages?.length) {
const libs = args?.packages
if (libs.length === 1) {
/// 先切包名
const lib = libs[0];
const [name] = lib.split('/')
const packagesAllPaths = getSinglePackagePaths('packages', name)
await createBuildPackages(packagesAllPaths)
await exit();
} else {
let componentsPathsObject = Object.create(null)
libs.forEach(async lib => {
const componentsPaths = getSinglePackagePaths('packages', lib)
componentsPathsObject[lib] = componentsPaths[lib]
});
await createBuildPackages(componentsPathsObject)
await exit();
}
}
/// 如果是打包全部
if (isAll) {
/// 先打对应的依赖components
const componentsAllPaths = getAllTargetsPath('components')
const packagesAllPaths = getAllTargetsPath('packages')
if (!Object.keys(componentsAllPaths).length && !Object.keys(packagesAllPaths).length) {
yellow('\n no build components and packages task! please check buildFormCreateOptions or private with components/*/*/package.json \n')
exit(1);
}
if (!Object.keys(componentsAllPaths).length) {
yellow('\n no build components task! please check buildFormCreateOptions or private with components/*/*/package.json \n')
}
if (!Object.keys(packagesAllPaths).length) {
yellow('\n no build packages task! please check buildFormCreateOptions or private with packages/*/package.json \n')
}
/// 打印对应的组件
await createBuildComponents(componentsAllPaths)
/// 再打对应的包
await createBuildPackages(packagesAllPaths)
/// 退出
await exit();
} else {
/// 单独打所有的component组件
if(isComponentsAll) {
const componentsAllPaths = getAllTargetsPath('components')
if (!Object.keys(componentsAllPaths).length) {
yellow('\n no build components task! please check buildFormCreateOptions or private with components/*/*/package.json \n')
await exit(1)
}
await createBuildComponents(componentsAllPaths)
await exit();
}
/// 单独打所有的package包
if (isPackagesAll) {
const packagesAllPaths = getAllTargetsPath('packages')
if (!Object.keys(packagesAllPaths).length) {
yellow('\n no build packages task! please check buildFormCreateOptions or private with packages/*/package.json \n')
await exit(1)
}
await createBuildPackages(packagesAllPaths)
await exit();
}
}
}
export default (_: any, args: any) => {
return createBuildTask(args)
}
+73
View File
@@ -0,0 +1,73 @@
/**
* 打包components文件
*/
import type { Ora } from 'ora';
import chalk from 'chalk';
import ora from 'ora';
import os from 'os';
import execa from 'execa';
import dayjs from 'dayjs';
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
let spinner: Ora;
const build = async (target: string, comp: string, targetName: string) => {
dayjs().startOf('millisecond');
/// env 先写死
const env = 'production'
await execa(
'rollup',
[
`-c`,
'--environment',
[
`NODE_ENV:${env}`,
`BUILD_TARGET:${targetName}`,
`BUILD_TARGET_COMP:${comp}`,
`BUILD_TYPE:component`,
`BUILD_TARGET_PATH:${target}`
].filter(Boolean).join(',')
],
{ stdio: 'inherit' }
);
console.log('build task time' + ' ' + dayjs().format('YYYY-MM-DD HH:mm:ss'))
}
const runParallel = async (maxConcurrency: number, source: string[], buildName: string, iteratorFn: Function) => {
const ret = []
const executing = []
for (const item of source) {
const comp = item.split('/').pop()
const p = Promise.resolve().then(() => iteratorFn(item, comp, buildName))
ret.push(p)
if (maxConcurrency <= source.length) {
const e = p.then(() => executing.splice(executing.indexOf(e), 1))
executing.push(e)
if (executing.length >= maxConcurrency) {
await Promise.race(executing)
}
}
}
return Promise.all(ret)
}
const buildAll = async (comAllTargets) => {
await runParallel(os.cpus().length, comAllTargets[1], comAllTargets[0], build)
}
const createBuildComponents = async (cpaths: { [k: string]: any }) => {
/// 根据每个不同的ui库去生成每个ui库下面的不同的组件打包
const cps = Object.entries(cpaths)
for (const cpath of cps) {
await buildAll(cpath)
}
}
export default createBuildComponents
+88
View File
@@ -0,0 +1,88 @@
/**
* 打包packages文件
*/
import type {Ora} from 'ora';
import chalk from 'chalk';
import ora from 'ora';
import os from 'os';
import execa from 'execa';
import dayjs from 'dayjs';
let spinner: Ora;
const build = async (target: string, comp: string, targetName: string) => {
dayjs().startOf('millisecond');
spinner.text = chalk.bold.yellow(`start build ${targetName} ui \n`);
/// env 先写死
const env = 'production'
await execa(
'rollup',
[
'-c',
'--environment',
[
`NODE_ENV:${env}`,
`BUILD_TARGET:${targetName}`,
`BUILD_TARGET_COMP:${comp}`,
'BUILD_TYPE:packages',
`BUILD_TARGET_PATH:${target}`
].filter(Boolean).join(',')
],
{stdio: 'inherit'}
);
spinner.text = chalk.bold.green(`finished build ${targetName} ui time: ${dayjs().startOf('millisecond').format('SSS')}ms. \n `);
}
const runParallel = async (maxConcurrency: number, source: string[], buildName: string, iteratorFn: Function) => {
const ret = []
const executing = []
for (const item of source) {
const comp = item.split('/').pop()
const p = Promise.resolve().then(() => iteratorFn(item, comp, buildName))
ret.push(p)
if (maxConcurrency <= source.length) {
const e = p.then(() => executing.splice(executing.indexOf(e), 1))
executing.push(e)
if (executing.length >= maxConcurrency) {
await Promise.race(executing)
}
}
}
return Promise.all(ret)
}
const buildAll = async (comAllTargets) => {
await runParallel(os.cpus().length, comAllTargets[1], comAllTargets[0], build)
}
const _filter_current_url_ = (urls: Array<any>) => {
const arr = []
urls.map((url) => {
const itemUrlLibName = url[0];
let itemUrlLibsUrl = '';
url[1].forEach((item, idx) => {
const suffix = item.split('/').pop()
if (suffix === itemUrlLibName) {
itemUrlLibsUrl = item
}
})
const item = [itemUrlLibName, [itemUrlLibsUrl]]
arr.push(item)
})
return arr
}
const createBuildPackages = async (cpaths: { [k: string]: any }) => {
const tips = chalk.redBright.bold('\n start build all packages \n')
spinner = ora(tips).start()
/// 根据每个不同的ui库去生成每个ui库下面的不同的组件打包
const cps = Object.entries(cpaths)
/// 处理下当前的url
const fCps = _filter_current_url_(cps)
for (const cpath of fCps) {
await buildAll(cpath)
}
}
export default createBuildPackages
+14
View File
@@ -0,0 +1,14 @@
import path from 'path';
/// 项目目录
export const projRoot = path.resolve(__dirname, '../../');
/// 单独component目录
export const compRoot = path.resolve(projRoot, './components');
/// packages目录
export const pkgRoot = path.resolve(projRoot, './packages');
/// file - packages.json \\\
export const pkgFileRoot = path.resolve(projRoot, './package.json');
/// file - lerna.json \\\
export const lernaFileRoot = path.resolve(projRoot, './lerna.json');
/// file - rollup.config.js \\\
export const rollupFileRoot = path.resolve(projRoot, './rollup.config.ts');
+140
View File
@@ -0,0 +1,140 @@
import chalk from "chalk";
import fs from "fs";
import { projRoot } from "./paths";
export function yellow(str: string, isBold: boolean = false) {
isBold ? console.log(chalk.bold.yellow(str)) : console.log(chalk.yellow(str))
}
export function green(str: string, isBold: boolean = false) {
isBold ? console.log(chalk.bold.green(str)) : console.log(chalk.green(str))
}
export function blue(str: string, isBold: boolean = false) {
isBold ? console.log(chalk.bold.blue(str)) : console.log(chalk.blue(str))
}
export function red(str: string, isBold: boolean = false) {
isBold ? console.log(chalk.bold.red(str)) : console.log(chalk.red(str))
}
export function errorAndExit(e) {
red(e.message)
process.exit(1)
}
export const targets = (dir: 'packages' | 'components' = 'packages') => {
const componentsAllPaths = Object.create(null);
const uiFoldersPath = fs.readdirSync(dir).filter(uiFolderPath => {
if (fs.statSync(`${projRoot}/${dir}/${uiFolderPath}`).isDirectory()) {
return true
}
})
// uiFoldersPath.forEach(uiPath => {
// const pkg = require(`${projRoot}/${dir}/${uiPath}/package.json`)
// if (pkg.private || !pkg.buildFormCreateOptions) {
// blue(`\n info: ${projRoot}/${dir}/${uiPath}/package.json private is true or buildFormCreateOptions is not exists!`)
// }
// })
if (dir === 'packages') {
const packagesFolderPath = []
for (let index = 0; index < uiFoldersPath.length; index++) {
const uiPath = uiFoldersPath[index];
if (!fs.statSync(`${projRoot}/${dir}/${uiPath}`).isDirectory()) {
continue;
}
const pkg = require(`${projRoot}/${dir}/${uiPath}/package.json`)
fs.rmdirSync(`${projRoot}/${dir}/${uiPath}/dist`, { recursive: true });
if (pkg.private || !pkg.buildFormCreateOptions) {
red(`\n info: ${projRoot}/${dir}/${uiPath}/package.json private is true or buildFormCreateOptions is not exists!`)
continue;
}
packagesFolderPath.push(`${projRoot}/${dir}/${uiPath}`)
if (packagesFolderPath.length) {
componentsAllPaths[uiPath] = packagesFolderPath
}
}
}
if (dir === 'components') {
uiFoldersPath.forEach(uiPath => {
const componentFolderPath = []
const alen = fs.readdirSync(`${projRoot}/${dir}/${uiPath}`).length
for (let index = 0; index < alen; index++) {
const comPath = fs.readdirSync(`${projRoot}/${dir}/${uiPath}`)[index];
if (!fs.statSync(`${projRoot}/${dir}/${uiPath}/${comPath}`).isDirectory()) {
continue;
}
const pkg = require(`${projRoot}/${dir}/${uiPath}/${comPath}/package.json`)
fs.rmdirSync(`${projRoot}/${dir}/${uiPath}/${comPath}/dist`, { recursive: true });
if (pkg.private || !pkg.buildFormCreateOptions) {
red(`\n info: ${projRoot}/${dir}/${uiPath}/${comPath}/package.json private is true or buildFormCreateOptions is not exists!`)
continue;
}
componentFolderPath.push(`${projRoot}/${dir}/${uiPath}/${comPath}`)
}
if (componentFolderPath.length) {
componentsAllPaths[uiPath] = componentFolderPath
}
})
}
return componentsAllPaths
}
export const getSingleComponentPaths = (dir: string = 'components', libname: string = '', comname: string = '') => {
const fpath = Object.create(null)
const _rootPath = dir
const _libPath = libname
const _compPath = comname
if (!fs.statSync(`${projRoot}/${_rootPath}/${_libPath}/${_compPath}`).isDirectory()) {
return
}
const pkg = require(`${projRoot}/${_rootPath}/${_libPath}/${_compPath}/package.json`)
fs.rmdirSync(`${projRoot}/${_rootPath}/${_libPath}/${_compPath}/dist`, { recursive: true });
if (pkg.private || !pkg.buildFormCreateOptions) {
red(`\n info: ${projRoot}/${_rootPath}/${_libPath}/${_compPath}/package.json private is true or buildFormCreateOptions is not exists!`)
return
}
fpath[_libPath] = [`${projRoot}/${_rootPath}/${_libPath}/${_compPath}`]
return fpath
}
export const getSinglePackagePaths = (dir: string = 'packages', libname: string = '') => {
const fpath = Object.create(null)
const _rootPath = dir
const _libPath = libname
if (!fs.statSync(`${projRoot}/${_rootPath}/${_libPath}`).isDirectory()) {
return
}
const pkg = require(`${projRoot}/${_rootPath}/${_libPath}/package.json`)
fs.rmdirSync(`${projRoot}/${_rootPath}/${_libPath}/dist`, { recursive: true });
if (pkg.private || !pkg.buildFormCreateOptions) {
red(`\n info: ${projRoot}/${_rootPath}/${_libPath}/package.json private is true or buildFormCreateOptions is not exists!`)
return
}
fpath[_libPath] = [`${projRoot}/${_rootPath}/${_libPath}`]
return fpath
}
/// Get all the folder names under the current folder
export const getFolderNames = (folder: string, uiFolder: string) => {
return fs.readdirSync(`${folder}/${uiFolder}`).map(uiFolderPath => {
if (fs.statSync(`${projRoot}/${folder}/${uiFolder}`).isDirectory()) {
fs.rmdirSync(`${projRoot}/${folder}/${uiFolder}/dist`, { recursive: true });
return `${uiFolder}/${uiFolderPath}`
}
})
}