diff --git a/.gitignore b/.gitignore index 5aa59fce646e10ca856168035ccc04f0cadf3f85..e9dd2d13ce60602de292b7bc2cd5021a44dcd810 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ node_modules .DS_Store dist dist-ssr +build *.local package-lock.json pnpm-lock.yaml diff --git a/devui-cli/commands/build.js b/devui-cli/commands/build.js new file mode 100644 index 0000000000000000000000000000000000000000..1d2090d8e5f5cc8bb4694707d4cbf39813c1ef31 --- /dev/null +++ b/devui-cli/commands/build.js @@ -0,0 +1,69 @@ +const path = require('path') +const fs = require('fs') +const { defineConfig, build } = require('vite') +const vue = require('@vitejs/plugin-vue') +const vueJsx = require('@vitejs/plugin-vue-jsx') + +const entryDir = path.resolve(__dirname, '../devui') +const outputDir = path.resolve(__dirname, '../build') + +const baseConfig = defineConfig({ + configFile: false, + publicDir: false, + plugins: [ vue(), vueJsx() ] +}) + +const rollupOptions = { + external: ['vue', 'vue-router'], + output: { + globals: { + vue: 'Vue' + } + } +} + +const buildSingle = async (name) => { + await build(defineConfig({ + ...baseConfig, + build: { + rollupOptions, + lib: { + entry: path.resolve(entryDir, name), + name: 'index', + fileName: 'index', + formats: ['es', 'umd'] + }, + outDir: path.resolve(outputDir, name) + } + })) +} + +const buildAll = async () => { + await build(defineConfig({ + ...baseConfig, + build: { + rollupOptions, + lib: { + entry: path.resolve(entryDir, 'vue-devui.ts'), + name: 'vue-devui', + fileName: 'vue-devui', + formats: ['es', 'umd'] + }, + outDir: outputDir + } + })) +} + +exports.build = async () => { + await buildAll() + + const components = fs.readdirSync(entryDir).filter(name => { + const componentDir = path.resolve(entryDir, name) + const isDir = fs.lstatSync(componentDir).isDirectory() + return isDir && fs.readdirSync(componentDir).includes('index.ts') + }) + + for(const name of components) { + await buildSingle(name) + } +} diff --git a/devui-cli/index.js b/devui-cli/index.js index db57d98ceefbd37438856df09d79ddcf210277ea..24f11c31cce75277a294fa522ced1dee9cf571da 100755 --- a/devui-cli/index.js +++ b/devui-cli/index.js @@ -1,6 +1,7 @@ #!/usr/bin/env node const { Command } = require('commander') const { create, validateCreateType } = require('./commands/create') +const { build } = require('./commands/build') const { VERSION, CREATE_SUPPORT_TYPES } = require('./shared/constant') const program = new Command() @@ -13,4 +14,9 @@ program .option('--cover', '覆盖原文件', false) .action(create) +program + .command('build') + .description('打包组件库') + .action(build) + program.parse().version(VERSION) diff --git a/package.json b/package.json index e1c54ce87023c9e71f5bdc7899aae2696ea49aef..fe1f86db4c8886e3d1fbb68878cd48170bdb7c21 100644 --- a/package.json +++ b/package.json @@ -27,14 +27,13 @@ "serve": "vitepress serve sites", "app:dev": "vite", "app:build": "vite build", - "build:lib": "yarn predev && vite build --config vite.config.build.ts && cp package.json dist && cp README.md dist", + "build:lib": "yarn predev && yarn build:components && cp package.json build && cp README.md build", "test": "jest --config jest.config.js", "ls-lint": "ls-lint", "lint": "eslint \"{src,devui}/**/*.{vue,js,ts,jsx,tsx}\"", "lint:fix": "eslint --fix \"{src,devui}/**/*.{vue,js,ts,jsx,tsx}\"", "stylelint": "stylelint --fix \"{devui,src}/**/*.{scss,css}\"", - "convert:route": "node ./scripts/convert-component-route.js", - "generate:devui": "node scripts/generate-devui.js", + "build:components": "node ./devui-cli/index.js build", "clean:cli": "npm uninstall -g devui-cli & npm uninstall -g vue-devui", "cli:create": "node ./devui-cli/index.js create", "predev": "node ./devui-cli/index.js create -t vue-devui --ignore-parse-error" diff --git a/scripts/add-api.js b/scripts/add-api.js deleted file mode 100644 index 5ffdbf8d9e8552bde1fb74ac10c220b0c0a73bd9..0000000000000000000000000000000000000000 --- a/scripts/add-api.js +++ /dev/null @@ -1,65 +0,0 @@ -const fs = require('fs') -const path = require('path') -const shelljs = require('shelljs') -const program = require('commander') -const { COMPONENTS } = require('./const') - -const DEFAULT_SOURCE_PATH = path.resolve(__dirname, '../../../code/ng-devui/devui') -const DEFAULT_TARGET_PATH = path.resolve(__dirname, '../devui') - -// 从命令行参数中取源文件和目标文件路径 -program - .option('-s, --source ', 'Original file path', DEFAULT_SOURCE_PATH) - .option('-t, --target ', 'Target file path', DEFAULT_TARGET_PATH) -program.parse(process.argv); - -const { source, target } = program.opts(); - -const sourcePath = source; -const targetPath = target; - -function addApi(sourcePath, targetPath) { - fs.readdir(sourcePath, function(sourcePathError, sourceComponentFolder) { - if (sourcePathError) { - console.error(sourcePathError) - return - } - - sourceComponentFolder - .filter(doc => COMPONENTS.includes(doc)) - .forEach((componentName) => { - const targetDocPath = path.resolve(targetPath, componentName, 'doc') - - // 在组件目录下创建 doc 目录 - if (!fs.existsSync(targetDocPath)) { - fs.mkdirSync(targetDocPath) - } - - // 拷贝中英文 API 文档 - const sourceDocPath = path.resolve(sourcePath, componentName, 'doc') - fs.readdir(sourceDocPath, (sourceDocPathError, sourceDocs) => { - if (sourceDocPathError) { - console.error(sourceDocPathError) - return - } - - sourceDocs.forEach(sourceDoc => { - shelljs.cp(path.resolve(sourceDocPath, sourceDoc), targetDocPath) - }) - }) - - // 修改路由 - const componentRoutePath = path.resolve(targetPath, componentName, 'demo', componentName + '.route.ts') - shelljs.sed('-i', /'..\/doc\/api-cn.md'/, 'ApiCn', componentRoutePath) - shelljs.sed('-i', /'..\/doc\/api-en.md'/, 'ApiEn', componentRoutePath) - shelljs.sed( - '-i', - /const routes = \[/, - 'import ApiCn from \'../doc/api-cn.md\'\nimport ApiEn from \'../doc/api-en.md\'\nconst routes = [', - componentRoutePath - ) - }) - }) -} - -addApi(sourcePath, targetPath) diff --git a/scripts/const.js b/scripts/const.js deleted file mode 100644 index 4f867767db1a8134a9ad18468060007fc9460712..0000000000000000000000000000000000000000 --- a/scripts/const.js +++ /dev/null @@ -1,69 +0,0 @@ -const COMPONENTS = [ - 'accordion', - 'alert', - 'anchor', - 'auto-complete', - 'avatar', - 'back-top', - 'badge', - 'breadcrumb', - 'button', - 'card', - - 'carousel', - 'cascader', - 'checkbox', - 'data-table', - 'datepicker', - 'dragdrop', - 'drawer', - 'dropdown', - 'editable-select', - 'form', - - - 'fullscreen', - 'gantt', - 'image-preview', - 'input-number', - 'layout', - 'loading', - 'modal', - 'multi-auto-complete', - 'pagination', - 'panel', - - 'popover', - 'progress', - 'quadrant-diagram', - 'radio', - 'rate', - 'read-tip', - 'search', - 'select', - 'slider', - 'splitter', - - 'status', - 'steps-guide', - 'sticky', - 'tabs', - 'tags', - 'tags-input', - 'text-input', - 'textarea', - 'time-axis', - 'time-picker', - - 'toast', - 'switch', - 'tooltip', - 'transfer', - 'tree', - 'tree-select', - 'upload', -] - -module.exports = { - COMPONENTS -} diff --git a/scripts/convert-component-route.js b/scripts/convert-component-route.js deleted file mode 100644 index eb459e2396ec2f1e5719d5c3e2111433f99a29cc..0000000000000000000000000000000000000000 --- a/scripts/convert-component-route.js +++ /dev/null @@ -1,72 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const shelljs = require('shelljs'); -const program = require('commander'); - -const DEFAULT_SOURCE_PATH = path.resolve(__dirname, '../docs/component.route.ts'); -const DEFAULT_TARGET_PATH = path.resolve(__dirname, '../src/components'); - -// 从命令行参数中取源文件和目标文件路径 -program - .option('-s, --source ', 'Original file path', DEFAULT_SOURCE_PATH) - .option('-t, --target ', 'Target file path', DEFAULT_TARGET_PATH) -program.parse(process.argv); - -const { source, target } = program.opts(); - -/** - * 将 ng-devui 的组件路由文件转换成 vue-devui 的路由文件 - * - * 主要转换规则: - * 1. loadChildren 整行移除,loadChildren 分多行的,需要将多行都移除 - * 2. data 改成 meta - * 3. import 的组件都从 app-demo-cell 导入 - * - * 例如: - * import { ExamplePanelComponent } from './example-panel.component'; -> import ExamplePanelComponent from './app-demo-cell.vue'; - * import { GetStartedComponent } from './get-started.component'; -> import GetStartedComponent from './app-demo-cell.vue'; - * import { ColorComponent } from './color/color.component'; -> import ColorComponent from './app-demo-cell.vue'; - * import { ThemeGuideComponent } from './theme-guide.component'; -> import ThemeGuideComponent from './app-demo-cell.vue'; - * - * { - * path: 'accordion', - * component: ExamplePanelComponent, - * loadChildren: () => import('../../../devui/accordion/demo/accordion-demo.moudule').then((m) => m.AccordionDemoModule), - * data: { - * type: '导航', - * enType: 'Navigation', - * name: 'Accordion', - * cnName: '手风琴', - * }, - * }, - * -> - * { - * path: 'accordion', - * component: ExamplePanelComponent, - * meta: { - * type: '导航', - * enType: 'Navigation', - * name: 'Accordion', - * cnName: '手风琴', - * }, - * }, - */ -function convertComponentRoute(source, target) { - shelljs.sed('-i', /import { ExamplePanelComponent } from '.\/example-panel.component'/, 'import ExamplePanelComponent from \'.\/app-demo-cell.vue\'', source); - shelljs.sed('-i', /import { GetStartedComponent } from '.\/get-started.component'/, 'import GetStartedComponent from \'.\/app-demo-cell.vue\'', source); - shelljs.sed('-i', /import { ColorComponent } from '.\/color\/color.component'/, 'import ColorComponent from \'.\/app-demo-cell.vue\'', source); - shelljs.sed('-i', /import { ThemeGuideComponent } from '.\/theme-guide.component'/, 'import ThemeGuideComponent from \'.\/app-demo-cell.vue\'', source); - - shelljs.sed('-i', /redirectTo: 'get-start'/, 'redirect: \'/components/button\'', source); - - shelljs.sed('-i', /^.*loadChildren.*$/, '', source); - shelljs.sed('-i', /^.*import\(.*$/, '', source); - - shelljs.sed('-i', /data: {/, 'meta: {', source); - - shelljs.sed('-i', /];/, '];\n\nexport default routesConfig;', source); - - shelljs.cp(source, target); -} - -convertComponentRoute(source, target); diff --git a/scripts/delete-old-api.js b/scripts/delete-old-api.js deleted file mode 100644 index b4517dffa7f8aab48c7b8372371a6010c250aad1..0000000000000000000000000000000000000000 --- a/scripts/delete-old-api.js +++ /dev/null @@ -1,28 +0,0 @@ -const fs = require('fs') -const path = require('path') -const shelljs = require('shelljs') -const { COMPONENTS } = require('./const') - -const targetPath = path.resolve(__dirname, '../devui') - -function deleteOldApi(targetPath) { - fs.readdir(targetPath, function(targetPathError, targetComponentFolder) { - if (targetPathError) { - console.error(targetPathError) - return - } - - targetComponentFolder - .filter(doc => COMPONENTS.includes(doc)) - .forEach((componentName) => { - const targetApiPath = path.resolve(targetPath, componentName, 'api') - - // 在组件目录下创建 doc 目录 - if (fs.existsSync(targetApiPath)) { - shelljs.rm('-rf', targetApiPath); - } - }) - }) -} - -deleteOldApi(targetPath) diff --git a/scripts/generate-devui.js b/scripts/generate-devui.js deleted file mode 100644 index 34976e1a6281aae361cf4a6f33933aa84b0b37ff..0000000000000000000000000000000000000000 --- a/scripts/generate-devui.js +++ /dev/null @@ -1,47 +0,0 @@ -require('esbuild-register'); - -const path = require('path'); -const fs = require('fs-extra'); - -const config = require('../sites/.vitepress/config/sidebar').default; -console.log('config:', config); - -let importStr = `import { App } from 'vue';\n\n`; -const components = []; - -config['/'].forEach(({ text: ctext, children }) => { - if (ctext !== '快速开始') { - importStr += `// ${ctext}\n`; - console.log('ctext:', ctext); - console.log('children:', children); - children && children.forEach(({ text, link }) => { - const name = text.split(' ')[0]; - const linkItem = link.split('/').filter(item => item); - const filename = linkItem[1]; - importStr += `import ${name} from './${filename}';\n`; - components.push(name); - }) - importStr += `\n`; - } -}); - -const componentStr = components.join(', '); - -let installStr = `function install(app: App): void { - const packages = [ ${componentStr} ]; - packages.forEach((item: any) => { - if (item.install) { - app.use(item); - } else if (item.name) { - app.component(item.name, item); - } - }); -}\n\n`; - -const exportStr = `export { ${componentStr} }; -export default { install, version: '0.0.1' };`; - -const fileStr = importStr + installStr + exportStr; - -const targetFile = path.resolve(__dirname, '../devui/vue-devui.ts'); -fs.outputFile(targetFile, fileStr, 'utf8'); diff --git a/sites/index.md b/sites/index.md index 403f7e8fb3dc5d310d7e2d49bdda881fadc60f1d..0e850304b15b0585b5ef2da151e9037256434a1c 100644 --- a/sites/index.md +++ b/sites/index.md @@ -10,7 +10,7 @@ 推荐使用@vite/cli创建你的项目 -```sh +```shell yarn create vite my-vue-app --template vue-ts ``` @@ -18,7 +18,7 @@ yarn create vite my-vue-app --template vue-ts 进入你的项目文件夹,使用yarn安装DevUI -```sh +```shell yarn add vue-devui # 可选,字体图标库, 部分Demo依赖此字体库 @@ -38,6 +38,6 @@ createApp(App).use(DevUI).mount('#app') ### 4. 启动开发调试 -```sh +```shell yarn dev ``` \ No newline at end of file