# ISV 专项
# 简介
ISV框架是为客开人员提供的一套插件类工程的项目模版。目前提供 PC
和 H5
两种类型模版,可配合 wat3 进行快速构建。
# 安装
npm install -g @esign/wat3
# 初始化项目
wat3 init plugin-demo
创建项目流程如下:
服务运行后展示效果如下:
# 脚本命令
# 查看最新的打包工具版本(如果模版里面版本落后的话请升级到最新); 要求pnpm版本6.35.1
npm view @esign/plugin-build versions --registry https://registry-npm.tsign.cn/
# 全局安装
npm i -g @esign/plugin-build@latest --registry https://registry-npm.tsign.cn/
# 项目升级最新的版本
pnpm add -Dw @esign/plugin-build@latest --registry https://registry-npm.tsign.cn/
# 运行服务指令
yarn serve
# 构建业务代码指令
yarn build:base
# 构建插件代码指令
yarn build:plugin
# 构建插件及业务代码指令
yarn build
# 快速创建插件模版指令
# 创建 template 插件模版
yarn create:plugin <插件名称>
# 构建插件指令
# 初始化插件配置
yarn plugin:init
# 构建插件 (打包所有插件)
yarn build:plugin
# 构建插件 (打包单独某个插件) 未开放
# 例如,打包 hello-world-plugin 插件
# yarn build:plugin-module @base/hello-world-plugin
# yarn build:plugin-module 插件的包名(package.name)
创建插件流程如下:
# 开发工具
- vue-class-component
- 插件使用SDK文档
- 插件构建SDK文档
- 接口请求SDK文档
- 数据SDK文档
- 指令集文档
- 通用能力SDK文档
- PC端基础组件库文档(版本号: 1.0.44-alpha1)
- H5端基础组件库文档
- 国际化vue-i18n
# 开发规范
# 目录
+-- _templates -------------------------------------------------> 插件模版目录
|
+-- dist -------------------------------------------------------> 构建后的源码目录
| |
| +-- base ---------------------------------------------------> 业务源码目录
| |
| +-- plugins ------------------------------------------------> 插件源码目录
|
+-- config -----------------------------------------------------> 配置文件
| |
| +-- verifyCommitMsg.js -------------------------------------> git提交规范
|
+-- thirdSDK ---------------------------------------------------> 三方业务测试SDK目录
| |
| +-- index.ts -----------------------------------------------> SDK包
| |
| +-- README.md ----------------------------------------------> SDK 说明文档
|
+-- build ------------------------------------------------------> 扩展指令目录(可选)
|
+-- moduleComponents -------------------------------------------> 公用业务组件目录(可选)
|
+-- plugins ----------------------------------------------------> 插件目录(必选)
| |
| +-- base ---------------------------------------------------> 业务域目录
| | |
| | +-- hello-world-plugin ---------------------------------> 插件目录
| | | |
| | | +-- package.json -----------------------------------> 插件的 package.json (用于插件单独单包)
| | | |
| | | +-- src --------------------------------------------> 插件源文件目录
| | | | |
| | | | +-- index.ts -----------------------------------> 插件入口文件
| | | | |
| | | | +-- components ---------------------------------> UI组件目录(可选)
| | | | |
| | | | +-- logic --------------------------------------> 逻辑目录(可选)
| | | | |
| | | | +-- plugin -------------------------------------> 插件源码目录
| | | | | |
| | | | | +-- index.js -------------------------------> 插件源码
| |
| +-- ......
| |
| +-- config.json --------------------------------------------> 插件配置文件目录
|
+-- pluginManager ----------------------------------------------> 插件引用方式管理目录
|
+-- src(demo) --------------------------------------------------> demo 目录(vue项目目录结构)
|
+-- .eslintrc.js -----------------------------------------------> eslint 配置文件
|
+-- .npmrc -----------------------------------------------------> npm 源配置文件
|
+-- babel.config.js --------------------------------------------> babel 配置文件
|
+-- tsconfig.json ----------------------------------------------> ts 配置文件
|
+-- package.json -----------------------------------------------> package.json
|
+-- vue.config.js ----------------------------------------------> vue 配置文件
|
+-- README.md --------------------------------------------------> 说明文档
# 国际化
如果你的项目需要使用多语言,我们的模板已提供了简单的vue-i18n
的集成能力,如下:
提示
当然,如果项目中不需要使用多语言,删除以下vue-i18n
依赖及引入文件即可
package.json
{
"dependencies": {
"vue-i18n": "8" // 8.x版本
}
}
语言包位置public/static/locales/
zh-CN.json
{
"standard": "标准",
"submitCounts": "提交次数",
"plugins.helloword.developmentDocuments": "开发文档",
"plugins.helloword.specificationDocument": "规范文档",
"plugins.helloword.toolsDocumentation": "工具文档",
"plugins.helloword.frontEndDevelopmentSpecification": "前端开发规范"
}
lib/i18n.ts
import VueI18n from 'vue-i18n'
const loadedLanguages: any = [] // 已加载的语言包
let i18n // VueI18n 实例
let langPrefix // 语言包前缀
let fallbackLocale = 'zh-CN' // 兜底语言
let beforeSetLanguage = (lang?: string) => {}
let afterSetLanguage = (lang?: string) => {}
// 解析 url 参数, 返回对象
function parseURL(url) {
return url
.slice(1)
.split('&')
.reduce((res, item) => {
const [key, value] = item.split('=')
res[key] = value
return res
}, {})
}
// url 中的语言标识
const langFromUrl = parseURL(window.location.search).lang
// 浏览器的语言设置
const langFromBrowser = window.navigator && window.navigator.language
let lang: string = langFromUrl || langFromBrowser || ''
// 浏览器设置语言环境为英文时, navigator.language 取出来的标识符可能是 en, en-us
lang = ['en', 'en-us', 'en-US'].includes(lang) ? 'en-US' : fallbackLocale // TODO: 现在就两种语言
// 异步加载语言包
function loadLanguageAsync(lang) {
beforeSetLanguage(lang)
return new Promise((resolve, reject) => {
// 已经加载过, 返回
if (loadedLanguages.includes(lang)) return resolve(setI18nLanguage(lang))
if (window[`i18n_${lang}`]) {
i18n.setLocaleMessage(lang, window[`i18n_${lang}`])
loadedLanguages.push(lang)
resolve(setI18nLanguage(lang))
return
}
// Indicator.open()
window.axios
.get(`${langPrefix}${lang}.json?t=${new Date().getTime()}`, { withCredentials: false })
.then(res => {
// Indicator.close()
i18n.setLocaleMessage(lang, res.data)
loadedLanguages.push(lang)
resolve(setI18nLanguage(lang))
})
.catch(e => {
reject(e)
})
.finally(() => {
afterSetLanguage(lang)
})
})
}
// 设置语言到关联语言的地方
function setI18nLanguage(lang) {
i18n.locale = lang
return lang
}
/**
*
* @param {*} Vue
* @param {*} prefix 语言包地址前缀
* @param {*} options 透传给 VueI18n 的参数
*/
function init(Vue, prefix, options): Promise<VueI18n> {
const opt = options || {}
langPrefix = prefix
Vue.use(VueI18n)
beforeSetLanguage = opt.beforeSetLanguage || beforeSetLanguage
afterSetLanguage = opt.afterSetLanguage || afterSetLanguage
fallbackLocale = opt.fallbackLocale || fallbackLocale
i18n = new VueI18n({
locale: lang || fallbackLocale, // set locale
fallbackLocale,
messages: {}, // set locale messages
...options,
})
return new Promise((resolve, reject) => {
return loadLanguageAsync(lang)
.catch(e => {
console.error(`Load language ${lang} fail, use fallback language ${fallbackLocale} instead.`)
loadLanguageAsync(fallbackLocale)
})
.catch(e => console.error('fallback language also faled. Use text key'))
.finally(() => resolve(i18n))
})
}
function text(...args) {
return i18n.t(...args)
}
function getLanguage() {
return i18n.locale
}
export { init, text as $t, getLanguage, loadLanguageAsync as setLanguage, i18n }
入口文件main.ts
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import { init as initI18n, $t, setLanguage, getLanguage } from './lib/i18n'
import axios from 'axios'
Vue.prototype.$t = $t
Vue.prototype.$setLanguage = setLanguage
Vue.prototype.$getLanguage = getLanguage
window.axios = axios
const prefix = '/static/locales/' // 字体包url前缀
initI18n(Vue, prefix, {}).then(async i18n => {
new Vue({
router,
store,
i18n,
render: h => h(App),
}).$mount('#app')
})
项目中使用
<template>
<div class="hello-world">
<h3>{{ $t('plugins.helloword.specificationDocument') }}</h3>
</div>
</template>
效果如下:
# 注意事项
- UI类组件使用/升级机制
通用UI类组件
: 通用组件会有专有的npm
包,客开人员可自行安装使用。定制UI类组件
: 定制组件会在项目开发前由主应用开发人员统一放在moduleComponents
目录下,客开人员可自行使用。
- src目录说明
- src目录内容为开发的插件提供可
预览
的页面,便于插件开发时预览UI效果和业务逻辑。
- src目录内容为开发的插件提供可
- 更多插件开发案例,可参考 esign-plugin-demo
esign-plugin-demo
仓库权限(或源码)可向主应用开发人员
申请。