feat(runtime): add all、pc、mobile、mobile-first、simple runtime (#1662)

This commit is contained in:
ajaxzheng 2024-06-04 02:24:58 -07:00 committed by GitHub
parent 494bb14efb
commit 336ef0a456
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 191 additions and 39 deletions

6
.gitignore vendored
View File

@ -18,6 +18,12 @@ test-results
/packages/vue-icon-saas/src
/packages/vue-icon-saas/index.ts
/packages/vue-runtime/pc.ts
/packages/vue-runtime/mobile.ts
/packages/vue-runtime/mobile-first.ts
/packages/vue-runtime/all.ts
/packages/vue-runtime/simple.ts
/packages/react/index.ts
/packages/react/pc.ts
/packages/react/mobile.ts

View File

@ -58,6 +58,7 @@
"esno": "^0.16.3",
"fast-glob": "^3.2.12",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-visualizer": "^5.12.0",
"vite-plugin-dts": "~3.0.0",
"vite-plugin-svgr": "^3.2.0",
"vite-svg-loader": "^3.6.0"

View File

@ -14,7 +14,7 @@ import { getComponents, excludeComponents } from '../../shared/module-utils'
import handlebarsRender from './handlebars.render'
const version = getopentinyVersion({ key: 'version' })
const outputDir = 'packages/vue'
const outputDir = 'packages/vue-runtime'
const MAIN_TEMPLATE = `{{{include}}}
import { $prefix } from '@opentiny/vue-common'
const components = [{{{components}}}]
@ -47,26 +47,98 @@ export const install = (app, opts = {}) => {
}
`
const buildFullRuntime = () => {
const outputPath = pathFromWorkspaceRoot(outputDir, 'app.ts')
const components = getComponents('all')
/**
* all
* simple runtimepc组件
* pc pc组件组件
* mobile mobile组件
* mobile-first
*/
type RunTimeModeType = 'all' | 'pc' | 'mobile' | 'mobile-first' | 'simple'
const runtimeModeList: Array<RunTimeModeType> = ['all', 'pc', 'mobile', 'mobile-first', 'simple']
// 简易模式下需要排除的组件列表包括chart、业务组件、冷门组件等
const notSimpleComponents = [
'Amount',
'Area',
'AsyncFlowchart',
'AutonaviMap',
'BaiduMap',
'BaseSelect',
'BulletinBoard',
'CascaderMobile',
'Chart',
'ChartBar',
'ChartBoxplot',
'ChartCandle',
'ChartCore',
'ChartFunnel',
'ChartGauge',
'ChartGraph',
'ChartHeatmap',
'ChartHistogram',
'ChartLine',
'ChartLiquidfill',
'ChartMap',
'ChartPie',
'ChartProcess',
'ChartRadar',
'ChartRing',
'ChartSankey',
'ChartScatter',
'ChartSunburst',
'ChartTree',
'ChartWaterfall',
'ChartWordcloud',
'Company',
'Country',
'Crop',
'Currency',
'DatePickerMobile',
'DatePickerMobileFirst',
'Dept',
'DropRoles',
'Espace',
'Flowchart',
'GridManager',
'Guide',
'Hrapprover',
'LinkMenu',
'Locales',
'LogonUser',
'Logout',
'MindMap',
'QrCode',
'QueryBuilder',
'RichText',
'RichTextEditor',
'River',
'SvgIcon',
'TextPopup',
'ToggleMenu',
'User',
'UserAccount',
'UserContact',
'UserLink'
]
const buildFullRuntime = (mode: RunTimeModeType) => {
const outputPath = pathFromWorkspaceRoot(outputDir, `${mode}.ts`)
const components = getComponents(mode === 'simple' ? 'pc' : mode)
const includeTemplate: string[] = []
const componentsTemplate: string[] = []
// 导出公共模块
components.push({
name: 'Renderless',
importName: '@opentiny/vue-renderless/common/runtime',
path: 'packages/renderless'
})
components.forEach((item) => {
if (item.inEntry !== false && !item.path.includes('river') && !excludeComponents.includes(item.name)) {
if (item.inEntry !== false) {
const component = capitalizeKebabCase(item.name)
if (
(mode !== 'simple' && !excludeComponents.includes(item.name)) ||
(mode === 'simple' && !notSimpleComponents.includes(item.name))
) {
componentsTemplate.push(` ${component}`)
includeTemplate.push(`import ${item.name} from '${item.importName}'`)
}
}
})
const template = handlebarsRender({
@ -81,7 +153,9 @@ const buildFullRuntime = () => {
fs.writeFileSync(outputPath, output)
logGreen(`npm run build:entry done. [${outputDir}/app.ts]`)
logGreen(`npm run build:entry done. [${outputDir}/${mode}.ts]`)
}
buildFullRuntime()
runtimeModeList.forEach((item: RunTimeModeType) => {
buildFullRuntime(item)
})

View File

@ -1,17 +1,17 @@
import path from 'node:path'
import type { UserConfig } from 'vite'
import { build } from 'vite'
import minimist from 'minimist'
import commonjs from '@rollup/plugin-commonjs'
import babel from '@rollup/plugin-babel'
import { logGreen } from '../../shared/utils'
import type { BuildUiOption, BaseConfig } from './build-ui'
import { pathFromPackages, getBaseConfig, requireModules } from './build-ui'
import { createProcessor } from 'tailwindcss/src/cli/build/plugin'
import { visualizer } from 'rollup-plugin-visualizer'
async function batchBuildAll({ vueVersion, tasks, message, emptyOutDir, npmScope, min }) {
async function batchBuildAll({ vueVersion, tasks, message, emptyOutDir, npmScope, min, isVisualizer }) {
const rootDir = pathFromPackages('')
const runtimeDir = `dist${vueVersion}/@opentiny/vue/runtime`
const runtimeDir = `vue-runtime/dist${vueVersion}`
const outDir = path.resolve(rootDir, runtimeDir)
await batchBuild({
@ -20,7 +20,8 @@ async function batchBuildAll({ vueVersion, tasks, message, emptyOutDir, npmScope
message,
emptyOutDir,
npmScope,
min
min,
isVisualizer
})
function toEntry(libs) {
@ -36,11 +37,12 @@ async function batchBuildAll({ vueVersion, tasks, message, emptyOutDir, npmScope
'@vue/composition-api': 'VueCompositionAPI',
'@opentiny/vue-locale': 'TinyVueLocale',
'@opentiny/vue-common': 'TinyVueCommon',
'@opentiny/vue-icon': 'TinyVueIcon'
'@opentiny/vue-icon': 'TinyVueIcon',
'echarts': 'Echarts'
}
}
async function batchBuild({ vueVersion, tasks, message, emptyOutDir, npmScope, min }) {
async function batchBuild({ vueVersion, tasks, message, emptyOutDir, npmScope, min, isVisualizer }) {
if (tasks.length === 0) return
logGreen(`====== 开始构建 ${message} ======`)
@ -72,7 +74,27 @@ async function batchBuildAll({ vueVersion, tasks, message, emptyOutDir, npmScope
babel({
extensions: ['.js', '.jsx', '.mjs', '.ts', '.tsx'],
presets: ['@babel/preset-env']
}),
isVisualizer
? visualizer({
filename: `${tasks[0].libPath}.html`,
open: true
})
: null,
{
name: 'vite-plugin-transfer-mode',
enforce: 'pre',
transform(code, id) {
if (tasks[0].path.includes('simple') && id.includes('src/index.ts') && code.includes('pc.vue')) {
// 简易模式,手动排除移动端和多端模版
const newCode = code.replace('mobile.vue', 'pc.vue').replace('mobile-first.vue', 'pc.vue')
return {
code: newCode,
map: null
}
}
}
}
] as any[])
)
@ -81,7 +103,7 @@ async function batchBuildAll({ vueVersion, tasks, message, emptyOutDir, npmScope
...baseConfig,
build: {
emptyOutDir,
minify: min,
minify: true,
sourcemap: min,
rollupOptions: {
external: (source, importer, isResolved) => {
@ -130,8 +152,24 @@ function getEntryTasks() {
libPath: 'tiny-vue-common'
},
{
path: 'vue/app.ts',
libPath: 'tiny-vue'
path: 'vue-runtime/all.ts',
libPath: 'tiny-vue-all'
},
{
path: 'vue-runtime/simple.ts',
libPath: 'tiny-vue-simple'
},
{
path: 'vue-runtime/pc.ts',
libPath: 'tiny-vue-pc'
},
{
path: 'vue-runtime/mobile.ts',
libPath: 'tiny-vue-mobile'
},
{
path: 'vue-runtime/mobile-first.ts',
libPath: 'tiny-vue-mobile-first'
},
{
path: 'vue-icon-saas/index.ts',
@ -149,7 +187,8 @@ export async function buildRuntime({
vueVersions = ['2', '3'],
clean = false,
scope = 'opentiny',
min = false
min = false,
isVisualizer = false
}: BuildUiOption) {
// 是否清空构建目录
let emptyOutDir = clean
@ -163,10 +202,10 @@ export async function buildRuntime({
// 这里注意不能使用多入口打包rollup多入口打包会抽取公共依赖再由inlineChunksPlugin插件处理导致组件库运行时加载失败
for (let i = 0; i < tasks.length; i++) {
await batchBuildAll({ vueVersion, tasks: [tasks[i]], message, emptyOutDir, npmScope: scope, min })
await batchBuildAll({ vueVersion, tasks: [tasks[i]], message, emptyOutDir, npmScope: scope, min, isVisualizer })
}
const rootDir = pathFromPackages('')
const runtimeDir = `dist${vueVersion}/@opentiny/vue/runtime`
const runtimeDir = `vue-runtime/dist${vueVersion}`
const outDir = path.resolve(rootDir, runtimeDir)
const processor = await createProcessor(
{

View File

@ -373,6 +373,7 @@ export interface BuildUiOption {
scope?: string // npm的组织名称
min?: boolean // 是否压缩产物
design?: string // 构建目标的设计规范
isVisualizer?: boolean // 是否开启打包产物分析
}
function getEntryTasks(): Module[] {

View File

@ -34,6 +34,7 @@ program
.description('打包组件 runtime 包')
.addOption(new Option('-v --vue-versions <vueVersions...>', '目标框架,默认所有').choices(['2', '2.7', '3']))
.option('-m, --min', '是否压缩输出文件', false)
.option('-vi, --isVisualizer', '是否分析打包产物', false)
.option('--tiny_mode', '输出的模板类型', 'pc')
.action(buildRuntime)

View File

@ -55,6 +55,7 @@
"// ---------- 创建组件和模板打包入口 ----------": "",
"create:mapping": "pnpm -C internals/cli create:mapping",
"sync-icons": "pnpm -C internals/cli sync-icons",
"build:entry-app": "pnpm -C internals/cli build:entry-app",
"// ---------- 打包运行时组件库 ----------": "",
"build:runtime": "pnpm -C internals/cli build:runtime",
"// ---------- 构建相关脚本 ----------": "",

View File

@ -170,6 +170,25 @@
"type": "component",
"exclude": false
},
"BaseSelect": {
"path": "vue/src/base-select/index.ts",
"type": "component",
"exclude": false,
"mode": [
"mobile-first",
"pc"
]
},
"BaseSelectMobileFirst": {
"path": "vue/src/base-select/src/mobile-first.vue",
"type": "template",
"exclude": false
},
"BaseSelectPc": {
"path": "vue/src/base-select/src/pc.vue",
"type": "template",
"exclude": false
},
"Breadcrumb": {
"path": "vue/src/breadcrumb/index.ts",
"type": "component",
@ -2329,14 +2348,6 @@
"pc"
]
},
"BaseSelect": {
"path": "vue/src/base-select/index.ts",
"type": "component",
"exclude": false,
"mode": [
"pc"
]
},
"SelectDropdown": {
"path": "vue/src/select-dropdown/index.ts",
"type": "component",

View File

@ -0,0 +1,18 @@
{
"name": "@opentiny/vue-runtime",
"version": "3.16.0",
"description": "",
"files": [
"dist2",
"dist3"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"publishConfig": {
"access": "public"
},
"keywords": [],
"author": "",
"license": "ISC"
}