Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: optimize expression, flatten i18n json, add validations for lite card #69

Merged
merged 9 commits into from
Nov 5, 2024
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"rules": {
"camelcase": 0,
"no-debugger": 1,
"no-unused-vars": 1
"no-unused-vars": 1,
"no-control-regex": 1
}
}
36 changes: 36 additions & 0 deletions packages/hap-compiler/src/actions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2021-present, the hapjs-platform Project Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { checkParams } from './validator'

function parse(actionObj) {
/**
* "actionObj": {
"jumpWithParams": {
"type": "router",
"url": "{{jumpParamsUrl}}",
"params": {
"type": "{{jumpParam}}"
}
},
}
*/
if (actionObj && Object.prototype.toString.call(actionObj) !== '[object Object]') {
throw new Error(`<data> 事件 actions 必须为 Object 对象`)
}

// 检查params参数合法性
Object.keys(actionObj).forEach((key) => {
checkParams(actionObj[key].params, 1)
})

return {
jsonAction: actionObj
}
}

export default {
parse
}
30 changes: 30 additions & 0 deletions packages/hap-compiler/src/actions/validator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2021-present, the hapjs-platform Project Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import exp from '../template/exp'

function isReserved(str) {
// $开头
const c = (str + '').charCodeAt(0)
return c === 0x24
}

function checkParams(paramsObj, dep) {
if (!paramsObj || Object.prototype.toString.call(paramsObj) !== '[object Object]') return

Object.keys(paramsObj).forEach((key) => {
if (isReserved(key)) {
throw new Error(`<data> 事件 actions 中 params 参数名不能以 “$” 开头`)
}

if (exp.isExpr(paramsObj[key]) && dep > 1) {
throw new Error(`<data> 事件 actions 中 params 参数值只支持一级结构中绑定变量`)
}

checkParams(paramsObj[key], dep + 1)
})
}

export { checkParams }
16 changes: 14 additions & 2 deletions packages/hap-compiler/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
'use strict'
import parse5 from 'parse5'
import templater from './template'
import actioner from './actions'
import styler from './style'
import scripter from './script'
import { serialize } from './utils'

export { scripter, styler, templater }
export { scripter, styler, templater, actioner }
export * from './style'

/**
Expand Down Expand Up @@ -156,5 +157,16 @@ function parseScript(source) {
return { parsed: parsed }
}

export { parseFragmentsWithCache, parseTemplate, parseStyle, parseScript, serialize }
/**
* 解析actions
* @param {String} jsonObj - actions对象
* @returns {Object}
*/
function parseActions(jsonObj) {
const { jsonAction } = actioner.parse(jsonObj)
const parsed = JSON.stringify(jsonAction)
return { parsed }
}

export { parseFragmentsWithCache, parseTemplate, parseStyle, parseScript, parseActions, serialize }
export { ENTRY_TYPE, FRAG_TYPE, isEmptyObject } from './utils'
2 changes: 1 addition & 1 deletion packages/hap-compiler/src/template/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ function traverse(node, output, previousNode, conditionList, options) {
output.log.push({
line: node.__location.line,
column: node.__location.col,
reason: `Warn: 组件 ${node.tagName} 不支持文本内容作为字节点`
reason: `Warn: 组件 ${node.tagName} 不支持文本内容作为子节点`
})
}
}
Expand Down
24 changes: 14 additions & 10 deletions packages/hap-compiler/src/template/validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ const tagNatives = {
}
},
component: {
supportCard: true,
excludeRoot: true,
attrs: {
extendCommon: false, // 不支持通用属性
Expand Down Expand Up @@ -1827,15 +1828,17 @@ function checkCustomDirective(name, value, output, node) {
function checkAttr(name, value, output, tagName, locationInfo, options) {
if (name && isValidValue(value)) {
if (shouldConvertPath(name, value, tagName)) {
// 判断路径下资源是否存在
const hasFile = fileExists(value, options.filePath)
if (!hasFile) {
output.log.push({
line: locationInfo.line,
column: locationInfo.column,
reason:
'WARN: ' + tagName + ' 属性 ' + name + ' 的值 ' + value + ' 下不存在对应的文件资源'
})
if (!exp.isExpr(value)) {
// 若路径不包含表达式,判断路径下资源是否存在
const hasFile = fileExists(value, options.filePath)
if (!hasFile) {
output.log.push({
line: locationInfo.line,
column: locationInfo.column,
reason:
'WARN: ' + tagName + ' 属性 ' + name + ' 的值 ' + value + ' 下不存在对应的文件资源'
})
}
}
// 转换为以项目源码为根的绝对路径
value = resolvePath(value, options.filePath)
Expand Down Expand Up @@ -2017,5 +2020,6 @@ export default {
getTagChildren,
isSupportedSelfClosing,
isEmptyElement,
isNotTextContentAtomic
isNotTextContentAtomic,
isExpr: exp.isExpr
}
11 changes: 7 additions & 4 deletions packages/hap-dsl-xvm/src/loaders/action-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
* Copyright (c) 2024-present, the hapjs-platform Project Contributors
* SPDX-License-Identifier: Apache-2.0
*/
import { parseActions } from '@hap-toolkit/compiler'

export default function actionLoader(source) {
let jsonObj = {}
let actionStr = ''
try {
const obj = JSON.parse(source)
jsonObj = obj.actions || {}
const jsonObj = obj.actions || {}
const { parsed } = parseActions(jsonObj)
actionStr = parsed
} catch (e) {
throw new Error(`Invalid <data> in ${this.resourcePath}:: ${e}`)
throw new Error(`Invalid <data> in ${this.resourcePath}\n${e}`)
}
return `module.exports = ${JSON.stringify(jsonObj)}`
return `module.exports = ${actionStr}`
}
2 changes: 2 additions & 0 deletions packages/hap-packager/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"babel.tree.config.js"
],
"dependencies": {
"@aiot-toolkit/card-expression": "^1.0.8",
"@babel/core": "^7.9.6",
"@babel/generator": "^7.9.6",
"@babel/parser": "^7.9.6",
Expand All @@ -41,6 +42,7 @@
"@hap-toolkit/shared-utils": "1.9.14",
"@jayfate/path": "^0.0.13",
"babel-loader": "^8.1.0",
"flat": "^5.0.2",
"fs-extra": "^10.0.0",
"glob": "^7.1.6",
"hash-sum": "^1.0.2",
Expand Down
11 changes: 7 additions & 4 deletions packages/hap-packager/src/common/constant.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,18 @@ const LOADER_PATH_STYLE = {
type: 'styles'
}

const LOADER_PATH_TEMPLATE = {
path: '/template-loader.js',
type: 'template'
}

/**
* loader path
*/
const LOADER_INFO_LIST = [
LOADER_PATH_UX,
{
path: '/template-loader.js',
type: 'template'
},
LOADER_PATH_STYLE,
LOADER_PATH_TEMPLATE,
{
path: '/script-loader.js',
type: 'script'
Expand Down Expand Up @@ -75,5 +77,6 @@ export {
BUILD_INFO_FILE,
LOADER_PATH_UX,
LOADER_PATH_STYLE,
LOADER_PATH_TEMPLATE,
LOADER_INFO_LIST
}
2 changes: 0 additions & 2 deletions packages/hap-packager/src/common/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import crypto from 'crypto'
import { sync as resolveSync } from 'resolve'

import { colorconsole } from '@hap-toolkit/shared-utils'

Check warning on line 11 in packages/hap-packager/src/common/utils.js

View workflow job for this annotation

GitHub Actions / unit-test

'colorconsole' is defined but never used

Check warning on line 11 in packages/hap-packager/src/common/utils.js

View workflow job for this annotation

GitHub Actions / test-cov

'colorconsole' is defined but never used

/**
* 获取要使用 babel.config.js 的路径
Expand Down Expand Up @@ -204,8 +204,6 @@
const entry = manifest.router.entry
const entrySkFiles = getEntrySkeleton(skeletonConf, entry)
priorities.splice(5, 0, ...entrySkFiles, new RegExp(`^${entry}/$`), new RegExp(`^${entry}/.+`))
} else {
colorconsole.error(`manifest.json 中未配置入口页面 router.entry`)
}
return priorities
}
Expand Down
67 changes: 46 additions & 21 deletions packages/hap-packager/src/plugins/lite-card-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
import Compilation from 'webpack/lib/Compilation'
import path from 'path'
import { getLastLoaderPath, calcDataDigest } from '../common/utils'
import { LOADER_INFO_LIST, LOADER_PATH_UX, LOADER_PATH_STYLE } from '../common/constant'
import {
LOADER_INFO_LIST,
LOADER_PATH_UX,
LOADER_PATH_STYLE,
LOADER_PATH_TEMPLATE
} from '../common/constant'
import { postHandleLiteCardRes } from '../post-handler'

const SUFFIX_UX = '.ux'
const CARD_ENTRY = '#entry'
Expand Down Expand Up @@ -59,7 +65,8 @@ class LiteCardPlugin {
pathSrc,
bundleFilePath
)
compilation.assets[templateFileName] = new ConcatSource(JSON.stringify(liteCardRes))
const templateJsonStr = postHandleLiteCardRes(liteCardRes)
compilation.assets[templateFileName] = new ConcatSource(templateJsonStr)
compilation.assets[cssFileName] = new ConcatSource(JSON.stringify(styleRes))
}
}
Expand Down Expand Up @@ -156,11 +163,18 @@ class LiteCardPlugin {
} else if (typeArr.includes(type)) {
if (type === LOADER_PATH_STYLE.type) {
// styles
const styleObjId = this.genStyleObjectId(compPath, styleRes)
const styleObjId = getStyleObjectId(compPath)
styleRes[styleObjId] = obj
isCardRes
? (currCompRes[CARD_ENTRY][STYLE_OBJECT_ID] = styleObjId)
: (currCompRes[STYLE_OBJECT_ID] = styleObjId)
} else if (type === LOADER_PATH_TEMPLATE.type) {
// template
const styleObjId = getStyleObjectId(compPath)
if (isCardRes) {
currCompRes[CARD_ENTRY][type] = obj
currCompRes[CARD_ENTRY][type][STYLE_OBJECT_ID] = styleObjId
} else {
currCompRes[type] = obj
currCompRes[type][STYLE_OBJECT_ID] = styleObjId
}
} else {
isCardRes ? (currCompRes[CARD_ENTRY][type] = obj) : (currCompRes[type] = obj)
}
Expand All @@ -171,21 +185,6 @@ class LiteCardPlugin {
}
}

genStyleObjectId(compPath, styleRes) {
const digest = calcDataDigest(Buffer.from(compPath, 'utf-8'))
const digestStr = digest.toString('hex')
const len = Math.min(6, digestStr.length)
let res = compPath
for (let i = len; i < digestStr.length; i++) {
res = digestStr.substring(0, i)
if (styleRes[res]) {
continue
}
break
}
return res
}

getComponentName(reqPath, pathSrc) {
if (!reqPath) {
return {}
Expand Down Expand Up @@ -262,4 +261,30 @@ class LiteCardPlugin {
}
}

const componentIdMap = new Map()
const componentPathMap = new Map()
function getStyleObjectId(compPath) {
if (!componentPathMap.get(compPath)) {
const compId = getHash(compPath)
componentIdMap.set(compId, compPath)
componentPathMap.set(compPath, compId)
}
return componentPathMap.get(compPath)
}

function getHash(compPath) {
const digest = calcDataDigest(Buffer.from(compPath, 'utf-8'))
const digestStr = digest.toString('hex')
const len = Math.min(6, digestStr.length)
let res = compPath
for (let i = len; i < digestStr.length; i++) {
res = digestStr.substring(0, i)
if (componentIdMap.has(res)) {
continue
}
break
}
return res
}

export { LiteCardPlugin }
11 changes: 8 additions & 3 deletions packages/hap-packager/src/plugins/resource-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import flatten from 'flat'
import path from 'path'
import fs from 'fs-extra'
import aaptjs from '@hap-toolkit/aaptjs'
Expand Down Expand Up @@ -122,21 +123,25 @@ function minifyWidgetI18nJSONFiles(targetDir) {
let arr = []
for (let key in widgetsOption) {
const widgetPath = widgetsOption[key].path
const isLite = widgetsOption[key].type === 'lite'
const dir = path.join(targetDir, widgetPath, 'i18n')
if (fs.existsSync(dir)) {
const jsonFiles = getFiles('*.json', dir)
jsonFiles.forEach((filePath) => {
arr.push(filePath)
minifyJson(filePath, filePath)
minifyJson(filePath, filePath, isLite)
})
}
}
}

function minifyJson(source, target) {
function minifyJson(source, target, isLite) {
try {
const contentStr = fs.readFileSync(source, 'utf8')
const content = JSON.parse(contentStr)
let content = JSON.parse(contentStr)
if (isLite) {
content = flatten.flatten(content)
}
const minifiedContent = JSON.stringify(content)
fs.writeFileSync(target, minifiedContent)
} catch (err) {
Expand Down
Loading
Loading