style(internal-cli): fix types and lint code (#257)

* fix(cli): fix types and lint code

* style(internal-cli): fix types and lint code
This commit is contained in:
zuixinwang 2023-06-08 10:15:44 +08:00 committed by GitHub
parent 302cf2573f
commit 6b1d103d69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 184 additions and 142 deletions

View File

@ -2,12 +2,18 @@
* *
*/ */
import fs from 'fs-extra' import fs from 'fs-extra'
import { EOL as endOfLine } from 'os' import { EOL as endOfLine } from 'node:os'
import * as utils from '../../shared/utils.js' import {
import * as moduleUtils from '../../shared/module-utils.js' getopentinyVersion,
import handlebarsRender from './handlebars.render.js' pathFromWorkspaceRoot,
capitalizeKebabCase,
prettierFormat,
logGreen,
} from '../../shared/utils'
import { getComponents } from '../../shared/module-utils'
import handlebarsRender from './handlebars.render'
const version = utils.getopentinyVersion({}) const version = getopentinyVersion({ key: 'version' })
const outputDir = 'packages/vue' const outputDir = 'packages/vue'
const MAIN_TEMPLATE = `{{{include}}} const MAIN_TEMPLATE = `{{{include}}}
@ -22,8 +28,8 @@ const MAIN_TEMPLATE = `{{{include}}}
` `
const buildFullRuntime = () => { const buildFullRuntime = () => {
const outputPath = utils.pathFromWorkspaceRoot(outputDir, 'app.ts') const outputPath = pathFromWorkspaceRoot(outputDir, 'app.ts')
const components = moduleUtils.getComponents('pc') const components = getComponents('pc')
const includeTemplate: string[] = [] const includeTemplate: string[] = []
const componentsTemplate: string[] = [] const componentsTemplate: string[] = []
@ -39,7 +45,7 @@ const buildFullRuntime = () => {
components.forEach((item) => { components.forEach((item) => {
// 暂时排除 chart 类组件 // 暂时排除 chart 类组件
if (item.inEntry !== false && !item.path.includes('chart') && !item.path.includes('river')) { if (item.inEntry !== false && !item.path.includes('chart') && !item.path.includes('river')) {
const component = utils.capitalizeKebabCase(item.name) const component = capitalizeKebabCase(item.name)
componentsTemplate.push(` ${component}`) componentsTemplate.push(` ${component}`)
includeTemplate.push(`import ${item.name} from '${item.importName}'`) includeTemplate.push(`import ${item.name} from '${item.importName}'`)
@ -54,11 +60,11 @@ const buildFullRuntime = () => {
} }
}) })
const output = utils.prettierFormat({ str: template }) const output = prettierFormat({ str: template })
fs.writeFileSync(outputPath, output) fs.writeFileSync(outputPath, output)
utils.logGreen(`npm run build:entry done. [${outputDir}/app.ts]`) logGreen(`npm run build:entry done. [${outputDir}/app.ts]`)
} }
buildFullRuntime() buildFullRuntime()

View File

@ -2,12 +2,18 @@
* pc.js / mobile.js / mobile-first.js / index.js * pc.js / mobile.js / mobile-first.js / index.js
*/ */
import fs from 'fs-extra' import fs from 'fs-extra'
import { EOL as endOfLine } from 'os' import { EOL as endOfLine } from 'node:os'
import * as utils from '../../shared/utils.js' import {
import * as moduleUtils from '../../shared/module-utils.js' getopentinyVersion,
import handlebarsRender from './handlebars.render.js' pathFromWorkspaceRoot,
capitalizeKebabCase,
prettierFormat,
logGreen,
} from '../../shared/utils'
import { getComponents } from '../../shared/module-utils'
import handlebarsRender from './handlebars.render'
const version = utils.getopentinyVersion({}) const version = getopentinyVersion({ key: 'version' })
const outputDir = 'packages/vue' const outputDir = 'packages/vue'
const fileNames = { const fileNames = {
@ -63,18 +69,18 @@ function getMainTemplate({ mode }) {
} }
const createEntry = (mode) => { const createEntry = (mode) => {
const OUTPUT_PATH = utils.pathFromWorkspaceRoot(outputDir, fileNames[mode]) const OUTPUT_PATH = pathFromWorkspaceRoot(outputDir, fileNames[mode])
const MAIN_TEMPLATE = getMainTemplate({ mode }) const MAIN_TEMPLATE = getMainTemplate({ mode })
const includeTemplate: string[] = [] const includeTemplate: string[] = []
const componentsTemplate: string[] = [] const componentsTemplate: string[] = []
const components = moduleUtils.getComponents(mode) const components = getComponents(mode)
const PKG_PATH = utils.pathFromWorkspaceRoot(outputDir, 'package.json') const PKG_PATH = pathFromWorkspaceRoot(outputDir, 'package.json')
const PKGContent = fs.readJSONSync(PKG_PATH) const PKGContent = fs.readJSONSync(PKG_PATH)
const PKGDeps = {} const PKGDeps = {}
components.forEach((item) => { components.forEach((item) => {
if (item.inEntry !== false) { if (item.inEntry !== false) {
const component = utils.capitalizeKebabCase(item.name) const component = capitalizeKebabCase(item.name)
PKGDeps[item.importName] = 'workspace:~' PKGDeps[item.importName] = 'workspace:~'
componentsTemplate.push(` ${component}`) componentsTemplate.push(` ${component}`)
includeTemplate.push(`import ${item.name} from '${item.importName}'`) includeTemplate.push(`import ${item.name} from '${item.importName}'`)
@ -95,7 +101,7 @@ const createEntry = (mode) => {
} }
}) })
const output = utils.prettierFormat({ str: template }) const output = prettierFormat({ str: template })
fs.writeFileSync(OUTPUT_PATH, output) fs.writeFileSync(OUTPUT_PATH, output)
} }
@ -103,7 +109,7 @@ const createEntry = (mode) => {
export function buildEntry() { export function buildEntry() {
['all', 'pc', 'mobile', 'mobile-first'].forEach(createEntry) ['all', 'pc', 'mobile', 'mobile-first'].forEach(createEntry)
utils.logGreen( logGreen(
`npm run build:entry done. [${outputDir}/index.ts,${outputDir}/pc.ts,${outputDir}/mobile.ts,${outputDir}/mobile-first.ts]` `npm run build:entry done. [${outputDir}/index.ts,${outputDir}/pc.ts,${outputDir}/mobile.ts,${outputDir}/mobile-first.ts]`
) )
} }

View File

@ -1,11 +1,11 @@
import path from 'node:path' import path from 'node:path'
import type { UserConfig } from 'vite' import type { UserConfig } from 'vite'
import { build } from 'vite' import { build } from 'vite'
import babel from '@rollup/plugin-babel'
import * as utils from '../../shared/utils.js'
import type { BuildUiOption } from './build-ui'
import { pathFromPackages, getBaseConfig, requireModules } from './build-ui'
import commonjs from '@rollup/plugin-commonjs' 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'
async function batchBuildAll({ vueVersion, tasks, message, emptyOutDir, npmScope, min }) { async function batchBuildAll({ vueVersion, tasks, message, emptyOutDir, npmScope, min }) {
const rootDir = pathFromPackages('') const rootDir = pathFromPackages('')
@ -40,16 +40,16 @@ async function batchBuildAll({ vueVersion, tasks, message, emptyOutDir, npmScope
async function batchBuild({ vueVersion, tasks, message, emptyOutDir, npmScope, min }) { async function batchBuild({ vueVersion, tasks, message, emptyOutDir, npmScope, min }) {
if (tasks.length === 0) return if (tasks.length === 0) return
utils.logGreen(`====== 开始构建 ${message} ======`) logGreen(`====== 开始构建 ${message} ======`)
const entry = toEntry(tasks) const entry = toEntry(tasks)
const baseConfig = getBaseConfig({ const baseConfig = getBaseConfig({
vueVersion, vueVersion,
dtsInclude: [], dtsInclude: [] as string[],
dts: false, dts: false,
npmScope, npmScope,
isRuntime: true isRuntime: true
}) as UserConfig } as BaseConfig) as UserConfig
baseConfig.define = Object.assign(baseConfig.define || {}, { baseConfig.define = Object.assign(baseConfig.define || {}, {
'process.env.BUILD_TARGET': JSON.stringify(vueVersion !== '3' ? 'runtime' : 'component'), 'process.env.BUILD_TARGET': JSON.stringify(vueVersion !== '3' ? 'runtime' : 'component'),
@ -60,15 +60,17 @@ async function batchBuildAll({ vueVersion, tasks, message, emptyOutDir, npmScope
}) })
baseConfig.plugins?.push( baseConfig.plugins?.push(
commonjs({ ...[
include: /node_modules/, commonjs({
requireReturnsDefault: true, include: /node_modules/,
defaultIsModuleExports: true requireReturnsDefault: true,
}), defaultIsModuleExports: true
babel({ }),
extensions: ['.js', '.jsx', '.mjs', '.ts', '.tsx'], babel({
presets: ['@babel/preset-env'] extensions: ['.js', '.jsx', '.mjs', '.ts', '.tsx'],
}) presets: ['@babel/preset-env']
})
] as any[]
) )
await build({ await build({

View File

@ -5,14 +5,18 @@ import path from 'node:path'
import { build, defineConfig } from 'vite' import { build, defineConfig } from 'vite'
import dtsPlugin from 'vite-plugin-dts' import dtsPlugin from 'vite-plugin-dts'
import vue3SvgPlugin from 'vite-svg-loader' import vue3SvgPlugin from 'vite-svg-loader'
import { getAlias, pathFromWorkspaceRoot } from '../../config/vite.js' import { getAlias, pathFromWorkspaceRoot } from '../../config/vite'
import * as config from '../../shared/config.js' import { external } from '../../shared/config'
import type { Module } from '../../shared/module-utils.js' import type { Module } from '../../shared/module-utils'
import { getAllIcons, getAllModules, getByName } from '../../shared/module-utils.js' import { getAllIcons, getAllModules, getByName } from '../../shared/module-utils'
import * as utils from '../../shared/utils.js' import {
import generatePackageJsonPlugin from './rollup/generate-package-json.js' logGreen,
import inlineChunksPlugin from './rollup/inline-chunks.js' kebabCase,
import replaceModuleNamePlugin from './rollup/replace-module-name.js' capitalizeKebabCase,
} from '../../shared/utils'
import generatePackageJsonPlugin from './rollup/generate-package-json'
import inlineChunksPlugin from './rollup/inline-chunks'
import replaceModuleNamePlugin from './rollup/replace-module-name'
export const pathFromPackages = (...args) => pathFromWorkspaceRoot('packages', ...args) export const pathFromPackages = (...args) => pathFromWorkspaceRoot('packages', ...args)
export const require = createRequire(import.meta.url) export const require = createRequire(import.meta.url)
@ -52,7 +56,17 @@ export const getVuePlugins = (vueVersion: string) => {
export const ns = (ver) => ({ '2': '', '2.7': '2', '3': '3' }[ver] || '') export const ns = (ver) => ({ '2': '', '2.7': '2', '3': '3' }[ver] || '')
export const getBaseConfig = ({ vueVersion, dtsInclude, dts, buildTarget, themeVersion, isRuntime }) => { export interface BaseConfig {
vueVersion: string
dtsInclude: string[] | Set<string>
dts: boolean
buildTarget: string
themeVersion: string
npmScope?: string
isRuntime: boolean
}
export const getBaseConfig = ({ vueVersion, dtsInclude, dts, buildTarget, themeVersion, isRuntime }: BaseConfig) => {
// 处理tsconfig中配置主要是处理paths映射确保dts可以找到正确的包 // 处理tsconfig中配置主要是处理paths映射确保dts可以找到正确的包
const compilerOptions = require(pathFromWorkspaceRoot(`tsconfig.vue${vueVersion}.json`)).compilerOptions const compilerOptions = require(pathFromWorkspaceRoot(`tsconfig.vue${vueVersion}.json`)).compilerOptions
@ -189,10 +203,10 @@ async function batchBuildAll({ vueVersion, tasks, formats, message, emptyOutDir,
async function batchBuild({ vueVersion, tasks, formats, message, emptyOutDir, dts }) { async function batchBuild({ vueVersion, tasks, formats, message, emptyOutDir, dts }) {
if (tasks.length === 0) return if (tasks.length === 0) return
utils.logGreen(`====== 开始构建 ${message} ======`) logGreen(`====== 开始构建 ${message} ======`)
const entry = toEntry(tasks) const entry = toEntry(tasks)
const dtsInclude = toTsInclude(tasks) const dtsInclude = toTsInclude(tasks) as BaseConfig['dtsInclude']
await build({ await build({
configFile: false, configFile: false,
...getBaseConfig({ vueVersion, dtsInclude, dts, buildTarget, themeVersion, isRuntime: false }), ...getBaseConfig({ vueVersion, dtsInclude, dts, buildTarget, themeVersion, isRuntime: false }),
@ -203,7 +217,7 @@ async function batchBuildAll({ vueVersion, tasks, formats, message, emptyOutDir,
plugins: [ plugins: [
getBabelOutputPlugin({ getBabelOutputPlugin({
presets: [['@babel/preset-env', { loose: true, modules: false }]] presets: [['@babel/preset-env', { loose: true, modules: false }]]
}) }) as any
], ],
external: (source, importer, isResolved) => { external: (source, importer, isResolved) => {
// vite打包入口文件或者没有解析过得包不能排除依赖 // vite打包入口文件或者没有解析过得包不能排除依赖
@ -223,7 +237,7 @@ async function batchBuildAll({ vueVersion, tasks, formats, message, emptyOutDir,
if (/src\/index/.test(importer)) { if (/src\/index/.test(importer)) {
// 模块入口pc/mobile 文件要分离,同时排除 node_modules 依赖 // 模块入口pc/mobile 文件要分离,同时排除 node_modules 依赖
return /^\.\/(pc|mobile|mobile-first)/.test(source) || config.external(source) return /^\.\/(pc|mobile|mobile-first)/.test(source) || external(source)
} }
// @opentiny/vue 总入口,需要排除所有依赖 // @opentiny/vue 总入口,需要排除所有依赖
@ -231,7 +245,7 @@ async function batchBuildAll({ vueVersion, tasks, formats, message, emptyOutDir,
return true return true
} }
return config.external(source) return external(source)
}, },
output: { output: {
strict: false, strict: false,
@ -268,8 +282,8 @@ function getEntryTasks(): Module[] {
dtsRoot: true, dtsRoot: true,
libPath: `vue/${mode}`, libPath: `vue/${mode}`,
type: 'module', type: 'module',
name: utils.kebabCase({ str: '@opentiny/vue' }), name: kebabCase({ str: '@opentiny/vue' }),
global: utils.capitalizeKebabCase('opentinyVue'), global: capitalizeKebabCase('opentinyVue'),
importName: '@opentiny/vue' importName: '@opentiny/vue'
})) }))
} }
@ -283,7 +297,7 @@ function getTasks(names: string[]): Module[] {
return names return names
.map((name) => .map((name) =>
getByName({ getByName({
name: utils.kebabCase({ str: name.replace('@opentiny/vue-', '') }), name: kebabCase({ str: name.replace('@opentiny/vue-', '') }),
isSort: false isSort: false
}) })
) )
@ -315,7 +329,7 @@ export async function buildUi(
// 如果指定了打包icon或者没有传入任何组件 // 如果指定了打包icon或者没有传入任何组件
if (names.some((name) => name.includes('icon')) || !names.length) { if (names.some((name) => name.includes('icon')) || !names.length) {
tasks.push(...getByName({ name: utils.kebabCase({ str: 'icon-saas' }), isSort: false })) tasks.push(...getByName({ name: kebabCase({ str: 'icon-saas' }), isSort: false }))
tasks.push(...getAllIcons()) tasks.push(...getAllIcons())
} }

View File

@ -1,3 +1,3 @@
export * from './build-ui.js' export * from './build-ui'
export * from './build-entry.js' export * from './build-entry'
export * from './build-runtime' export * from './build-runtime'

View File

@ -54,6 +54,7 @@ export default function ({ deleteInlinedFiles = true }): Plugin {
// 删除 chunks // 删除 chunks
bundlesToDelete.forEach((name) => { bundlesToDelete.forEach((name) => {
delete bundle[name] delete bundle[name]
// eslint-disable-next-line no-console
console.log(`\n${chalk.red(name)} 已经被内联并删除`) console.log(`\n${chalk.red(name)} 已经被内联并删除`)
}) })
} }

View File

@ -1,12 +1,12 @@
import path from 'path' import path from 'node:path'
import { removeSync } from 'fs-extra' import { removeSync } from 'fs-extra'
import * as utils from './utils' import { walkFileTree, pathJoin, logGreen, logRed } from '../shared/utils'
/** /**
* packages distruntimenode_modules * packages distruntimenode_modules
*/ */
const deleteDistFile = () => { const deleteDistFile = () => {
utils.walkFileTree({ walkFileTree({
isDeep: true, isDeep: true,
fileFilter({ file, subPath, isDirectory }) { fileFilter({ file, subPath, isDirectory }) {
let flag = true let flag = true
@ -22,7 +22,7 @@ const deleteDistFile = () => {
return flag return flag
}, },
dirPath: utils.pathJoin('..', 'packages'), dirPath: pathJoin('..', 'packages'),
callback() { callback() {
// empty // empty
} }
@ -42,7 +42,7 @@ try {
removeSync(path.join(__dirname, '..', 'packages', name + '.js')) removeSync(path.join(__dirname, '..', 'packages', name + '.js'))
}) })
utils.logGreen('npm run clean:build done.') logGreen('npm run clean:build done.')
} catch (e) { } catch (e) {
utils.logRed('npm run clean:build failed.', e) logRed('npm run clean:build failed.')
} }

View File

@ -4,7 +4,7 @@
import path from 'node:path' import path from 'node:path'
import fs from 'fs-extra' import fs from 'fs-extra'
import { searchForWorkspaceRoot } from 'vite' import { searchForWorkspaceRoot } from 'vite'
import { filesFragmentReplace } from '../../shared/utils.js' import { filesFragmentReplace } from '../../shared/utils'
const ROOT_PATH = searchForWorkspaceRoot(process.cwd()) const ROOT_PATH = searchForWorkspaceRoot(process.cwd())
const packages = path.join(ROOT_PATH, 'packages') const packages = path.join(ROOT_PATH, 'packages')

View File

@ -1,6 +1,6 @@
import path from 'node:path' import path from 'node:path'
import fs from 'fs-extra' import fs from 'fs-extra'
import * as utils from '../../shared/utils' import { capitalize, walkFileTree, pathFromWorkspaceRoot, logGreen, logRed } from '../../shared/utils'
import { writeModuleMap, quickSort } from '../../shared/module-utils' import { writeModuleMap, quickSort } from '../../shared/module-utils'
import commonMapping from './commonMapping.json' import commonMapping from './commonMapping.json'
@ -30,7 +30,7 @@ const getTemplateName = (currentPaths, entryObj) => {
} }
const mapKey = Object.keys(entryObj).filter(item => entryObj[item] && item !== 'isBuildEntryFile')[0] const mapKey = Object.keys(entryObj).filter(item => entryObj[item] && item !== 'isBuildEntryFile')[0]
const subFix = entryMaps[mapKey] const subFix = entryMaps[mapKey]
return `${currentPaths.split('-').map(utils.capitalize).join('')}${subFix}` return `${currentPaths.split('-').map(capitalize).join('')}${subFix}`
} }
const tempMap = { const tempMap = {
@ -47,9 +47,9 @@ const makeModules = () => {
// 获取存放所有组件的文件夹 // 获取存放所有组件的文件夹
const packagesStr = 'packages/vue/src' const packagesStr = 'packages/vue/src'
utils.walkFileTree({ walkFileTree({
isDeep: true, isDeep: true,
dirPath: utils.pathFromWorkspaceRoot(packagesStr), dirPath: pathFromWorkspaceRoot(packagesStr),
fileFilter({ file }) { fileFilter({ file }) {
return !/node_modules|helper|common|assets/.test(file) return !/node_modules|helper|common|assets/.test(file)
}, },
@ -97,7 +97,7 @@ const makeModules = () => {
try { try {
makeModules() makeModules()
utils.logGreen('npm run create:mapping done.') logGreen('npm run create:mapping done.')
} catch (e) { } catch (e) {
utils.logRed(e) logRed(e)
} }

View File

@ -5,21 +5,28 @@
* yarn create:ui img-preview -single pc / * yarn create:ui img-preview -single pc /
* yarn create:ui img-preview -mobile * yarn create:ui img-preview -mobile
*/ */
import path from 'path' import path from 'node:path'
import fs from 'fs-extra' import fs from 'fs-extra'
import semver from 'semver' import semver from 'semver'
import * as utils from '../../shared/utils' import {
getInputCmd,
pathJoin,
walkFileTree,
capitalizeKebabCase,
logGreen,
logYellow
} from '../../shared/utils'
import { createModuleMapping } from '../../shared/module-utils' import { createModuleMapping } from '../../shared/module-utils'
import handlebarsRender from '../build/handlebars.render' import handlebarsRender from '../build/handlebars.render'
const args = utils.getInputCmd() const args = getInputCmd()
if (args.length > 0) { if (args.length > 0) {
const commands: string[] = [] const commands: string[] = []
const components: string[] = [] const components: string[] = []
const templateDir = utils.pathJoin('../../public/template/component') const templateDir = pathJoin('../../public/template/component')
const componetDir = utils.pathJoin('../../../../packages/vue/src') const componetDir = pathJoin('../../../../packages/vue/src')
const { version } = fs.readJSONSync(utils.pathJoin('../../../../packages/vue/package.json')) const { version } = fs.readJSONSync(pathJoin('../../../../packages/vue/package.json'))
args.forEach((item) => { args.forEach((item) => {
if (item.indexOf('-') === 0) { if (item.indexOf('-') === 0) {
@ -36,11 +43,11 @@ if (args.length > 0) {
let componentPath = path.join(componetDir, componentName) let componentPath = path.join(componetDir, componentName)
if (fs.existsSync(componentPath)) { if (fs.existsSync(componentPath)) {
utils.logYellow(`The component name : ${componentName} is exist , please enter other name.`) logYellow(`The component name : ${componentName} is exist , please enter other name.`)
return return
} }
utils.walkFileTree({ walkFileTree({
isDeep: true, isDeep: true,
dirPath: templateDir, dirPath: templateDir,
callback({ file, subPath }) { callback({ file, subPath }) {
@ -70,7 +77,7 @@ if (args.length > 0) {
componentPath = path.join(componentPath, fileName) componentPath = path.join(componentPath, fileName)
let fileContent = fs.readFileSync(subPath, { encoding: 'utf8' }) let fileContent = fs.readFileSync(subPath, { encoding: 'utf8' })
const upperComponentName = utils.capitalizeKebabCase(componentName) const upperComponentName = capitalizeKebabCase(componentName)
// 编译模板 // 编译模板
fileContent = handlebarsRender({ fileContent = handlebarsRender({
@ -92,7 +99,7 @@ if (args.length > 0) {
createModuleMapping(componentName, isMobile) createModuleMapping(componentName, isMobile)
}) })
utils.logGreen('npm run create:ui done.') logGreen('npm run create:ui done.')
} else { } else {
utils.logYellow('please enter the component name after command.') logYellow('please enter the component name after command.')
} }

View File

@ -1 +1 @@
export * from './create-icon-saas.js' export * from './create-icon-saas'

View File

@ -1,29 +1,37 @@
/** /**
* / ICON @opentiny/vue-theme/svgs SVG ICON * / ICON @opentiny/vue-theme/svgs SVG ICON
*/ */
const path = require('path') import path from 'node:path'
const fs = require('fs-extra') import fs from 'fs-extra'
const utils = require('./utils') import semver from 'semver'
const semver = require('semver') import { EOL } from 'node:os'
const { EOL } = require('os') import handlebarsRender from '../build/handlebars.render'
const handlebarsRender = require('./handlebars.render') import {
pathJoin,
logYellow,
getopentinyVersion,
capitalizeKebabCase,
prettierFormat,
logGreen,
logRed
} from '../../shared/utils'
const svgRE = /\.svg$/ const svgRE = /\.svg$/
const svgDir = utils.pathJoin('..', 'node_modules', '@opentiny', 'theme', 'svgs') const svgDir = pathJoin('..', 'node_modules', '@opentiny', 'theme', 'svgs')
const iconDir = utils.pathJoin('..', 'packages', 'icon') const iconDir = pathJoin('..', 'packages', 'icon')
const packageJson = 'package.json' const packageJson = 'package.json'
const templatePath = utils.pathJoin('..', 'template') const templatePath = pathJoin('..', 'template')
// 检查是否按照依赖包 // 检查是否按照依赖包
if (!fs.existsSync(svgDir)) { if (!fs.existsSync(svgDir)) {
utils.logYellow(`The @opentiny/vue-theme is not exist , please npm install @opentiny/vue-theme.`) logYellow('The @opentiny/vue-theme is not exist , please npm install @opentiny/vue-theme.')
} }
// 是否包含 package/icon 目录 // 是否包含 package/icon 目录
if (!fs.existsSync(iconDir)) { if (!fs.existsSync(iconDir)) {
fs.mkdirSync(iconDir) fs.mkdirSync(iconDir)
const version = utils.getopentinyVersion() const version = getopentinyVersion({ key: 'version' })
const iconTemplate = fs.readJSONSync(path.join(templatePath, 'component', packageJson)) const iconTemplate = fs.readJSONSync(path.join(templatePath, 'component', packageJson))
// 删除多余的依赖 // 删除多余的依赖
@ -43,8 +51,8 @@ if (!fs.existsSync(iconDir)) {
fs.writeFileSync(path.join(iconDir, packageJson), packageContent) fs.writeFileSync(path.join(iconDir, packageJson), packageContent)
} }
const exportComponents = [] const exportComponents: string[] = []
const exportIcons = [] const exportIcons: string[] = []
const componentTemplate = fs.readFileSync(path.join(templatePath, 'icon', 'index.ts'), { encoding: 'utf8' }) const componentTemplate = fs.readFileSync(path.join(templatePath, 'icon', 'index.ts'), { encoding: 'utf8' })
// 根据 @opentiny/vue-theme/svgs 中的 svg 图片创建对应的 icon 组件 // 根据 @opentiny/vue-theme/svgs 中的 svg 图片创建对应的 icon 组件
@ -56,7 +64,7 @@ fs.readdirSync(svgDir).forEach((fileName) => {
if (!fs.existsSync(iconPath)) { if (!fs.existsSync(iconPath)) {
fs.mkdirSync(iconPath) fs.mkdirSync(iconPath)
const iconName = utils.capitalizeKebabCase(svgName) const iconName = capitalizeKebabCase(svgName)
const fullIconName = `Icon${iconName}` const fullIconName = `Icon${iconName}`
const iconEntryContent = handlebarsRender({ const iconEntryContent = handlebarsRender({
template: componentTemplate, template: componentTemplate,
@ -67,7 +75,7 @@ fs.readdirSync(svgDir).forEach((fileName) => {
delimiter: ['\\[\\[', '\\]\\]'] delimiter: ['\\[\\[', '\\]\\]']
}) })
fs.writeFileSync(path.join(iconPath, 'index.ts'), utils.prettierFormat({ str: iconEntryContent })) fs.writeFileSync(path.join(iconPath, 'index.ts'), prettierFormat({ str: iconEntryContent }))
exportComponents.push(`import ${fullIconName} from './${svgName}'`) exportComponents.push(`import ${fullIconName} from './${svgName}'`)
exportIcons.push(fullIconName) exportIcons.push(fullIconName)
@ -78,7 +86,7 @@ fs.readdirSync(svgDir).forEach((fileName) => {
if (exportComponents.length) { if (exportComponents.length) {
fs.writeFileSync( fs.writeFileSync(
path.join(iconDir, 'index.ts'), path.join(iconDir, 'index.ts'),
utils.prettierFormat({ prettierFormat({
str: `${exportComponents.join(EOL)} str: `${exportComponents.join(EOL)}
export { export {
@ -92,7 +100,7 @@ if (exportComponents.length) {
}) })
) )
utils.logGreen('npm run create:icon done.') logGreen('npm run create:icon done.')
} else { } else {
utils.logRed('npm run create:icon fail.') logRed('npm run create:icon fail.')
} }

View File

@ -1,6 +1,6 @@
import path from 'node:path' import path from 'node:path'
import { searchForWorkspaceRoot } from 'vite' import { searchForWorkspaceRoot } from 'vite'
import { getAllModules } from '../shared/module-utils.js' import { getAllModules } from '../shared/module-utils'
const workspaceRoot = searchForWorkspaceRoot(process.cwd()) const workspaceRoot = searchForWorkspaceRoot(process.cwd())
const pathFromWorkspaceRoot = (...args) => path.resolve(workspaceRoot, ...args) const pathFromWorkspaceRoot = (...args) => path.resolve(workspaceRoot, ...args)

View File

@ -1,6 +1,6 @@
#!/usr/bin/env node #!/usr/bin/env node
import { Command, Option } from 'commander' import { Command, Option } from 'commander'
import { buildUi, buildEntry, buildRuntime } from './commands/build/index.js' import { buildUi, buildEntry, buildRuntime } from './commands/build'
const program = new Command() const program = new Command()

View File

@ -6,10 +6,16 @@ import * as fs from 'fs-extra'
import path from 'node:path' import path from 'node:path'
import { createRequire } from 'node:module' import { createRequire } from 'node:module'
import fg from 'fast-glob' import fg from 'fast-glob'
import * as utils from './utils' import {
pathFromWorkspaceRoot,
capitalizeKebabCase,
kebabCase,
prettierFormat,
pathJoin
} from './utils'
const require = createRequire(import.meta.url) const require = createRequire(import.meta.url)
const moduleMap = require(utils.pathFromWorkspaceRoot('packages/modules.json')) const moduleMap = require(pathFromWorkspaceRoot('packages/modules.json'))
type mode = 'pc' | 'mobile' | 'mobile-first' type mode = 'pc' | 'mobile' | 'mobile-first'
@ -66,10 +72,8 @@ const getModuleInfo = (key: string) => {
* @param {Boolean} isOriginal * @param {Boolean} isOriginal
* @param {Boolean} isSort * @param {Boolean} isSort
*/ */
const getByName = ( const getByName = ({ name, isSort = true, inversion = false, isOriginal = false }:
{ name, inversion = false, isOriginal = false, isSort = true }: { name: string; isSort: boolean; inversion?: boolean; isOriginal?: boolean }) => {
{ name: string;inversion: boolean;isOriginal: boolean;isSort: boolean }
) => {
const callback = (item) => { const callback = (item) => {
const result = new RegExp(`/${name}/|^vue-${name}/`).test(item.path) const result = new RegExp(`/${name}/|^vue-${name}/`).test(item.path)
return inversion ? !result : result return inversion ? !result : result
@ -122,10 +126,10 @@ const getSortModules = ({ filterIntercept, isSort = true }: { filterIntercept: F
// 这段逻辑暂时没有用到 // 这段逻辑暂时没有用到
const componentName = dirs.slice(1, dirs.indexOf('src')) const componentName = dirs.slice(1, dirs.indexOf('src'))
// UpperName: Todo // UpperName: Todo
component.UpperName = utils.capitalizeKebabCase(componentName.pop() ?? '') component.UpperName = capitalizeKebabCase(componentName.pop() ?? '')
// LowerName: todo // LowerName: todo
component.LowerName = utils.kebabCase({ str: component.UpperName }) component.LowerName = kebabCase({ str: component.UpperName })
// 工程的父文件夹 // 工程的父文件夹
component.parentDir = componentName component.parentDir = componentName
@ -166,7 +170,7 @@ const getSortModules = ({ filterIntercept, isSort = true }: { filterIntercept: F
// global: 'TinyTodoPc' // global: 'TinyTodoPc'
component.global = 'Tiny' + key component.global = 'Tiny' + key
component.importName = `@opentiny/vue-${utils.kebabCase({ str: key })}` component.importName = `@opentiny/vue-${kebabCase({ str: key })}`
// "vue-common/src/index.ts" ==> "vue-common/lib/index" // "vue-common/src/index.ts" ==> "vue-common/lib/index"
if (component.type === 'module') { if (component.type === 'module') {
@ -380,10 +384,8 @@ const getComponents = (mode, isSort = true) => {
* @param {Oject} newObj * @param {Oject} newObj
* @returns * @returns
*/ */
export const addModule = ( export const addModule = ({ componentName, templateName, newObj = {}, isMobile }:
{ componentName, templateName, newObj = {} }: { componentName: string; templateName?: string; newObj?: object; isMobile: boolean }) => {
{ componentName: string; templateName?: string; newObj?: object; isMobile: boolean }
) => {
const isEntry = templateName?.endsWith('index') ?? false const isEntry = templateName?.endsWith('index') ?? false
return { return {
path: `vue/src/${componentName}/` + (isEntry ? `${templateName}.ts` : `src/${templateName}.vue`), path: `vue/src/${componentName}/` + (isEntry ? `${templateName}.ts` : `src/${templateName}.vue`),
@ -400,8 +402,8 @@ export const addModule = (
*/ */
export const writeModuleMap = (moduleMap) => { export const writeModuleMap = (moduleMap) => {
fs.writeFileSync( fs.writeFileSync(
utils.pathFromWorkspaceRoot('packages/modules.json'), pathFromWorkspaceRoot('packages/modules.json'),
utils.prettierFormat({ prettierFormat({
str: typeof moduleMap === 'string' ? moduleMap : JSON.stringify(moduleMap), str: typeof moduleMap === 'string' ? moduleMap : JSON.stringify(moduleMap),
options: { options: {
parser: 'json', parser: 'json',
@ -423,7 +425,7 @@ export const readModuleMap = () => moduleMap || {}
* @param {Boolean} isMobile * @param {Boolean} isMobile
*/ */
const createModuleMapping = (componentName, isMobile = false) => { const createModuleMapping = (componentName, isMobile = false) => {
const upperName = utils.capitalizeKebabCase(componentName) const upperName = capitalizeKebabCase(componentName)
// 生成 modules.json 文件 // 生成 modules.json 文件
moduleMap[upperName] = addModule({ moduleMap[upperName] = addModule({
@ -434,8 +436,8 @@ const createModuleMapping = (componentName, isMobile = false) => {
const moduleJson = quickSort({ sortData: moduleMap, returnType: 'object' }) const moduleJson = quickSort({ sortData: moduleMap, returnType: 'object' })
fs.writeJsonSync( fs.writeJsonSync(
utils.pathJoin('..', 'modules.json'), pathJoin('..', 'modules.json'),
utils.prettierFormat({ prettierFormat({
str: JSON.stringify(moduleJson), str: JSON.stringify(moduleJson),
options: { options: {
parser: 'json', parser: 'json',
@ -446,7 +448,7 @@ const createModuleMapping = (componentName, isMobile = false) => {
} }
const getAllIcons = () => { const getAllIcons = () => {
const entries = fg.sync('vue-icon*/src/*', { cwd: utils.pathFromWorkspaceRoot('packages'), onlyDirectories: true }) const entries = fg.sync('vue-icon*/src/*', { cwd: pathFromWorkspaceRoot('packages'), onlyDirectories: true })
return entries.map((item) => { return entries.map((item) => {
const name = path.basename(item) const name = path.basename(item)
@ -456,8 +458,8 @@ const getAllIcons = () => {
libPath: item.replace('/src/', '/lib/'), libPath: item.replace('/src/', '/lib/'),
type: 'component', type: 'component',
componentType: 'icon', componentType: 'icon',
name: utils.kebabCase({ str: name }), name: kebabCase({ str: name }),
global: utils.capitalizeKebabCase(name), global: capitalizeKebabCase(name),
importName: '@opentiny/vue-' + item importName: '@opentiny/vue-' + item
} as Module } as Module
}) })

View File

@ -129,7 +129,7 @@ const kebabCase = ({ str, splitChar = '-' }: { str: string; splitChar?: string }
* @param {String} str * @param {String} str
* @param {Object} options * @param {Object} options
*/ */
const prettierFormat = ({ str, options = {} }: { str: string; options: object }) => { const prettierFormat = ({ str, options = {} }: { str: string; options?: object }) => {
return prettier.format( return prettier.format(
str, str,
Object.assign( Object.assign(
@ -156,10 +156,8 @@ const prettierFormat = ({ str, options = {} }: { str: string; options: object })
* @param {Function} fileFilter * @param {Function} fileFilter
* @param {Function} callback * @param {Function} callback
*/ */
const walkFileTree = ( const walkFileTree = ({ dirPath, isDeep = false, fileFilter, callback }:
{ dirPath, isDeep = false, fileFilter, callback }: { dirPath: string; isDeep: boolean; fileFilter?: Function; callback: Function }) => {
{ dirPath: string; isDeep: boolean; fileFilter?: Function; callback: Function }
) => {
if (!dirPath || typeof callback !== 'function') { if (!dirPath || typeof callback !== 'function') {
return return
} }
@ -207,10 +205,8 @@ const getVersion = ({ name, context, isVue2 }: { name: string; context: string;
* @param {Boolean} vue2 * @param {Boolean} vue2
* @returns * @returns
*/ */
const getComponentVersion = ( const getComponentVersion = ({ name, context = '..', dir = 'packages', isOrigin = false, isVue2 }:
{ name, context = '..', dir = 'packages', isOrigin = false, isVue2 }: { name: string; context?: string; dir?: string; isOrigin?: boolean; isVue2: boolean }) => {
{ name: string; context?: string; dir?: string; isOrigin?: boolean; isVue2: boolean }
) => {
let version: string let version: string
const packageJSONPath = pathJoin(context, dir, name, 'package.json') const packageJSONPath = pathJoin(context, dir, name, 'package.json')
@ -476,7 +472,7 @@ const fragmentReplace = (filePath, regExpStr, targetStr) => {
* @param {Array<string> | string} regExpStr * @param {Array<string> | string} regExpStr
* @param {Array<string> | string} targetStr * @param {Array<string> | string} targetStr
*/ */
const filesFragmentReplace = (folderPath, regExpStr: Array<string> | string, targetStr: Array<string> | string) => { const filesFragmentReplace = (folderPath, regExpStr: Array<string | RegExp> | string | RegExp, targetStr: Array<string> | string) => {
let filesPath = getFilesPath(folderPath) let filesPath = getFilesPath(folderPath)
if (filesPath) { if (filesPath) {

View File

@ -1,6 +1,6 @@
const fs = require('fs-extra') import * as fs from 'fs-extra'
const path = require('path') import path from 'node:path'
const { filesFragmentReplace, logYellow, isBuildForVue2, logGreen } = require('./utils') import { filesFragmentReplace, logYellow, isBuildForVue2, logGreen } from './utils'
const replaceVue3Type = process.env.REPLACE_VUE3_TYPE const replaceVue3Type = process.env.REPLACE_VUE3_TYPE
@ -25,9 +25,9 @@ if (replaceVue3Type === 'typings') {
/'virtual:locale\/vue'/g /'virtual:locale\/vue'/g
], ],
[ [
"'./vue2'", '\'./vue2\'',
"'./types/vue2'", '\'./types/vue2\'',
"'./vue2'" '\'./vue2\''
] ]
) )
} else { } else {
@ -54,9 +54,9 @@ if (replaceVue3Type === 'typings') {
/'virtual:locale\/vue'/g /'virtual:locale\/vue'/g
], ],
[ [
"'./vue3'", '\'./vue3\'',
"'./types/vue3'", '\'./types/vue3\'',
"'./vue3'" '\'./vue3\''
] ]
) )
} else { } else {