From 822a9ec5365daebdb042e09a43001632c45998c7 Mon Sep 17 00:00:00 2001 From: leihaohao Date: Tue, 10 Aug 2021 11:56:56 +0800 Subject: [PATCH 1/4] =?UTF-8?q?build:=20=E5=A2=9E=E5=8A=A0=20devui-cli?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - package.json 增加 devui-cli 命令 - 增加 devui-cli + 创建组件模板 --- devui-cli/commands/create.mjs | 118 +++++++++++++++++++++++++ devui-cli/index.mjs | 14 +++ devui-cli/inquirers/component.mjs | 57 ++++++++++++ devui-cli/inquirers/create.mjs | 7 ++ devui-cli/shared/constant.js | 15 ++++ devui-cli/shared/logger.mjs | 16 ++++ devui-cli/shared/utils.mjs | 5 ++ devui-cli/templates/component.mjs | 128 +++++++++++++++++++++++++++ package.json | 13 ++- yarn.lock | 138 +++++++++++++++++++++++++++--- 10 files changed, 497 insertions(+), 14 deletions(-) create mode 100644 devui-cli/commands/create.mjs create mode 100644 devui-cli/index.mjs create mode 100644 devui-cli/inquirers/component.mjs create mode 100644 devui-cli/inquirers/create.mjs create mode 100644 devui-cli/shared/constant.js create mode 100644 devui-cli/shared/logger.mjs create mode 100644 devui-cli/shared/utils.mjs create mode 100644 devui-cli/templates/component.mjs diff --git a/devui-cli/commands/create.mjs b/devui-cli/commands/create.mjs new file mode 100644 index 00000000..22e1b0f4 --- /dev/null +++ b/devui-cli/commands/create.mjs @@ -0,0 +1,118 @@ +import logger from '../shared/logger.mjs' +import { bigCamelCase } from '../shared/utils.mjs' +import fs from 'fs-extra' +import { resolve } from 'path' +import { DEVUI_NAMESPACE, DEVUI_DIR, TESTS_DIR_NAME, COMPONENT_PARTS_MAP } from '../shared/constant.js' +import { isEmpty, kebabCase } from 'lodash-es' +import inquirer from 'inquirer' +import { selectCreateType } from '../inquirers/create.mjs' +import { selectCategory, selectParts, typeName, typeTitle } from '../inquirers/component.mjs' +import { + createComponentTemplate, + createStyleTemplate, + createTypesTemplate, + createDirectiveTemplate, + createServiceTemplate, + createIndexTemplate, + createTestsTemplate +} from '../templates/component.mjs' + +export function validateCreateType(type) { + const flag = /^(component|(vue-devui)|(vitepress\/sidebar))$/.test(type) + + !flag && logger.error('类型错误,可选类型为:component, vue-devui, vitepress/sidebar') + + return flag ? type : null +} + +export async function create(cwd) { + let { type } = cwd + + if (isEmpty(type)) { + const result = await inquirer.prompt([selectCreateType()]) + type = result.type + } + + if (type !== 'component') { + logger.info('抱歉,该功能暂未完成!') + return process.exit(0) + } + + const result = await inquirer.prompt([typeName(), typeTitle(), selectCategory(), selectParts()]) + result.hasComponent = result.parts.includes(COMPONENT_PARTS_MAP.get('component')) + result.hasDirective = result.parts.includes(COMPONENT_PARTS_MAP.get('directive')) + result.hasService = result.parts.includes(COMPONENT_PARTS_MAP.get('service')) + + try { + await createComponent(result) + } catch (e) { + logger.error(e.toString()) + process.exit(1) + } +} + +async function createComponent(params = {}) { + let { name, hasComponent, hasDirective, hasService } = params + + name = name.replace(new RegExp(`^${DEVUI_NAMESPACE}`, 'i'), '') + + const componentName = kebabCase(name) + const styleName = kebabCase(name) + const typesName = kebabCase(name) + '-types' + const directiveName = kebabCase(name) + '-directive' + const serviceName = kebabCase(name) + '-service' + + const _params = { + ...params, + componentName, + typesName, + directiveName, + serviceName, + styleName + } + + const componentTemplate = createComponentTemplate(_params) + const styleTemplate = createStyleTemplate(_params) + const typesTemplate = createTypesTemplate(_params) + const directiveTemplate = createDirectiveTemplate(_params) + const serviceTemplate = createServiceTemplate(_params) + const indexTemplate = createIndexTemplate(_params) + const testsTemplate = createTestsTemplate(_params) + + const componentDir = resolve(DEVUI_DIR, componentName) + const srcDir = resolve(componentDir, 'src') + const testsDir = resolve(DEVUI_DIR, componentName, TESTS_DIR_NAME) + + if (fs.pathExistsSync(componentDir)) { + logger.error(`${bigCamelCase(componentName)} 组件目录已存在!`) + return process.exit(1) + } + + await Promise.all([fs.mkdirs(componentDir), fs.mkdirs(srcDir), fs.mkdirs(testsDir)]) + + const writeFiles = [fs.writeFile(resolve(componentDir, `index.ts`), indexTemplate)] + + if (hasComponent || hasService) { + writeFiles.push(fs.writeFile(resolve(srcDir, `${typesName}.ts`), typesTemplate)) + } + + if (hasComponent) { + writeFiles.push( + fs.writeFile(resolve(srcDir, `${componentName}.tsx`), componentTemplate), + fs.writeFile(resolve(srcDir, `${styleName}.scss`), styleTemplate) + ) + } + + if (hasDirective) { + writeFiles.push(fs.writeFile(resolve(srcDir, `${directiveName}.ts`), directiveTemplate)) + } + + if (hasService) { + writeFiles.push(fs.writeFile(resolve(srcDir, `${serviceName}.ts`), serviceTemplate)) + } + + await Promise.all(writeFiles) + + logger.info(`组件目录:${componentDir}`) + logger.success('创建成功!') +} diff --git a/devui-cli/index.mjs b/devui-cli/index.mjs new file mode 100644 index 00000000..dd0948da --- /dev/null +++ b/devui-cli/index.mjs @@ -0,0 +1,14 @@ +#!/usr/bin/env node +import { Command } from 'commander' +import { create, validateCreateType } from './commands/create.mjs' +import { VERSION } from './shared/constant.js' + +const program = new Command() + +program + .command('create') + .description('创建一个组件模板或配置文件') + .option('-t --type ', '创建类型,可选值:component, vue-devui, vitepress/sidebar', validateCreateType) + .action(create) + +program.parse().version(VERSION) diff --git a/devui-cli/inquirers/component.mjs b/devui-cli/inquirers/component.mjs new file mode 100644 index 00000000..f814d0f6 --- /dev/null +++ b/devui-cli/inquirers/component.mjs @@ -0,0 +1,57 @@ +import { COMPONENT_PARTS_MAP } from '../shared/constant.js' + +export const typeName = () => ({ + name: 'name', + type: 'input', + message: '(必填)请输入组件 name ,将用作目录及文件名:', + validate: (value) => { + if (value.trim() === '') { + return '组件 name 是必填项!' + } + return true + } +}) + +export const typeTitle = () => ({ + name: 'title', + type: 'input', + message: '(必填)请输入组件中文名称,将用作文档列表显示:', + validate: (value) => { + if (value.trim() === '') { + return '组件名称是必填项!' + } + return true + } +}) + +export const selectCategory = () => ({ + name: 'category', + type: 'list', + message: '(必填)请选择组件分类,将用作文档列表分类:', + choices: ['通用', '导航', '反馈', '扩展服务', '数据录入', '数据展示', '布局'], + default: 0 +}) + +export const typeAliasName = () => ({ + name: 'alias', + type: 'input', + message: '(选填)请输入组件 name 别名,将用作组件别名被导出:' +}) + +export const selectParts = () => ({ + name: 'parts', + type: 'checkbox', + message: '(必填)请选择包含部件,将自动生成部件文件:', + choices: [ + COMPONENT_PARTS_MAP.get('component'), + COMPONENT_PARTS_MAP.get('directive'), + COMPONENT_PARTS_MAP.get('service') + ], + default: [], + validate: (value) => { + if (value.length === 0) { + return '部件必须包含至少一项' + } + return true + } +}) diff --git a/devui-cli/inquirers/create.mjs b/devui-cli/inquirers/create.mjs new file mode 100644 index 00000000..74fb9510 --- /dev/null +++ b/devui-cli/inquirers/create.mjs @@ -0,0 +1,7 @@ +export const selectCreateType = () => ({ + name: 'type', + type: 'list', + message: '(必填)请选择创建类型:', + choices: ['component', 'vue-devui', 'vitepress/sidebar'], + default: 0 +}) diff --git a/devui-cli/shared/constant.js b/devui-cli/shared/constant.js new file mode 100644 index 00000000..6fd85eac --- /dev/null +++ b/devui-cli/shared/constant.js @@ -0,0 +1,15 @@ +const { resolve } = require('path') +const { version } = require('../../package.json') + +exports.VERSION = version +exports.CWD = process.cwd() +exports.DEVUI_DIR = resolve(this.CWD, 'devui') +exports.DEVUI_NAMESPACE = 'd' +exports.DEVUI_INDEX_FILE = 'vue-devui.ts' +exports.TESTS_DIR_NAME = '__tests__' + +exports.COMPONENT_PARTS_MAP = new Map([ + ['component', 'component(组件)'], + ['directive', 'directive(指令)'], + ['service', 'service(服务)'] +]) diff --git a/devui-cli/shared/logger.mjs b/devui-cli/shared/logger.mjs new file mode 100644 index 00000000..a8b4d50e --- /dev/null +++ b/devui-cli/shared/logger.mjs @@ -0,0 +1,16 @@ +import chalk from 'chalk' + +export default { + info(text) { + console.log(chalk.hex('#00afef')(text)) + }, + success(text) { + console.log(chalk.hex('#00c48f')(text)) + }, + warning(text) { + console.log(chalk.hex('#ff9800')(text)) + }, + error(text) { + console.log(chalk.hex('#f44336')(text)) + } +} diff --git a/devui-cli/shared/utils.mjs b/devui-cli/shared/utils.mjs new file mode 100644 index 00000000..b64507ec --- /dev/null +++ b/devui-cli/shared/utils.mjs @@ -0,0 +1,5 @@ +import { camelCase, upperFirst } from 'lodash-es' + +export function bigCamelCase(str) { + return upperFirst(camelCase(str)) +} diff --git a/devui-cli/templates/component.mjs b/devui-cli/templates/component.mjs new file mode 100644 index 00000000..0f6312c0 --- /dev/null +++ b/devui-cli/templates/component.mjs @@ -0,0 +1,128 @@ +import { DEVUI_NAMESPACE } from '../shared/constant.js' +import { camelCase } from 'lodash-es' +import { bigCamelCase } from '../shared/utils.mjs' + +export const createComponentTemplate = ({ styleName, componentName, typesName }) => `\ +import './${styleName}.scss' + +import { defineComponent } from 'vue' +import { ${camelCase(componentName)}Props, ${bigCamelCase(componentName)}Props } from './${typesName}' + +export default defineComponent({ + name: '${bigCamelCase(DEVUI_NAMESPACE)}${bigCamelCase(componentName)}', + props: ${camelCase(componentName)}Props, + emits: [], + setup(props: ${bigCamelCase(componentName)}Props, ctx) { + return {} + }, + render() { + const {} = this + + return
+ } +}) +` + +export const createTypesTemplate = ({ componentName }) => `\ +import type { PropType, ExtractPropTypes } from 'vue' + +export const ${camelCase(componentName)}Props = { + \/\* test: { + type: Object as PropType<{ xxx: xxx }> + } \*\/ +} as const + +export type ${bigCamelCase(componentName)}Props = ExtractPropTypes +` + +export const createDirectiveTemplate = () => `\ +// can export function. +export default { + created() { }, + beforeMount() { }, + mounted() { }, + beforeUpdate() { }, + updated() { }, + beforeUnmount() { }, + unmounted() { } +} +` + +export const createServiceTemplate = ({ componentName, typesName, serviceName }) => `\ +import { ${bigCamelCase(componentName)}Props } from './${typesName}' + +const ${bigCamelCase(serviceName)} = { + // open(props: ${bigCamelCase(componentName)}Props) { } +} + +export default ${bigCamelCase(serviceName)} +` + +export const createStyleTemplate = ({ componentName }) => `\ +.${DEVUI_NAMESPACE}-${componentName} { + // +} +` + +export const createIndexTemplate = ({ + title, + category, + hasComponent, + hasDirective, + hasService, + componentName, + directiveName, + serviceName +}) => { + const importComponentStr = `\nimport ${bigCamelCase(componentName)} from './src/${componentName}'` + const importDirectiveStr = `\nimport ${bigCamelCase(directiveName)} from './src/${directiveName}'` + const importServiceStr = `\nimport ${bigCamelCase(serviceName)} from './src/${serviceName}'` + + const installComponentStr = `\n\t\tapp.use(${bigCamelCase(componentName)} as any)` + const installDirectiveStr = `\n\t\tapp.directive('${bigCamelCase(componentName)}', ${bigCamelCase(directiveName)})` + const installServiceStr = `\n\t\tapp.config.globalProperties.$${camelCase(serviceName)} = ${bigCamelCase( + serviceName + )}` + + const getPartStr = (state, str) => (state ? str : '') + + const importStr = + getPartStr(hasComponent, importComponentStr) + + getPartStr(hasDirective, importDirectiveStr) + + getPartStr(hasService, importServiceStr) + + const installStr = + getPartStr(hasComponent, installComponentStr) + + getPartStr(hasDirective, installDirectiveStr) + + getPartStr(hasService, installServiceStr) + + return `\ +import type { App } from 'vue'\ +${importStr} +${ + hasComponent + ? `\n${bigCamelCase(componentName)}.install = function(app: App) { + app.component(${bigCamelCase(componentName)}.name, ${bigCamelCase(componentName)}) +}\n` + : '' +} +export { ${[ + hasComponent ? bigCamelCase(componentName) : null, + hasDirective ? bigCamelCase(directiveName) : null, + hasService ? bigCamelCase(serviceName) : null + ] + .filter((p) => p !== null) + .join(', ')} } + +export default { + title: '${bigCamelCase(componentName)} ${title}', + category: '${category}', + install(app: App) {\ + ${installStr} + } +} +` +} + +export const createTestsTemplate = () => `\ +` diff --git a/package.json b/package.json index 39442595..bc2a43cc 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,9 @@ "main": "vue-devui.umd.js", "module": "vue-devui.es.js", "style": "style.css", + "bin": { + "devui-cli": "./devui-cli/index.mjs" + }, "scripts": { "dev": "vitepress dev sites", "build": "vitepress build sites", @@ -32,7 +35,8 @@ "stylelint": "stylelint --fix \"{devui,src}/**/*.{scss,css}\"", "convert:route": "node ./scripts/convert-component-route.js", "publish": "cd dist && npm publish", - "generate:devui": "node scripts/generate-devui.js" + "generate:devui": "node scripts/generate-devui.js", + "postinstall": "npm link" }, "dependencies": { "@devui-design/icons": "^1.3.0", @@ -47,6 +51,8 @@ "@commitlint/cli": "^11.0.0", "@commitlint/config-conventional": "^11.0.0", "@ls-lint/ls-lint": "^1.10.0", + "@types/chalk": "^2.2.0", + "@types/commander": "^2.12.2", "@types/jest": "^26.0.23", "@typescript-eslint/eslint-plugin": "^4.27.0", "@typescript-eslint/parser": "^4.27.0", @@ -58,13 +64,16 @@ "@vuedx/typecheck": "^0.4.1", "@vuedx/typescript-plugin-vue": "^0.4.1", "babel-jest": "^27.0.2", - "commander": "^7.1.0", + "chalk": "^4.1.2", + "commander": "^8.1.0", "esbuild-register": "^2.6.0", "eslint": "^7.28.0", "eslint-plugin-vue": "^7.11.1", "husky": "^4.3.7", + "inquirer": "^8.1.2", "jest": "^27.0.4", "lint-staged": "^11.0.0", + "ora": "^5.4.1", "sass": "^1.32.2", "shelljs": "^0.8.4", "stylelint": "^13.13.1", diff --git a/yarn.lock b/yarn.lock index 45d6914c..13ffcfb9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1661,6 +1661,20 @@ resolved "https://registry.nlark.com/@types/braces/download/@types/braces-3.0.1.tgz#5a284d193cfc61abb2e5a50d36ebbc50d942a32b" integrity sha1-WihNGTz8Yauy5aUNNuu8UNlCoys= +"@types/chalk@^2.2.0": + version "2.2.0" + resolved "https://registry.npmjs.org/@types/chalk/-/chalk-2.2.0.tgz#b7f6e446f4511029ee8e3f43075fb5b73fbaa0ba" + integrity sha512-1zzPV9FDe1I/WHhRkf9SNgqtRJWZqrBWgu7JGveuHmmyR9CnAPCie2N/x+iHrgnpYBIcCJWHBoMRv2TRWktsvw== + dependencies: + chalk "*" + +"@types/commander@^2.12.2": + version "2.12.2" + resolved "https://registry.npmjs.org/@types/commander/-/commander-2.12.2.tgz#183041a23842d4281478fa5d23c5ca78e6fd08ae" + integrity sha512-0QEFiR8ljcHp9bAbWxecjVRuAMr16ivPiGOw6KFQBVrVd0RQIcM3xKdRisH2EDWgVWujiYtHwhSkSUoAAGzH7Q== + dependencies: + commander "*" + "@types/estree@^0.0.48": version "0.0.48" resolved "https://registry.nlark.com/@types/estree/download/@types/estree-0.0.48.tgz#18dc8091b285df90db2f25aa7d906cfc394b7f74" @@ -2667,6 +2681,14 @@ caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001248: resolved "https://registry.nlark.com/caniuse-lite/download/caniuse-lite-1.0.30001249.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcaniuse-lite%2Fdownload%2Fcaniuse-lite-1.0.30001249.tgz#90a330057f8ff75bfe97a94d047d5e14fabb2ee8" integrity sha1-kKMwBX+P91v+l6lNBH1eFPq7Lug= +chalk@*, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.nlark.com/chalk/download/chalk-4.1.2.tgz?cache=0&sync_timestamp=1627647108647&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fchalk%2Fdownload%2Fchalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha1-qsTit3NKdAhnrrFr8CqtVWoeegE= + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chalk@4.1.0: version "4.1.0" resolved "https://registry.nlark.com/chalk/download/chalk-4.1.0.tgz?cache=0&sync_timestamp=1627647108647&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fchalk%2Fdownload%2Fchalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" @@ -2684,14 +2706,6 @@ chalk@^2.0.0, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: - version "4.1.2" - resolved "https://registry.nlark.com/chalk/download/chalk-4.1.2.tgz?cache=0&sync_timestamp=1627647108647&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fchalk%2Fdownload%2Fchalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha1-qsTit3NKdAhnrrFr8CqtVWoeegE= - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - char-regex@^1.0.2: version "1.0.2" resolved "https://registry.nlark.com/char-regex/download/char-regex-1.0.2.tgz?cache=0&sync_timestamp=1622809452827&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fchar-regex%2Fdownload%2Fchar-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" @@ -2719,6 +2733,11 @@ character-reference-invalid@^1.0.0: resolved "https://registry.npm.taobao.org/character-reference-invalid/download/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" integrity sha1-CDMpzaDq4nKrPbvzfpo4LBOvFWA= +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + "chokidar@>=3.0.0 <4.0.0": version "3.5.2" resolved "https://registry.nlark.com/chokidar/download/chokidar-3.5.2.tgz?cache=0&sync_timestamp=1623763792599&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fchokidar%2Fdownload%2Fchokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" @@ -2786,6 +2805,11 @@ cli-truncate@^2.1.0: slice-ansi "^3.0.0" string-width "^4.2.0" +cli-width@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" + integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== + cliui@^6.0.0: version "6.0.0" resolved "https://registry.nlark.com/cliui/download/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" @@ -2862,12 +2886,17 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" +commander@*, commander@^8.1.0: + version "8.1.0" + resolved "https://registry.npmjs.org/commander/-/commander-8.1.0.tgz#db36e3e66edf24ff591d639862c6ab2c52664362" + integrity sha512-mf45ldcuHSYShkplHHGKWb4TrmwQadxOn7v4WuhDJy0ZVoY5JFajaRDKD0PNe5qXzBX0rhovjTnP6Kz9LETcuA== + commander@^6.1.0: version "6.2.1" resolved "https://registry.nlark.com/commander/download/commander-6.2.1.tgz?cache=0&sync_timestamp=1627358801712&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcommander%2Fdownload%2Fcommander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" integrity sha1-B5LraC37wyWZm7K4T93duhEKxzw= -commander@^7.1.0, commander@^7.2.0: +commander@^7.2.0: version "7.2.0" resolved "https://registry.nlark.com/commander/download/commander-7.2.0.tgz?cache=0&sync_timestamp=1627358801712&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcommander%2Fdownload%2Fcommander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha1-o2y1fQtQHOEI5NIFWaFQo5HZerc= @@ -3521,6 +3550,15 @@ extend@^3.0.0: resolved "https://registry.nlark.com/extend/download/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo= +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.npm.taobao.org/fast-deep-equal/download/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -3566,6 +3604,13 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +figures@^3.0.0: + version "3.2.0" + resolved "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.npm.taobao.org/file-entry-cache/download/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -3940,7 +3985,7 @@ husky@^4.3.7: slash "^3.0.0" which-pm-runs "^1.0.0" -iconv-lite@0.4.24: +iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.nlark.com/iconv-lite/download/iconv-lite-0.4.24.tgz?cache=0&sync_timestamp=1621826418510&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ficonv-lite%2Fdownload%2Ficonv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha1-ICK0sl+93CHS9SSXSkdKr+czkIs= @@ -4021,6 +4066,26 @@ ini@^1.3.4, ini@^1.3.5: resolved "https://registry.npm.taobao.org/ini/download/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha1-op2kJbSIBvNHZ6Tvzjlyaa8oQyw= +inquirer@^8.1.2: + version "8.1.2" + resolved "https://registry.npmjs.org/inquirer/-/inquirer-8.1.2.tgz#65b204d2cd7fb63400edd925dfe428bafd422e3d" + integrity sha512-DHLKJwLPNgkfwNmsuEUKSejJFbkv0FMO9SMiQbjI3n5NQuCrSIBqP66ggqyz2a6t2qEolKrMjhQ3+W/xXgUQ+Q== + dependencies: + ansi-escapes "^4.2.1" + chalk "^4.1.1" + cli-cursor "^3.1.0" + cli-width "^3.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.21" + mute-stream "0.0.8" + ora "^5.3.0" + run-async "^2.4.0" + rxjs "^7.2.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + interpret@^1.0.0: version "1.4.0" resolved "https://registry.npm.taobao.org/interpret/download/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" @@ -5202,6 +5267,11 @@ ms@2.1.2: resolved "https://registry.nlark.com/ms/download/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk= +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + mz@^2.4.0: version "2.7.0" resolved "https://registry.nlark.com/mz/download/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" @@ -5361,7 +5431,7 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" -ora@^5.4.0: +ora@^5.3.0, ora@^5.4.0: version "5.4.1" resolved "https://registry.nlark.com/ora/download/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" integrity sha1-GyZ4Qmr0rEpQkAjl5KyemVnbnhg= @@ -5376,6 +5446,26 @@ ora@^5.4.0: strip-ansi "^6.0.0" wcwidth "^1.0.1" +ora@^5.4.1: + version "5.4.1" + resolved "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" + integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== + dependencies: + bl "^4.1.0" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-spinners "^2.5.0" + is-interactive "^1.0.0" + is-unicode-supported "^0.1.0" + log-symbols "^4.1.0" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + p-each-series@^2.1.0: version "2.2.0" resolved "https://registry.npm.taobao.org/p-each-series/download/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" @@ -6065,6 +6155,11 @@ rollup@^2.38.5: optionalDependencies: fsevents "~2.3.2" +run-async@^2.4.0: + version "2.4.1" + resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.npm.taobao.org/run-parallel/download/run-parallel-1.2.0.tgz?cache=0&sync_timestamp=1612926584650&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frun-parallel%2Fdownload%2Frun-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -6079,6 +6174,13 @@ rxjs@^6.6.7: dependencies: tslib "^1.9.0" +rxjs@^7.2.0: + version "7.3.0" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.3.0.tgz#39fe4f3461dc1e50be1475b2b85a0a88c1e938c6" + integrity sha512-p2yuGIg9S1epc3vrjKf6iVb3RCaAYjYskkO+jHIaV0IjOPlJop4UnodOoFb2xeNwlguqLYvGw1b1McillYb5Gw== + dependencies: + tslib "~2.1.0" + safe-buffer@5.1.2, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.nlark.com/safe-buffer/download/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -6588,11 +6690,18 @@ through2@^4.0.0: dependencies: readable-stream "3" -"through@>=2.2.7 <3", through@^2.3.8: +"through@>=2.2.7 <3", through@^2.3.6, through@^2.3.8: version "2.3.8" resolved "https://registry.npm.taobao.org/through/download/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + tmpl@1.0.x: version "1.0.4" resolved "https://registry.npm.taobao.org/tmpl/download/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" @@ -6663,6 +6772,11 @@ tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.nlark.com/tslib/download/tslib-1.14.1.tgz?cache=0&sync_timestamp=1623452008922&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ftslib%2Fdownload%2Ftslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha1-zy04vcNKE0vK8QkcQfZhni9nLQA= +tslib@~2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" + integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.npm.taobao.org/tsutils/download/tsutils-3.21.0.tgz?cache=0&sync_timestamp=1615171794332&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsutils%2Fdownload%2Ftsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" -- Gitee From 9c3ae6aea9ab19f77810b11e5a522f89f9cc07c2 Mon Sep 17 00:00:00 2001 From: leihaohao Date: Tue, 10 Aug 2021 13:48:33 +0800 Subject: [PATCH 2/4] =?UTF-8?q?build:=20=E5=88=9B=E5=BB=BA=20vue-devui.ts?= =?UTF-8?q?=20=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 创建 vue-devui.ts 功能完成 - 创建文件时增加 spinner --- devui-cli/commands/create.mjs | 112 ++++++++++++++++++++++-------- devui-cli/shared/constant.js | 5 +- devui-cli/shared/utils.mjs | 63 +++++++++++++++++ devui-cli/templates/vue-devui.mjs | 46 ++++++++++++ package.json | 2 + yarn.lock | 24 +++---- 6 files changed, 207 insertions(+), 45 deletions(-) create mode 100644 devui-cli/templates/vue-devui.mjs diff --git a/devui-cli/commands/create.mjs b/devui-cli/commands/create.mjs index 22e1b0f4..8de8ce80 100644 --- a/devui-cli/commands/create.mjs +++ b/devui-cli/commands/create.mjs @@ -1,8 +1,17 @@ import logger from '../shared/logger.mjs' -import { bigCamelCase } from '../shared/utils.mjs' +import { bigCamelCase, resolveDirFilesInfo, parseExportByFileInfo } from '../shared/utils.mjs' import fs from 'fs-extra' import { resolve } from 'path' -import { DEVUI_NAMESPACE, DEVUI_DIR, TESTS_DIR_NAME, COMPONENT_PARTS_MAP } from '../shared/constant.js' +import { + DEVUI_NAMESPACE, + DEVUI_DIR, + TESTS_DIR_NAME, + COMPONENT_PARTS_MAP, + INDEX_FILE_NAME, + VUE_DEVUI_FILE, + VUE_DEVUI_IGNORE_DIRS, + VUE_DEVUI_FILE_NAME +} from '../shared/constant.js' import { isEmpty, kebabCase } from 'lodash-es' import inquirer from 'inquirer' import { selectCreateType } from '../inquirers/create.mjs' @@ -16,6 +25,8 @@ import { createIndexTemplate, createTestsTemplate } from '../templates/component.mjs' +import { createVueDevuiTemplate } from '../templates/vue-devui.mjs' +import ora from 'ora' export function validateCreateType(type) { const flag = /^(component|(vue-devui)|(vitepress\/sidebar))$/.test(type) @@ -33,18 +44,29 @@ export async function create(cwd) { type = result.type } - if (type !== 'component') { + if (['vitepress/sidebar'].includes(type)) { logger.info('抱歉,该功能暂未完成!') return process.exit(0) } - const result = await inquirer.prompt([typeName(), typeTitle(), selectCategory(), selectParts()]) - result.hasComponent = result.parts.includes(COMPONENT_PARTS_MAP.get('component')) - result.hasDirective = result.parts.includes(COMPONENT_PARTS_MAP.get('directive')) - result.hasService = result.parts.includes(COMPONENT_PARTS_MAP.get('service')) - try { - await createComponent(result) + switch (type) { + case 'component': + const result = await inquirer.prompt([typeName(), typeTitle(), selectCategory(), selectParts()]) + result.hasComponent = result.parts.includes(COMPONENT_PARTS_MAP.get('component')) + result.hasDirective = result.parts.includes(COMPONENT_PARTS_MAP.get('directive')) + result.hasService = result.parts.includes(COMPONENT_PARTS_MAP.get('service')) + + await createComponent(result) + break + case 'vue-devui': + await createVueDevui() + break + case 'vitepress/sidebar': + break + default: + break + } } catch (e) { logger.error(e.toString()) process.exit(1) @@ -88,31 +110,65 @@ async function createComponent(params = {}) { return process.exit(1) } - await Promise.all([fs.mkdirs(componentDir), fs.mkdirs(srcDir), fs.mkdirs(testsDir)]) + let spinner = ora(`创建组件 ${bigCamelCase(componentName)} 开始...`).start() - const writeFiles = [fs.writeFile(resolve(componentDir, `index.ts`), indexTemplate)] + try { + await Promise.all([fs.mkdirs(componentDir), fs.mkdirs(srcDir), fs.mkdirs(testsDir)]) - if (hasComponent || hasService) { - writeFiles.push(fs.writeFile(resolve(srcDir, `${typesName}.ts`), typesTemplate)) - } + const writeFiles = [fs.writeFile(resolve(componentDir, INDEX_FILE_NAME), indexTemplate)] - if (hasComponent) { - writeFiles.push( - fs.writeFile(resolve(srcDir, `${componentName}.tsx`), componentTemplate), - fs.writeFile(resolve(srcDir, `${styleName}.scss`), styleTemplate) - ) - } + if (hasComponent || hasService) { + writeFiles.push(fs.writeFile(resolve(srcDir, `${typesName}.ts`), typesTemplate)) + } - if (hasDirective) { - writeFiles.push(fs.writeFile(resolve(srcDir, `${directiveName}.ts`), directiveTemplate)) - } + if (hasComponent) { + writeFiles.push( + fs.writeFile(resolve(srcDir, `${componentName}.tsx`), componentTemplate), + fs.writeFile(resolve(srcDir, `${styleName}.scss`), styleTemplate) + ) + } - if (hasService) { - writeFiles.push(fs.writeFile(resolve(srcDir, `${serviceName}.ts`), serviceTemplate)) + if (hasDirective) { + writeFiles.push(fs.writeFile(resolve(srcDir, `${directiveName}.ts`), directiveTemplate)) + } + + if (hasService) { + writeFiles.push(fs.writeFile(resolve(srcDir, `${serviceName}.ts`), serviceTemplate)) + } + + await Promise.all(writeFiles) + + spinner.succeed(`创建组件 ${bigCamelCase(componentName)} 成功!`) + logger.info(`组件目录:${componentDir}`) + } catch (e) { + spinner.fail(e.toString()) + process.exit(1) } +} + +async function createVueDevui() { + const fileInfo = resolveDirFilesInfo(DEVUI_DIR, VUE_DEVUI_IGNORE_DIRS) + const exportModules = [] + + fileInfo.forEach((f) => { + const em = parseExportByFileInfo(f) + + if (isEmpty(em)) return + + exportModules.push(em) + }) + + const template = createVueDevuiTemplate(exportModules) - await Promise.all(writeFiles) + let spinner = ora(`创建 ${VUE_DEVUI_FILE_NAME} 文件开始...`).start() - logger.info(`组件目录:${componentDir}`) - logger.success('创建成功!') + try { + await fs.writeFile(VUE_DEVUI_FILE, template, { encoding: 'utf-8' }) + + spinner.succeed(`创建 ${VUE_DEVUI_FILE_NAME} 文件成功!`) + logger.info(`文件地址:${VUE_DEVUI_FILE}`) + } catch (e) { + spinner.fail(e.toString()) + process.exit(1) + } } diff --git a/devui-cli/shared/constant.js b/devui-cli/shared/constant.js index 6fd85eac..d4852ff0 100644 --- a/devui-cli/shared/constant.js +++ b/devui-cli/shared/constant.js @@ -5,8 +5,11 @@ exports.VERSION = version exports.CWD = process.cwd() exports.DEVUI_DIR = resolve(this.CWD, 'devui') exports.DEVUI_NAMESPACE = 'd' -exports.DEVUI_INDEX_FILE = 'vue-devui.ts' exports.TESTS_DIR_NAME = '__tests__' +exports.INDEX_FILE_NAME = 'index.ts' +exports.VUE_DEVUI_IGNORE_DIRS = ['shared', 'style'] +exports.VUE_DEVUI_FILE_NAME = 'vue-devui.ts' +exports.VUE_DEVUI_FILE = resolve(this.DEVUI_DIR, this.VUE_DEVUI_FILE_NAME) exports.COMPONENT_PARTS_MAP = new Map([ ['component', 'component(组件)'], diff --git a/devui-cli/shared/utils.mjs b/devui-cli/shared/utils.mjs index b64507ec..f56492c2 100644 --- a/devui-cli/shared/utils.mjs +++ b/devui-cli/shared/utils.mjs @@ -1,5 +1,68 @@ import { camelCase, upperFirst } from 'lodash-es' +import { INDEX_FILE_NAME } from './constant.js' +import { resolve } from 'path' +import logger from './logger.mjs' +import fs from 'fs-extra' export function bigCamelCase(str) { return upperFirst(camelCase(str)) } + +export function resolveDirFilesInfo(targetDir, ignoreDirs = []) { + return fs + .readdirSync(targetDir) + .filter( + (dir) => + // 过滤:必须是目录,且不存在与忽略目录内,拥有 INDEX_FILE_NAME + fs.statSync(resolve(targetDir, dir)).isDirectory() && + !ignoreDirs.includes(dir) && + fs.existsSync(resolve(targetDir, dir, INDEX_FILE_NAME)) + ) + .map((dir) => ({ + name: bigCamelCase(dir), + dirname: dir, + path: resolve(targetDir, dir, INDEX_FILE_NAME) + })) +} + +export function parseExportByFileInfo(fileInfo) { + const exportModule = {} + const indexContent = fs.readFileSync(fileInfo.path, { encoding: 'utf-8' }) + + const defaultRe = /export default/ + const partRe = /export {/ + + if (!defaultRe.test(indexContent)) { + logger.error(`${fileInfo.path} must have "export default".`) + return process.exit(1) + } + + if (!partRe.test(indexContent)) { + logger.error(`${fileInfo.path} must have "export {}".`) + return process.exit(1) + } + + const parts = [] + let searchContent = indexContent + + while (searchContent.search(partRe) !== -1) { + const reStartIndex = indexContent.search(partRe) + const partStartIndex = indexContent.indexOf('{', reStartIndex) + 1 + const partEndIndex = indexContent.indexOf('}', partStartIndex) - 1 + + const partContent = indexContent.slice(partStartIndex, partEndIndex) + + partContent + .replace(/(\s|\r|\n|\t)/g, '') + .split(',') + .forEach((p) => parts.push(p)) + + searchContent = indexContent.slice(partEndIndex) + } + + exportModule.default = fileInfo.name + 'Install' + exportModule.parts = parts + exportModule.fileInfo = fileInfo + + return exportModule +} diff --git a/devui-cli/templates/vue-devui.mjs b/devui-cli/templates/vue-devui.mjs new file mode 100644 index 00000000..7d242f91 --- /dev/null +++ b/devui-cli/templates/vue-devui.mjs @@ -0,0 +1,46 @@ +import { relative } from 'path' +import { INDEX_FILE_NAME, VERSION } from '../shared/constant.js' +import { VUE_DEVUI_FILE } from '/own-files/own-workspace/vue-devui/devui-cli/shared/constant.js' + +export function createVueDevuiTemplate(exportModules = []) { + const packages = [] + const imports = [] + const installs = [] + + exportModules.forEach((m) => { + const { fileInfo } = m + const relativePath = relative(VUE_DEVUI_FILE, fileInfo.path) + .replace(/\\/g, '/') + .replace('..', '.') + .replace('/' + INDEX_FILE_NAME, '') + + const importStr = `import ${m.default}, { ${m.parts.join(', ')} } from '${relativePath}'` + + packages.push(...m.parts) + imports.push(importStr) + installs.push(m.default) + }) + + const template = `\ +import type { App } from 'vue' + +${imports.join('\n')} + +const installs = [ + ${installs.join(',\n\t')} +] + +export { + ${packages.join(',\n\t')} +} + +export default { + version: '${VERSION}', + install(app: App) { + installs.forEach((p) => app.use(p)) + } +} +` + + return template +} diff --git a/package.json b/package.json index bc2a43cc..24f7c54a 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "convert:route": "node ./scripts/convert-component-route.js", "publish": "cd dist && npm publish", "generate:devui": "node scripts/generate-devui.js", + "predev": "devui-cli create -t vue-devui", "postinstall": "npm link" }, "dependencies": { @@ -54,6 +55,7 @@ "@types/chalk": "^2.2.0", "@types/commander": "^2.12.2", "@types/jest": "^26.0.23", + "@types/ora": "^3.2.0", "@typescript-eslint/eslint-plugin": "^4.27.0", "@typescript-eslint/parser": "^4.27.0", "@vitejs/plugin-vue": "^1.3.0", diff --git a/yarn.lock b/yarn.lock index 13ffcfb9..95a75658 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1784,6 +1784,13 @@ resolved "https://registry.nlark.com/@types/normalize-package-data/download/@types/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" integrity sha1-0zV0eaD9/dWQf+Z+F+CoXJBuEwE= +"@types/ora@^3.2.0": + version "3.2.0" + resolved "https://registry.npmjs.org/@types/ora/-/ora-3.2.0.tgz#b2f65d1283a8f36d8b0f9ee767e0732a2f429362" + integrity sha512-jll99xUKpiFbIFZSQcxm4numfsLaOWBzWNaRk3PvTSE7BPqTzzOCFmS0mQ7m8qkTfmYhuYbehTGsxkvRLPC++w== + dependencies: + ora "*" + "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.nlark.com/@types/parse-json/download/@types/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" @@ -5431,7 +5438,7 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" -ora@^5.3.0, ora@^5.4.0: +ora@*, ora@^5.3.0, ora@^5.4.0, ora@^5.4.1: version "5.4.1" resolved "https://registry.nlark.com/ora/download/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" integrity sha1-GyZ4Qmr0rEpQkAjl5KyemVnbnhg= @@ -5446,21 +5453,6 @@ ora@^5.3.0, ora@^5.4.0: strip-ansi "^6.0.0" wcwidth "^1.0.1" -ora@^5.4.1: - version "5.4.1" - resolved "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" - integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== - dependencies: - bl "^4.1.0" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-spinners "^2.5.0" - is-interactive "^1.0.0" - is-unicode-supported "^0.1.0" - log-symbols "^4.1.0" - strip-ansi "^6.0.0" - wcwidth "^1.0.1" - os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" -- Gitee From d2302f8d0e7113479391039ed7549843eac22c4a Mon Sep 17 00:00:00 2001 From: leihaohao Date: Tue, 10 Aug 2021 13:59:58 +0800 Subject: [PATCH 3/4] =?UTF-8?q?build:=20devui-cli=20create=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E9=85=8D=E7=BD=AE=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 增加忽略解析错误配置项 --- devui-cli/commands/create.mjs | 8 ++++---- devui-cli/index.mjs | 1 + devui-cli/shared/utils.mjs | 16 +++++++++++++--- devui-cli/templates/vue-devui.mjs | 2 +- package.json | 2 +- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/devui-cli/commands/create.mjs b/devui-cli/commands/create.mjs index 8de8ce80..197dff1a 100644 --- a/devui-cli/commands/create.mjs +++ b/devui-cli/commands/create.mjs @@ -37,7 +37,7 @@ export function validateCreateType(type) { } export async function create(cwd) { - let { type } = cwd + let { type, ignoreParseError } = cwd if (isEmpty(type)) { const result = await inquirer.prompt([selectCreateType()]) @@ -60,7 +60,7 @@ export async function create(cwd) { await createComponent(result) break case 'vue-devui': - await createVueDevui() + await createVueDevui(ignoreParseError) break case 'vitepress/sidebar': break @@ -146,12 +146,12 @@ async function createComponent(params = {}) { } } -async function createVueDevui() { +async function createVueDevui(ignoreParseError) { const fileInfo = resolveDirFilesInfo(DEVUI_DIR, VUE_DEVUI_IGNORE_DIRS) const exportModules = [] fileInfo.forEach((f) => { - const em = parseExportByFileInfo(f) + const em = parseExportByFileInfo(f, ignoreParseError) if (isEmpty(em)) return diff --git a/devui-cli/index.mjs b/devui-cli/index.mjs index dd0948da..9ad3ce60 100644 --- a/devui-cli/index.mjs +++ b/devui-cli/index.mjs @@ -9,6 +9,7 @@ program .command('create') .description('创建一个组件模板或配置文件') .option('-t --type ', '创建类型,可选值:component, vue-devui, vitepress/sidebar', validateCreateType) + .option('--ignore-parse-error', '忽略解析错误', false) .action(create) program.parse().version(VERSION) diff --git a/devui-cli/shared/utils.mjs b/devui-cli/shared/utils.mjs index f56492c2..2d0b82e3 100644 --- a/devui-cli/shared/utils.mjs +++ b/devui-cli/shared/utils.mjs @@ -25,7 +25,7 @@ export function resolveDirFilesInfo(targetDir, ignoreDirs = []) { })) } -export function parseExportByFileInfo(fileInfo) { +export function parseExportByFileInfo(fileInfo, ignoreParseError) { const exportModule = {} const indexContent = fs.readFileSync(fileInfo.path, { encoding: 'utf-8' }) @@ -34,12 +34,22 @@ export function parseExportByFileInfo(fileInfo) { if (!defaultRe.test(indexContent)) { logger.error(`${fileInfo.path} must have "export default".`) - return process.exit(1) + + if (ignoreParseError) { + return exportModule + } else { + process.exit(1) + } } if (!partRe.test(indexContent)) { logger.error(`${fileInfo.path} must have "export {}".`) - return process.exit(1) + + if (ignoreParseError) { + return exportModule + } else { + process.exit(1) + } } const parts = [] diff --git a/devui-cli/templates/vue-devui.mjs b/devui-cli/templates/vue-devui.mjs index 7d242f91..f6358428 100644 --- a/devui-cli/templates/vue-devui.mjs +++ b/devui-cli/templates/vue-devui.mjs @@ -37,7 +37,7 @@ export { export default { version: '${VERSION}', install(app: App) { - installs.forEach((p) => app.use(p)) + installs.forEach((p) => app.use(p as any)) } } ` diff --git a/package.json b/package.json index 24f7c54a..4cd41b0a 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "convert:route": "node ./scripts/convert-component-route.js", "publish": "cd dist && npm publish", "generate:devui": "node scripts/generate-devui.js", - "predev": "devui-cli create -t vue-devui", + "predev": "devui-cli create -t vue-devui --ignore-parse-error", "postinstall": "npm link" }, "dependencies": { -- Gitee From 6245b57209a234fc9133bfb30344a31682e51021 Mon Sep 17 00:00:00 2001 From: leihaohao Date: Tue, 10 Aug 2021 16:50:43 +0800 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20PR=20=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 模块导入路径修改 --- devui-cli/templates/vue-devui.mjs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/devui-cli/templates/vue-devui.mjs b/devui-cli/templates/vue-devui.mjs index f6358428..8414b648 100644 --- a/devui-cli/templates/vue-devui.mjs +++ b/devui-cli/templates/vue-devui.mjs @@ -1,6 +1,5 @@ import { relative } from 'path' -import { INDEX_FILE_NAME, VERSION } from '../shared/constant.js' -import { VUE_DEVUI_FILE } from '/own-files/own-workspace/vue-devui/devui-cli/shared/constant.js' +import { INDEX_FILE_NAME, VERSION, VUE_DEVUI_FILE } from '../shared/constant.js' export function createVueDevuiTemplate(exportModules = []) { const packages = [] -- Gitee