Full-project rename. `git grep -i aksrt` is now empty apart from the
DBMigrator 3.3.0 changelog note that documents the rename itself.
Code identifiers
- PHP namespace AKSRT\ -> Jio\ (composer PSR-4 + 378 declarations)
- global constants AKSRT_* -> JIO_* (VERSION/DIR/URI, PAY_TYPE_*, CAPTCHA_*)
- procedural functions, hooks, options, meta keys, table names,
cookies, query vars, ajax actions and nonces: aksrt_ -> jio_
- text domain aksrt -> jio; Theme Name -> Jio
- JS globals: aksrtData/aksrtAdminData/... -> jioData/jioAdminData/...,
window.AKSRTCaptcha & friends -> window.JioCaptcha, Aksrt* -> Jio*
- Vue components Aks*.vue -> Jio*.vue (15 files renamed + imports)
- CSS classes/data-attrs/custom properties: aksrt- -> jio-
- REST namespace aksrt/v1 -> jio/v1 (incl. payment gateway callbacks)
Storage layer
- DB tables {prefix}aksrt_* -> {prefix}jio_*; SCHEMA_VERSION 3.2.0 -> 3.3.0
so dbDelta creates the new names on install
- widget id_base aksrt_widget_* -> jio_widget_*
- uninstall.php drop list rebuilt from the actual migrator tables
(dropped 3 stale entries, added the 17 missing ones)
Removed
- hardcoded https://api.aksrt.com/version.json default update endpoint;
get_endpoint() now reads the 「更新端点」 setting and do_check() no-ops
when it is empty
Files renamed: inc/helpers/aksrt-*.php -> jio-*.php (54),
assets/admin/src/components/form/Aks*.vue -> Jio*.vue (15).
Build artifacts regenerated: assets/css/build, assets/js/runtime,
assets/admin/build.
Verified: audit-psr4-paths errors=0, audit-admin-contracts errors=0
(warnings=56, unchanged baseline), 813/813 widget-system tests,
44/44 phpunit, php -l clean across all PHP.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
182 lines
6.6 KiB
JavaScript
182 lines
6.6 KiB
JavaScript
/**
|
|
* extract-naive-styles.mjs
|
|
*
|
|
* 在构建时直接调用 NaiveUI 组件的 .cssr.mjs 样式函数的 render() 方法,
|
|
* 提取所有组件的运行时 JSS 为静态 CSS 文件。
|
|
* 彻底解决 WordPress 后台环境中样式丢失问题。
|
|
*
|
|
* 原理:
|
|
* 每个 NaiveUI 组件都有 src/styles/index.cssr.mjs 文件
|
|
* 导出的函数返回 css-render 的 CNode 对象
|
|
* 调用 CNode.render({ clsPrefix: 'n' }) 即可获取纯 CSS 字符串
|
|
* 无需虚拟 DOM、无需 Vue、无任何浏览器 API 依赖
|
|
*/
|
|
|
|
import { writeFile, mkdir } from 'fs/promises'
|
|
import { dirname, join } from 'path'
|
|
import { fileURLToPath } from 'url'
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
const BUILD_DIR = join(__dirname, 'build')
|
|
|
|
// ============================================================
|
|
// 需要提取样式的组件列表(对应各组件的 .cssr.mjs 入口)
|
|
// 格式:[导入路径在 naive-ui/es 内部的相对路径]
|
|
// ============================================================
|
|
const COMPONENT_STYLES = [
|
|
// 内部基础组件
|
|
['_internal/scrollbar/src/styles/index.cssr.mjs'],
|
|
// 布局
|
|
['layout/src/styles/layout.cssr.mjs'],
|
|
// 导航
|
|
['menu/src/styles/index.cssr.mjs'],
|
|
['breadcrumb/src/styles/index.cssr.mjs'],
|
|
['tabs/src/styles/index.cssr.mjs'],
|
|
['steps/src/styles/index.cssr.mjs'],
|
|
['pagination/src/styles/index.cssr.mjs'],
|
|
// 表单
|
|
['form/src/styles/form.cssr.mjs'],
|
|
['form/src/styles/form-item.cssr.mjs'],
|
|
['input/src/styles/input.cssr.mjs'],
|
|
['input/src/styles/input-group.cssr.mjs'],
|
|
['input-number/src/styles/input-number.cssr.mjs'],
|
|
['switch/src/styles/index.cssr.mjs'],
|
|
['select/src/styles/index.cssr.mjs'],
|
|
['radio/src/styles/radio.cssr.mjs'],
|
|
['radio/src/styles/radio-group.cssr.mjs'],
|
|
['checkbox/src/styles/index.cssr.mjs'],
|
|
['slider/src/styles/index.cssr.mjs'],
|
|
['rate/src/styles/index.cssr.mjs'],
|
|
['date-picker/src/styles/index.cssr.mjs'],
|
|
['time-picker/src/styles/index.cssr.mjs'],
|
|
// 展示
|
|
['card/src/styles/index.cssr.mjs'],
|
|
['tag/src/styles/index.cssr.mjs'],
|
|
['alert/src/styles/index.cssr.mjs'],
|
|
['data-table/src/styles/index.cssr.mjs'],
|
|
['descriptions/src/styles/index.cssr.mjs'],
|
|
['empty/src/styles/index.cssr.mjs'],
|
|
['result/src/styles/index.cssr.mjs'],
|
|
['statistic/src/styles/index.cssr.mjs'],
|
|
['list/src/styles/index.cssr.mjs'],
|
|
['collapse/src/styles/index.cssr.mjs'],
|
|
['timeline/src/styles/index.cssr.mjs'],
|
|
// 反馈
|
|
['button/src/styles/index.cssr.mjs'],
|
|
['modal/src/styles/index.cssr.mjs'],
|
|
['dialog/src/styles/index.cssr.mjs'],
|
|
['message/src/styles/index.cssr.mjs'],
|
|
['notification/src/styles/index.cssr.mjs'],
|
|
['popconfirm/src/styles/index.cssr.mjs'],
|
|
['popover/src/styles/index.cssr.mjs'],
|
|
// tooltip 复用 popover 的共享样式(自身没有独立 cssr 文件)。
|
|
['dropdown/src/styles/index.cssr.mjs'],
|
|
// 其他
|
|
['icon/src/styles/index.cssr.mjs'],
|
|
['icon-wrapper/src/styles/index.cssr.mjs'],
|
|
// space 全部用内联 style 布局,没有 cssr 文件,故不在此列。
|
|
['divider/src/styles/index.cssr.mjs'],
|
|
['gradient-text/src/styles/index.cssr.mjs'],
|
|
['ellipsis/src/styles/index.cssr.mjs'],
|
|
['spin/src/styles/index.cssr.mjs'],
|
|
['loading-bar/src/styles/index.cssr.mjs'],
|
|
['upload/src/styles/index.cssr.mjs'],
|
|
['image/src/styles/index.cssr.mjs'],
|
|
['carousel/src/styles/index.cssr.mjs'],
|
|
['transfer/src/styles/index.cssr.mjs'],
|
|
['tree-select/src/styles/index.cssr.mjs'],
|
|
['tree/src/styles/index.cssr.mjs'],
|
|
['thing/src/styles/index.cssr.mjs'],
|
|
['color-picker/src/styles/index.cssr.mjs'],
|
|
['typography/src/styles/p.cssr.mjs'],
|
|
['typography/src/styles/a.cssr.mjs'],
|
|
['typography/src/styles/blockquote.cssr.mjs'],
|
|
['typography/src/styles/list.cssr.mjs'],
|
|
['typography/src/styles/hr.cssr.mjs'],
|
|
['typography/src/styles/header.cssr.mjs'],
|
|
['auto-complete/src/styles/index.cssr.mjs'],
|
|
['cascader/src/styles/index.cssr.mjs'],
|
|
['dynamic-input/src/styles/index.cssr.mjs'],
|
|
['dynamic-tags/src/styles/index.cssr.mjs'],
|
|
['input-otp/src/styles/index.cssr.mjs'],
|
|
// 全局
|
|
['_styles/global/index.cssr.mjs'],
|
|
]
|
|
|
|
async function extractStyles() {
|
|
console.log('\n[Jio] 开始提取 NaiveUI 组件样式...\n')
|
|
|
|
const allCss = []
|
|
let successCount = 0
|
|
let failCount = 0
|
|
|
|
for (const [componentPath] of COMPONENT_STYLES) {
|
|
try {
|
|
// 动态导入每个组件的 cssr 样式模块
|
|
const styleModule = await import(
|
|
`naive-ui/es/${componentPath}`
|
|
)
|
|
|
|
const defaultExport = styleModule.default || styleModule
|
|
|
|
// cssr 模块有两种导出形态:函数本体,或带 render() 的 CNode 对象。
|
|
// 两者都必须接收 props 对象(至少 {}),否则 render 内部读
|
|
// props.bPrefix 会抛错——card / data-table / dialog 等组件的样式
|
|
// 曾因漏传参数被整体跳过。
|
|
const css = typeof defaultExport === 'function'
|
|
? defaultExport({ clsPrefix: 'n' })
|
|
: defaultExport.render({ clsPrefix: 'n' })
|
|
|
|
if (typeof css === 'string' && css.trim()) {
|
|
allCss.push(`/* ${componentPath} */\n${css}`)
|
|
successCount++
|
|
}
|
|
} catch (err) {
|
|
const code = err && err.code
|
|
// 路径写错时 import 会直接抛 MODULE_NOT_FOUND。这类错误必须显式报出来:
|
|
// 静默跳过的后果是组件样式整体缺失(取色器曾因此没有尺寸和边框,糊成一团),
|
|
// 而页面不报错,只能靠肉眼发现。
|
|
if (code === 'ERR_MODULE_NOT_FOUND' || code === 'MODULE_NOT_FOUND') {
|
|
console.error(`[Jio] 样式路径不存在,已跳过: ${componentPath}`)
|
|
} else {
|
|
console.error(`[Jio] 样式提取异常,已跳过: ${componentPath}: ${err && err.message}`)
|
|
}
|
|
failCount++
|
|
}
|
|
}
|
|
|
|
const cssOutput = allCss.join('\n\n')
|
|
|
|
if (!cssOutput.trim()) {
|
|
console.warn('[Jio] 警告:未提取到任何 NaiveUI 样式!')
|
|
return null
|
|
}
|
|
|
|
// 确保 build 目录存在
|
|
await mkdir(BUILD_DIR, { recursive: true })
|
|
|
|
// 写入 CSS 文件
|
|
const cssFile = join(BUILD_DIR, 'naive-ui.css')
|
|
const fullContent = `/* Auto-extracted by extract-naive-styles.mjs */
|
|
/* Naive UI v2 Component Styles - Build-time extraction */
|
|
/* DO NOT EDIT MANUALLY */
|
|
|
|
${cssOutput}`
|
|
|
|
await writeFile(cssFile, fullContent, 'utf-8')
|
|
|
|
console.log(`[Jio] NaiveUI 样式提取完成:`)
|
|
console.log(` 成功: ${successCount} 个组件`)
|
|
console.log(` 跳过: ${failCount} 个组件`)
|
|
console.log(` 输出: ${cssFile}`)
|
|
console.log(` 大小: ${(Buffer.byteLength(fullContent) / 1024).toFixed(1)} KB\n`)
|
|
|
|
return cssFile
|
|
}
|
|
|
|
// 执行
|
|
extractStyles().catch((err) => {
|
|
console.error('[Jio] 样式提取失败:', err)
|
|
process.exit(1)
|
|
})
|