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
+61
View File
@@ -0,0 +1,61 @@
/*
* @Author : djkloop
* @Date : 2021-09-15 15:13:17
* @LastEditors : djkloop
* @LastEditTime : 2021-09-19 16:10:22
* @Description : 头部注释
* @FilePath : /form-create2/tools/cli/run.ts
*/
import {program} from 'commander';
import path from 'path';
import chalk from 'chalk';
import build from '../lib/build';
// pkgUrl
const log = console.log
const commandExecUrl = process.cwd()
log()
log(' ' + chalk.green('command run path with: ', commandExecUrl))
log()
const pkgUrl = path.join(commandExecUrl, '/lerna.json');
program.on('--help', () => {
log();
log(chalk.blue.bold(' Usage:'), chalk.cyan.bold('tools build tools with Node 👍 ~'));
log();
})
/// tools 版本
program
.version(`@form-create/tools v${require(pkgUrl).version}`, '-v, --version', 'tools versions')
program
.command('build [flag]')
.description('build components && packages || build components || build packages')
.option('-a,--all', 'Build @form-create/[all]packages') /// 默认打包components和packages
.option('-c, --components <ui-compnents...>', 'Build @form-create/component-<ui-package> package or packages array') // 打单独的组件
.option('-p, --packages <ui-package...>', 'Build @form-create/<ui-package> package or packages array') // 打单独的包
.action((_: any, cmd: any) => build(_, cleanArgs(cmd)));
program.parse(process.argv);
// code with vue-cli: https://github.com/vuejs/vue-cli/blob/dev/packages/%40vue/cli/bin/vue.js#L275
function camelize(str: string) {
return str.replace(/-(\w)/g, (_, c) => c ? c.toUpperCase() : '')
}
// commander passes the Command object itself as options,
// extract only actual options into a fresh object.
function cleanArgs(cmd: any) {
const args: any = {}
cmd.options.forEach((o: any) => {
const key = camelize(o.long.replace(/^--/, ''))
// if an option is not present and Command has a method with the same name
// it should not be copied
if (typeof cmd[key] !== 'function' && typeof cmd[key] !== 'undefined') {
args[key] = cmd[key]
}
})
return args
}
+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}`
}
})
}
+69
View File
@@ -0,0 +1,69 @@
/*
* @Author : djkloop
* @Date : 2021-09-19 13:53:31
* @LastEditors : djkloop
* @LastEditTime : 2021-09-19 14:11:52
* @Description : 头部注释
* @FilePath : /form-create2/tools/rollup/plugin/index.ts
*/
import vue from 'rollup-plugin-vue';
import postcss from 'rollup-plugin-postcss';
import { cssUrl } from '@sixian/css-url';
import externals from 'rollup-plugin-node-externals';
import nodeResolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel';
export const createRollupPlugins = () => {
const rollupPlugins = [
vue({
preprocessStyles: true,
})
];
/// css settings
rollupPlugins.push(postcss({
minimize: true,
extract: false,
plugins: [
cssUrl({
imgExtensions: /\.(png|jpg|jpeg|gif|svg)$/,
fontExtensions: /\.(ttf|woff|woff2|eot)$/,
limit: 8192,
hash: false,
slash: false
})
]
}));
/// devDependencies
rollupPlugins.push(externals({
devDeps: true
}));
/// j
rollupPlugins.push(nodeResolve({
extensions: ['.js', '.json', '.jsx', '.ts', '.tsx'],
preferBuiltins: true,
browser: true
}));
/// commonjs
rollupPlugins.push(commonjs());
rollupPlugins.push(babel({
babelHelpers: 'bundled',
exclude: 'node_modules/**',
extensions: ['.js', '.jsx', '.mjs', '.ts', '.tsx', '.vue'],
}));
// if (visualizer) {
// }
return rollupPlugins
}