UNPKG

press-ui

Version:

简单、易用的跨端组件库,兼容 Vue2 和 Vue3,同时支持 uni-app和普通 Vue 项目

216 lines (169 loc) 5.36 kB
const fs = require('fs'); const path = require('path'); const { replaceAllPolyfill, hyphenate } = require('t-comm'); // eslint-disable-next-line import/order const glob = require('glob'); replaceAllPolyfill(); const PACKAGE_ENTRY_JS = './src/packages/index.js'; const MAIN_TEMPLATE = `/* eslint-disable import/order */ /* Automatically generated by 'press-ui/script/generate-component-config/generate-entry.js' */ {{install}} const components = { {{components}} }; const install = function (Vue) { Object.values(components).forEach((component) => { Vue.component(component.name, component); }); }; if (typeof window !== 'undefined' && window.Vue) { install(window.Vue); } export default { install, ...components, }; export * from './packages/common/public/public'; `; const CSS_BASE = `/* 基础样式 */ @import './packages/common/style/press/index.scss'; @import './packages/common/style/press/var.scss'; /* 组件样式 */ `; function getAllPressComponents(globMatch) { const list = glob.sync(globMatch); const preNames = {}; const compList = list.map((item) => { const list = item.split('/'); const file = list[list.length - 1]; const componentName = file.replace(/^press-/, '').replace(/\.vue$/, ''); const parsedComponentName = componentName.replace(/(?:^|-)(\w)/g, (_, c) => (c ? c.toUpperCase() : '')); preNames[parsedComponentName] = (preNames[parsedComponentName] || 0) + 1; return { dir: path.dirname(item), name: componentName, folder: list[list.length - 2], componentName: preNames[parsedComponentName] > 1 ? parsedComponentName + preNames[parsedComponentName] : parsedComponentName, }; }); const componentNameList = compList.map(item => item.componentName); const importList = compList.map(item => `import ${item.componentName} from './packages/${item.folder}/press-${item.name}.vue';`); sortByStr(compList, 'name'); sortByStr(importList); sortByStr(componentNameList); return { compList, importList, componentNameList, }; } function generateIndexScss({ scssPath, globMatch, targetDir }) { const { compList } = getAllPressComponents(globMatch); let result = []; for (const comp of compList) { const globMatch = `${comp.dir}/css/*`; const list = glob.sync(globMatch); sortByStr(list); result.push(...list.map((item) => { let relativePath = path.relative(targetDir, item); if (process.platform === 'win32') { relativePath = relativePath.replace(/\\/g, '/'); } const str = `@import './${relativePath}';`; return str; })); } result = Array.from(new Set(result)); const resultStr = `${CSS_BASE}${result.join('\n')}`; fs.writeFileSync(scssPath, resultStr, { encoding: 'utf-8', }); } function getComponentPath(component) { const SPECIAL_COMPONENT_MAP = { 'message-board': 'message-board-list', }; return SPECIAL_COMPONENT_MAP[component] || component; } function sortByStr(list, key) { list.sort((a, b) => { const valueA = key ? a[key] : a; const valueB = key ? b[key] : b; return valueA.localeCompare(valueB); // if (valueA - valueB > 0) { // return 1; // } // if (valueA - valueB < 0) { // return -1; // } // return 0; }); } function getCompList(componentConfig) { const importList = []; const componentNameList = []; Object.keys(componentConfig) .forEach((key) => { const value = componentConfig[key]; const { list } = value; list.forEach((item) => { const hyphenatedName = hyphenate(item.name); const shortName = item.name.replace(/$Press/, ''); const compPath = getComponentPath(hyphenatedName); importList.push(`import ${shortName} from './packages/press-${hyphenatedName}/press-${compPath}.vue';`); componentNameList.push(shortName); }); }); sortByStr(importList); sortByStr(componentNameList); return { importList, componentNameList, }; } function getSrcIndexJs({ componentConfig, allComponent = false, globMatch }) { let { importList, componentNameList, } = getCompList(componentConfig); if (allComponent) { const info = getAllPressComponents(globMatch); importList = info.importList; componentNameList = info.componentNameList; } const res = MAIN_TEMPLATE .replace('{{install}}', importList.join('\n')) .replaceAll('{{components}}', componentNameList.map(item => `${item},`).join('\n ')); return res; } function writeSrcIndexJs({ componentConfig, filePath, allComponent = false, scssPath, globMatch, targetDir, }) { const js = getSrcIndexJs({ componentConfig, allComponent, globMatch }); fs.writeFileSync(filePath, js, { encoding: 'utf-8', }); const packageEntryJsContent = getAllPressComponents(globMatch) .compList .map((item) => { const result = (`export { default as ${item.componentName} } from './${item.folder}/press-${item.name}.vue';`); return result; }) .join('\n'); generateIndexScss({ scssPath, globMatch, targetDir }); fs.writeFileSync(PACKAGE_ENTRY_JS, `/* eslint-disable no-duplicate-imports */\n${packageEntryJsContent}\n`, { encoding: 'utf-8', }); } module.exports = { hyphenate, getComponentPath, writeSrcIndexJs, };