diff --git a/.eslintrc.js b/.eslintrc.js index 4b3d3af29..f7a3043b1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -28,7 +28,8 @@ module.exports = { ], 'vue/no-multiple-template-root': 0, 'vue/no-lone-template': 0, - 'vue/no-v-model-argument': 0 + 'vue/no-v-model-argument': 0, + 'vue/one-component-per-file': 0 } }, { diff --git a/package.json b/package.json index f95628f9c..d5793d6e5 100644 --- a/package.json +++ b/package.json @@ -23,11 +23,12 @@ "test:cov": "cross-env NODE_ENV=test NODE_OPTIONS=--unhandled-rejections=warn jest", "test:watch": "cross-env NODE_ENV=test jest ---watch --verbose --coverage", "gen-version": "node scripts/gen-version", - "gen-component-type": "esno scripts/gen-component-type", + "gen-component-declaration": "esno scripts/gen-component-declaration", "release-changelog": "node scripts/release-changelog", "build:site:ts": "./scripts/pre-build-site/pre-build-site.sh && cross-env TUSIMPLE=true NODE_ENV=production NODE_OPTIONS=--max-old-space-size=4096 vite build && ./scripts/post-build-site/post-build-site.sh", "prepare": "husky install", - "translate": "node scripts/md-to-vue element" + "translate": "node scripts/md-to-vue element", + "preinstall": "pnpm run gen-component-declaration" }, "author": "07akioni", "license": "MIT", @@ -103,6 +104,7 @@ "esno": "^0.13.0", "express": "^4.17.1", "fs-extra": "^10.0.0", + "fast-glob": "^3.2.7", "husky": "^7.0.0", "inquirer": "^8.1.0", "jest": "^27.0.4", diff --git a/scripts/gen-component-declaration.js b/scripts/gen-component-declaration.js new file mode 100644 index 000000000..9cfbb57b4 --- /dev/null +++ b/scripts/gen-component-declaration.js @@ -0,0 +1,91 @@ +const { resolve, join } = require('path') +const fs = require('fs-extra') +const fg = require('fast-glob') + +const COMPONENT_ROOT = resolve(__dirname, '../src') + +const excludeDir = ['global-style', 'themes', 'composables', 'locales'] + +function exist (path) { + return fs.existsSync(path) +} + +async function loadComponent (dir) { + return { + path: dir, + name: `n-${dir}`, + components: exist(join(COMPONENT_ROOT, dir, 'index.ts')) ? await require(join(COMPONENT_ROOT, dir, 'index.ts')) : {} + } +} +function parseComponentsDeclaration (code) { + if (!code) { + return {} + } + return Object.fromEntries( + Array.from(code.matchAll(/(? [i[1], i[2]] + ) + ) +} + +async function generateComponentsType () { + const folders = (await fg('[^_]*', { + onlyDirectories: true, + cwd: COMPONENT_ROOT + })).filter(fold => !excludeDir.includes(fold)) + const files = await Promise.all( + folders.map(async dir => await loadComponent(dir)) + ) + + const components = {} + + files.forEach((file) => { + const fileComponents = file.components + Object.keys(fileComponents).forEach((key) => { + const entry = `typeof import('./${file.path}')['${key}']` + if (key.startsWith('N')) { + components[key] = entry + } + }) + }) + const originalContent = exist( + resolve(COMPONENT_ROOT, 'components-declaration.d.ts') + ) + ? await fs.readFile( + resolve(COMPONENT_ROOT, 'components-declaration.d.ts'), + 'utf-8' + ) + : '' + + const originImports = parseComponentsDeclaration(originalContent) + const lines = Object.entries({ + ...originImports, + ...components + }) + .filter(([name]) => { + return components[name] + }) + .map(([name, v]) => { + if (!/^\w+$/.test(name)) { + name = `'${name}'` + } + return `${name}: ${v}` + }) + const code = `// this is global component declaration +declare module 'vue' { + export interface GlobalComponents { + ${lines.join('\n ')} + [x: string]: any + } +} +export { } +` + if (code !== originalContent) { + await fs.writeFile( + resolve(COMPONENT_ROOT, 'components-declaration.d.ts'), + code, + 'utf-8' + ) + } +} +generateComponentsType() diff --git a/scripts/gen-component-type.js b/scripts/gen-component-type.js deleted file mode 100644 index 230361100..000000000 --- a/scripts/gen-component-type.js +++ /dev/null @@ -1,65 +0,0 @@ -import { resolve } from 'path' -import { promises as fs, existsSync } from 'fs' -import * as components from '../src/components' - -export function parseDeclaration (code) { - if (!code) { - return {} - } - return Object.fromEntries( - Array.from(code.matchAll(/(? [i[1], i[2]] - ) - ) -} - -async function generateComponentsType () { - const componentsKeys = {} - Object.keys(components).forEach((key) => { - const entry = `typeof import('./${key.toLowerCase().slice(1)}')['${key}']` - if (key.startsWith('N')) { - componentsKeys[key] = entry - } - }) - const originalContent = existsSync( - resolve(__dirname, '..', 'src', 'components-type.d.ts') - ) - ? await fs.readFile( - resolve(__dirname, '..', 'src', 'components-type.d.ts'), - 'utf-8' - ) - : '' - - const originImports = parseDeclaration(originalContent) - console.log(originImports) - const lines = Object.entries({ - ...originImports, - ...componentsKeys - }) - .sort((a, b) => a[0].localeCompare(b[0])) - .filter(([name]) => { - return componentsKeys[name] - }) - .map(([name, v]) => { - if (!/^\w+$/.test(name)) { - name = `'${name}'` - } - return `${name}: ${v}` - }) - const code = `// this is global component declaration - declare module 'vue' { - export interface GlobalComponents { - ${lines.join('\n ')} - } - } - export { } - ` - if (code !== originalContent) { - await fs.writeFile( - resolve(__dirname, '..', 'src', 'components-type.d.ts'), - code, - 'utf-8' - ) - } -} -generateComponentsType() diff --git a/src/components-declaration.d.ts b/src/components-declaration.d.ts new file mode 100644 index 000000000..7460c9d67 --- /dev/null +++ b/src/components-declaration.d.ts @@ -0,0 +1,143 @@ +// this is global component declaration +declare module 'vue' { + export interface GlobalComponents { + NAffix: typeof import('./affix')['NAffix'] + NAlert: typeof import('./alert')['NAlert'] + NAnchor: typeof import('./anchor')['NAnchor'] + NAnchorLink: typeof import('./anchor')['NAnchorLink'] + NAutoComplete: typeof import('./auto-complete')['NAutoComplete'] + NAvatar: typeof import('./avatar')['NAvatar'] + NAvatarGroup: typeof import('./avatar')['NAvatarGroup'] + NBackTop: typeof import('./back-top')['NBackTop'] + NBadge: typeof import('./badge')['NBadge'] + NBreadcrumb: typeof import('./breadcrumb')['NBreadcrumb'] + NBreadcrumbItem: typeof import('./breadcrumb')['NBreadcrumbItem'] + NButton: typeof import('./button')['NButton'] + NButtonGroup: typeof import('./button')['NButtonGroup'] + NxButton: typeof import('./button')['NxButton'] + NCalendar: typeof import('./calendar')['NCalendar'] + NCard: typeof import('./card')['NCard'] + NCarousel: typeof import('./carousel')['NCarousel'] + NCascader: typeof import('./cascader')['NCascader'] + NCheckbox: typeof import('./checkbox')['NCheckbox'] + NCheckboxGroup: typeof import('./checkbox')['NCheckboxGroup'] + NCode: typeof import('./code')['NCode'] + NCollapse: typeof import('./collapse')['NCollapse'] + NCollapseItem: typeof import('./collapse')['NCollapseItem'] + NCollapseTransition: typeof import('./collapse-transition')['NCollapseTransition'] + NColorPicker: typeof import('./color-picker')['NColorPicker'] + NConfigProvider: typeof import('./config-provider')['NConfigProvider'] + NCountdown: typeof import('./countdown')['NCountdown'] + NDataTable: typeof import('./data-table')['NDataTable'] + NDatePicker: typeof import('./date-picker')['NDatePicker'] + NDescriptions: typeof import('./descriptions')['NDescriptions'] + NDescriptionsItem: typeof import('./descriptions')['NDescriptionsItem'] + NDialog: typeof import('./dialog')['NDialog'] + NDialogProvider: typeof import('./dialog')['NDialogProvider'] + NDivider: typeof import('./divider')['NDivider'] + NDrawer: typeof import('./drawer')['NDrawer'] + NDrawerContent: typeof import('./drawer')['NDrawerContent'] + NDropdown: typeof import('./dropdown')['NDropdown'] + NDynamicInput: typeof import('./dynamic-input')['NDynamicInput'] + NDynamicTags: typeof import('./dynamic-tags')['NDynamicTags'] + NEl: typeof import('./element')['NEl'] + NElement: typeof import('./element')['NElement'] + NEllipsis: typeof import('./ellipsis')['NEllipsis'] + NEmpty: typeof import('./empty')['NEmpty'] + NForm: typeof import('./form')['NForm'] + NFormItem: typeof import('./form')['NFormItem'] + NFormItemCol: typeof import('./form')['NFormItemCol'] + NFormItemGi: typeof import('./form')['NFormItemGi'] + NFormItemGridItem: typeof import('./form')['NFormItemGridItem'] + NFormItemRow: typeof import('./form')['NFormItemRow'] + NGradientText: typeof import('./gradient-text')['NGradientText'] + NGi: typeof import('./grid')['NGi'] + NGrid: typeof import('./grid')['NGrid'] + NGridItem: typeof import('./grid')['NGridItem'] + NIcon: typeof import('./icon')['NIcon'] + NImage: typeof import('./image')['NImage'] + NImageGroup: typeof import('./image')['NImageGroup'] + NInput: typeof import('./input')['NInput'] + NInputGroup: typeof import('./input')['NInputGroup'] + NInputGroupLabel: typeof import('./input')['NInputGroupLabel'] + NInputNumber: typeof import('./input-number')['NInputNumber'] + NLayout: typeof import('./layout')['NLayout'] + NLayoutContent: typeof import('./layout')['NLayoutContent'] + NLayoutFooter: typeof import('./layout')['NLayoutFooter'] + NLayoutHeader: typeof import('./layout')['NLayoutHeader'] + NLayoutSider: typeof import('./layout')['NLayoutSider'] + NCol: typeof import('./legacy-grid')['NCol'] + NRow: typeof import('./legacy-grid')['NRow'] + NList: typeof import('./list')['NList'] + NListItem: typeof import('./list')['NListItem'] + NLoadingBarProvider: typeof import('./loading-bar')['NLoadingBarProvider'] + NLog: typeof import('./log')['NLog'] + NMention: typeof import('./mention')['NMention'] + NMenu: typeof import('./menu')['NMenu'] + NMessageProvider: typeof import('./message')['NMessageProvider'] + NModal: typeof import('./modal')['NModal'] + NNotificationProvider: typeof import('./notification')['NNotificationProvider'] + NNumberAnimation: typeof import('./number-animation')['NNumberAnimation'] + NPageHeader: typeof import('./page-header')['NPageHeader'] + NPagination: typeof import('./pagination')['NPagination'] + NPopconfirm: typeof import('./popconfirm')['NPopconfirm'] + NPopover: typeof import('./popover')['NPopover'] + NPopselect: typeof import('./popselect')['NPopselect'] + NProgress: typeof import('./progress')['NProgress'] + NRadio: typeof import('./radio')['NRadio'] + NRadioButton: typeof import('./radio')['NRadioButton'] + NRadioGroup: typeof import('./radio')['NRadioGroup'] + NRate: typeof import('./rate')['NRate'] + NResult: typeof import('./result')['NResult'] + NScrollbar: typeof import('./scrollbar')['NScrollbar'] + NSelect: typeof import('./select')['NSelect'] + NSkeleton: typeof import('./skeleton')['NSkeleton'] + NSlider: typeof import('./slider')['NSlider'] + NSpace: typeof import('./space')['NSpace'] + NSpin: typeof import('./spin')['NSpin'] + NStatistic: typeof import('./statistic')['NStatistic'] + NStep: typeof import('./steps')['NStep'] + NSteps: typeof import('./steps')['NSteps'] + NSwitch: typeof import('./switch')['NSwitch'] + NTable: typeof import('./table')['NTable'] + NTbody: typeof import('./table')['NTbody'] + NTd: typeof import('./table')['NTd'] + NTh: typeof import('./table')['NTh'] + NThead: typeof import('./table')['NThead'] + NTr: typeof import('./table')['NTr'] + NTab: typeof import('./tabs')['NTab'] + NTabPane: typeof import('./tabs')['NTabPane'] + NTabs: typeof import('./tabs')['NTabs'] + NTag: typeof import('./tag')['NTag'] + NThemeEditor: typeof import('./theme-editor')['NThemeEditor'] + NThing: typeof import('./thing')['NThing'] + NTime: typeof import('./time')['NTime'] + NTimePicker: typeof import('./time-picker')['NTimePicker'] + NTimeline: typeof import('./timeline')['NTimeline'] + NTimelineItem: typeof import('./timeline')['NTimelineItem'] + NTooltip: typeof import('./tooltip')['NTooltip'] + NTransfer: typeof import('./transfer')['NTransfer'] + NTree: typeof import('./tree')['NTree'] + NTreeSelect: typeof import('./tree-select')['NTreeSelect'] + NA: typeof import('./typography')['NA'] + NBlockquote: typeof import('./typography')['NBlockquote'] + NH1: typeof import('./typography')['NH1'] + NH2: typeof import('./typography')['NH2'] + NH3: typeof import('./typography')['NH3'] + NH4: typeof import('./typography')['NH4'] + NH5: typeof import('./typography')['NH5'] + NH6: typeof import('./typography')['NH6'] + NHr: typeof import('./typography')['NHr'] + NLi: typeof import('./typography')['NLi'] + NOl: typeof import('./typography')['NOl'] + NP: typeof import('./typography')['NP'] + NText: typeof import('./typography')['NText'] + NUl: typeof import('./typography')['NUl'] + NUpload: typeof import('./upload')['NUpload'] + NUploadDragger: typeof import('./upload')['NUploadDragger'] + NUploadFileList: typeof import('./upload')['NUploadFileList'] + NUploadTrigger: typeof import('./upload')['NUploadTrigger'] + [x: string]: any + } +} +export { } diff --git a/src/components-type.d.ts b/src/components-type.d.ts deleted file mode 100644 index 627bc0123..000000000 --- a/src/components-type.d.ts +++ /dev/null @@ -1,142 +0,0 @@ -// this is global component declaration -declare module 'vue' { - export interface GlobalComponents { - NA: typeof import('./a')['NA'] - NAffix: typeof import('./affix')['NAffix'] - NAlert: typeof import('./alert')['NAlert'] - NAnchor: typeof import('./anchor')['NAnchor'] - NAnchorLink: typeof import('./anchorlink')['NAnchorLink'] - NAutoComplete: typeof import('./autocomplete')['NAutoComplete'] - NAvatar: typeof import('./avatar')['NAvatar'] - NAvatarGroup: typeof import('./avatargroup')['NAvatarGroup'] - NBackTop: typeof import('./backtop')['NBackTop'] - NBadge: typeof import('./badge')['NBadge'] - NBlockquote: typeof import('./blockquote')['NBlockquote'] - NBreadcrumb: typeof import('./breadcrumb')['NBreadcrumb'] - NBreadcrumbItem: typeof import('./breadcrumbitem')['NBreadcrumbItem'] - NButton: typeof import('./button')['NButton'] - NButtonGroup: typeof import('./buttongroup')['NButtonGroup'] - NCalendar: typeof import('./calendar')['NCalendar'] - NCard: typeof import('./card')['NCard'] - NCarousel: typeof import('./carousel')['NCarousel'] - NCascader: typeof import('./cascader')['NCascader'] - NCheckbox: typeof import('./checkbox')['NCheckbox'] - NCheckboxGroup: typeof import('./checkboxgroup')['NCheckboxGroup'] - NCode: typeof import('./code')['NCode'] - NCol: typeof import('./col')['NCol'] - NCollapse: typeof import('./collapse')['NCollapse'] - NCollapseItem: typeof import('./collapseitem')['NCollapseItem'] - NCollapseTransition: typeof import('./collapsetransition')['NCollapseTransition'] - NColorPicker: typeof import('./colorpicker')['NColorPicker'] - NConfigProvider: typeof import('./configprovider')['NConfigProvider'] - NCountdown: typeof import('./countdown')['NCountdown'] - NDataTable: typeof import('./datatable')['NDataTable'] - NDatePicker: typeof import('./datepicker')['NDatePicker'] - NDescriptions: typeof import('./descriptions')['NDescriptions'] - NDescriptionsItem: typeof import('./descriptionsitem')['NDescriptionsItem'] - NDialog: typeof import('./dialog')['NDialog'] - NDialogProvider: typeof import('./dialogprovider')['NDialogProvider'] - NDivider: typeof import('./divider')['NDivider'] - NDrawer: typeof import('./drawer')['NDrawer'] - NDrawerContent: typeof import('./drawercontent')['NDrawerContent'] - NDropdown: typeof import('./dropdown')['NDropdown'] - NDynamicInput: typeof import('./dynamicinput')['NDynamicInput'] - NDynamicTags: typeof import('./dynamictags')['NDynamicTags'] - NEl: typeof import('./el')['NEl'] - NElement: typeof import('./element')['NElement'] - NEllipsis: typeof import('./ellipsis')['NEllipsis'] - NEmpty: typeof import('./empty')['NEmpty'] - NForm: typeof import('./form')['NForm'] - NFormItem: typeof import('./formitem')['NFormItem'] - NFormItemCol: typeof import('./formitemcol')['NFormItemCol'] - NFormItemGi: typeof import('./formitemgi')['NFormItemGi'] - NFormItemGridItem: typeof import('./formitemgriditem')['NFormItemGridItem'] - NFormItemRow: typeof import('./formitemrow')['NFormItemRow'] - NGi: typeof import('./gi')['NGi'] - NGlobalStyle: typeof import('./globalstyle')['NGlobalStyle'] - NGradientText: typeof import('./gradienttext')['NGradientText'] - NGrid: typeof import('./grid')['NGrid'] - NGridItem: typeof import('./griditem')['NGridItem'] - NH1: typeof import('./h1')['NH1'] - NH2: typeof import('./h2')['NH2'] - NH3: typeof import('./h3')['NH3'] - NH4: typeof import('./h4')['NH4'] - NH5: typeof import('./h5')['NH5'] - NH6: typeof import('./h6')['NH6'] - NHr: typeof import('./hr')['NHr'] - NIcon: typeof import('./icon')['NIcon'] - NImage: typeof import('./image')['NImage'] - NImageGroup: typeof import('./imagegroup')['NImageGroup'] - NInput: typeof import('./input')['NInput'] - NInputGroup: typeof import('./inputgroup')['NInputGroup'] - NInputGroupLabel: typeof import('./inputgrouplabel')['NInputGroupLabel'] - NInputNumber: typeof import('./inputnumber')['NInputNumber'] - NLayout: typeof import('./layout')['NLayout'] - NLayoutContent: typeof import('./layoutcontent')['NLayoutContent'] - NLayoutFooter: typeof import('./layoutfooter')['NLayoutFooter'] - NLayoutHeader: typeof import('./layoutheader')['NLayoutHeader'] - NLayoutSider: typeof import('./layoutsider')['NLayoutSider'] - NLi: typeof import('./li')['NLi'] - NList: typeof import('./list')['NList'] - NListItem: typeof import('./listitem')['NListItem'] - NLoadingBarProvider: typeof import('./loadingbarprovider')['NLoadingBarProvider'] - NLog: typeof import('./log')['NLog'] - NMention: typeof import('./mention')['NMention'] - NMenu: typeof import('./menu')['NMenu'] - NMessageProvider: typeof import('./messageprovider')['NMessageProvider'] - NModal: typeof import('./modal')['NModal'] - NNotificationProvider: typeof import('./notificationprovider')['NNotificationProvider'] - NNumberAnimation: typeof import('./numberanimation')['NNumberAnimation'] - NOl: typeof import('./ol')['NOl'] - NP: typeof import('./p')['NP'] - NPageHeader: typeof import('./pageheader')['NPageHeader'] - NPagination: typeof import('./pagination')['NPagination'] - NPopconfirm: typeof import('./popconfirm')['NPopconfirm'] - NPopover: typeof import('./popover')['NPopover'] - NPopselect: typeof import('./popselect')['NPopselect'] - NProgress: typeof import('./progress')['NProgress'] - NRadio: typeof import('./radio')['NRadio'] - NRadioButton: typeof import('./radiobutton')['NRadioButton'] - NRadioGroup: typeof import('./radiogroup')['NRadioGroup'] - NRate: typeof import('./rate')['NRate'] - NResult: typeof import('./result')['NResult'] - NRow: typeof import('./row')['NRow'] - NScrollbar: typeof import('./scrollbar')['NScrollbar'] - NSelect: typeof import('./select')['NSelect'] - NSkeleton: typeof import('./skeleton')['NSkeleton'] - NSlider: typeof import('./slider')['NSlider'] - NSpace: typeof import('./space')['NSpace'] - NSpin: typeof import('./spin')['NSpin'] - NStatistic: typeof import('./statistic')['NStatistic'] - NStep: typeof import('./step')['NStep'] - NSteps: typeof import('./steps')['NSteps'] - NSwitch: typeof import('./switch')['NSwitch'] - NTab: typeof import('./tab')['NTab'] - NTable: typeof import('./table')['NTable'] - NTabPane: typeof import('./tabpane')['NTabPane'] - NTabs: typeof import('./tabs')['NTabs'] - NTag: typeof import('./tag')['NTag'] - NTbody: typeof import('./tbody')['NTbody'] - NTd: typeof import('./td')['NTd'] - NText: typeof import('./text')['NText'] - NTh: typeof import('./th')['NTh'] - NThead: typeof import('./thead')['NThead'] - NThing: typeof import('./thing')['NThing'] - NTime: typeof import('./time')['NTime'] - NTimeline: typeof import('./timeline')['NTimeline'] - NTimelineItem: typeof import('./timelineitem')['NTimelineItem'] - NTimePicker: typeof import('./timepicker')['NTimePicker'] - NTooltip: typeof import('./tooltip')['NTooltip'] - NTr: typeof import('./tr')['NTr'] - NTransfer: typeof import('./transfer')['NTransfer'] - NTree: typeof import('./tree')['NTree'] - NTreeSelect: typeof import('./treeselect')['NTreeSelect'] - NUl: typeof import('./ul')['NUl'] - NUpload: typeof import('./upload')['NUpload'] - NUploadDragger: typeof import('./uploaddragger')['NUploadDragger'] - NUploadFileList: typeof import('./uploadfilelist')['NUploadFileList'] - NUploadTrigger: typeof import('./uploadtrigger')['NUploadTrigger'] - NxButton: typeof import('./xbutton')['NxButton'] - } -} -export {} diff --git a/src/message/demos/enUS/customize-message.demo.vue b/src/message/demos/enUS/customize-message.demo.vue index 5e6ff1b51..58b9a2d22 100644 --- a/src/message/demos/enUS/customize-message.demo.vue +++ b/src/message/demos/enUS/customize-message.demo.vue @@ -18,7 +18,7 @@ import { defineComponent, h } from 'vue' import { NAlert, NButton, useMessage } from 'naive-ui' import type { MessageProviderRenderMessage } from 'naive-ui' -const MessageTrigger = { +const MessageTrigger = defineComponent({ setup () { const { error } = useMessage() return () => @@ -36,7 +36,7 @@ const MessageTrigger = { } ) } -} +}) export default defineComponent({ components: { MessageTrigger }, diff --git a/src/message/demos/zhCN/customize-message.demo.vue b/src/message/demos/zhCN/customize-message.demo.vue index b9fa619ad..8e0619f34 100644 --- a/src/message/demos/zhCN/customize-message.demo.vue +++ b/src/message/demos/zhCN/customize-message.demo.vue @@ -18,7 +18,7 @@ import { defineComponent, h } from 'vue' import { NAlert, NButton, useMessage } from 'naive-ui' import type { MessageProviderRenderMessage } from 'naive-ui' -const MessageTrigger = { +const MessageTrigger = defineComponent({ setup () { const { error } = useMessage() return () => @@ -34,7 +34,7 @@ const MessageTrigger = { } ) } -} +}) export default defineComponent({ components: { MessageTrigger },