Skip to content

Commit 2a6f24c

Browse files
committed
feat(alita): 配合WatchModuleUpdatedPlugin 监听到的模块更新,更新对应的小程序组件文件
1 parent 3e55be2 commit 2a6f24c

File tree

5 files changed

+432
-0
lines changed

5 files changed

+432
-0
lines changed
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import configure from "../configure";
2+
import * as path from "path";
3+
4+
5+
export const handleChanged = (info, finalJSPath) => {
6+
const newWxOutFiles = {}
7+
8+
const {outComp, isPageComp} = info.RFInfo
9+
10+
11+
let outCompCode = `Component(wx.__bridge.WxNormalComp())`
12+
13+
let renderCode
14+
if (isPageComp) {
15+
const projectRelativePath = finalJSPath
16+
.replace(configure.outputFullpath + path.sep, '')
17+
.replace('.js', '')
18+
.replace(/\\/g, '/') // win 平台
19+
20+
const pageCompPath = configure.configObj.subDir.endsWith('/') ? configure.configObj.subDir + projectRelativePath : configure.configObj.subDir + '/' + projectRelativePath
21+
renderCode = `Component(wx.__bridge.WxNormalComp("${pageCompPath}"))`
22+
} else {
23+
renderCode = outCompCode
24+
}
25+
26+
for(let i = 0; i < outComp.length; i++) {
27+
const name = outComp[i]
28+
29+
const jspath = (name === 'render' ? finalJSPath : finalJSPath.replace('.js', `${name}.js`))
30+
const jscode = (name === 'render' ? renderCode : outCompCode)
31+
32+
newWxOutFiles[jspath] = jscode
33+
}
34+
35+
return newWxOutFiles
36+
}
+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import * as path from "path";
2+
3+
import {getModuleInfo} from '../util/cacheModuleInfos'
4+
import {getLibPath, judgeLibPath} from "../util/util"
5+
import configure from "../configure";
6+
import {compInfos} from "../util/getAndStorecompInfos";
7+
8+
9+
10+
export const handleChanged = (module, info, finalJSPath) => {
11+
12+
const newWxOutFiles = {}
13+
const {json, outComp} = info.RFInfo
14+
15+
const renderUsingComponents = getUsedCompPaths(module)
16+
17+
for(let i = 0; i < outComp.length; i ++) {
18+
const name = outComp[i]
19+
if (name === 'render') {
20+
continue
21+
} else {
22+
renderUsingComponents[name] = path.basename(finalJSPath).replace('.js', `${name}`)
23+
}
24+
}
25+
26+
27+
const renderJSON = {
28+
...json,
29+
usingComponents: renderUsingComponents
30+
}
31+
32+
let renderJSONStr = JSON.stringify(renderJSON, null, '\t')
33+
34+
for(let i = 0; i < outComp.length; i ++) {
35+
const name = outComp[i]
36+
37+
const comppath = (name === 'render' ? finalJSPath.replace('.js', `.json`) : finalJSPath.replace('.js', `${name}.json`))
38+
newWxOutFiles[comppath] = renderJSONStr
39+
}
40+
41+
return newWxOutFiles
42+
}
43+
44+
45+
46+
function getUsedCompPaths(module) {
47+
48+
const info = getModuleInfo(module)
49+
50+
const usedComps = {}
51+
52+
info.JSXElements.forEach(element => {
53+
54+
if (!info.im[element]) {
55+
//TODO 配合移除 "单文件单组件"
56+
usedComps[element] = `./${element}`
57+
return
58+
}
59+
60+
const source = info.im[element].source
61+
if (isRnBaseSkipEle(element, source)) {
62+
return
63+
}
64+
65+
const elementKey = source === 'react-native' ? `WX${element}` : element
66+
usedComps[elementKey] = getFinalPath(element, source, module, info)
67+
})
68+
69+
return usedComps
70+
}
71+
72+
function isRnBaseSkipEle(element, source) {
73+
74+
if (source === 'react-native' && (
75+
element === 'View'
76+
|| element === 'Text'
77+
|| element === 'TouchableWithoutFeedback'
78+
|| element === 'TouchableOpacity'
79+
|| element === 'TouchableHighlight'
80+
|| element === 'Image'
81+
)) {
82+
return true
83+
}
84+
85+
if (source === '@areslabs/wx-animated' && (
86+
element === 'AnimatedView'
87+
|| element === 'AnimatedImage'
88+
|| element === 'AnimatedText'
89+
)) {
90+
return true
91+
}
92+
93+
return false
94+
}
95+
96+
97+
function getFinalPath(element, source, module, info) {
98+
if (source === 'react-native') {
99+
return compInfos[source][`WX${element}`]
100+
}
101+
102+
// import {xx} from 'xx'
103+
if (judgeLibPath(source) && source === getLibPath(source) && compInfos[source][element]) {
104+
return compInfos[source][element]
105+
}
106+
107+
const absolutePath = info.deps[source] //syncResolve(path.dirname(filepath), source)
108+
109+
return deepSeekPath(element, absolutePath, module)
110+
}
111+
112+
113+
function deepSeekPath(element, absolutePath, module) {
114+
115+
let info = getModuleInfo(absolutePath)
116+
let im = info.im
117+
118+
while (im[element]) {
119+
const source = im[element].source
120+
absolutePath = info.deps[source]
121+
info = getModuleInfo(absolutePath)
122+
im = info.im
123+
}
124+
125+
return shortPath(absolutePath, module)
126+
}
127+
128+
function shortPath(ao, module) {
129+
const aoArr = ao.split(path.sep)
130+
const filepathArr = path.dirname(module).split(path.sep)
131+
132+
var i = 0
133+
while (filepathArr[i] === aoArr[i]) {
134+
i ++
135+
}
136+
137+
const backPath = filepathArr.slice(i).map(() => '..').join('/')
138+
const toPath = aoArr.slice(i).join('/')
139+
140+
const relativePath = `${backPath || '.'}/${toPath}`
141+
142+
const absolutePath = ao.replace(configure.inputFullpath, '')
143+
.replace('node_modules', 'npm')
144+
145+
const shortPath = relativePath.length > absolutePath.length ? absolutePath : relativePath
146+
147+
const extname = path.extname(shortPath)
148+
149+
// remove ext
150+
return shortPath.replace(`.wx${extname}`, '')
151+
.replace(extname, '')
152+
}
153+
154+
155+
+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import {getRootPathPrefix, miscNameToJSName, wxCompoutPath} from "../util/util"
2+
import * as nodepath from "path";
3+
import * as t from "@babel/types";
4+
import traverse from "@babel/traverse";
5+
import {geneReactCode} from "../util/uast";
6+
7+
8+
export const handleChanged = (info, finalJSPath) => {
9+
const newWxOutFiles = {}
10+
11+
12+
const { templates, outComp, childTemplates} = info.RFInfo;
13+
14+
const newTemp = [];
15+
for (let i = 0; i < templates.length; i++) {
16+
newTemp.push(t.jsxText("\n "));
17+
newTemp.push(templates[i]);
18+
newTemp.push(t.jsxText("\n "));
19+
}
20+
newTemp.push(t.jsxText("\n "));
21+
22+
23+
const ast = t.jsxElement(
24+
t.jsxOpeningElement(
25+
t.jsxIdentifier("InnerTmpOpeningElement"),
26+
[]
27+
),
28+
t.jsxClosingElement(t.jsxIdentifier("InnerTmpOpeningElement")),
29+
newTemp,
30+
false
31+
);
32+
33+
const past = t.program([
34+
t.expressionStatement(ast)
35+
]);
36+
37+
traverse(past, {
38+
exit: path => {
39+
if (path.type === "JSXExpressionContainer"
40+
&& (path.node as t.JSXExpressionContainer).expression.type === "JSXEmptyExpression"
41+
) {
42+
path.remove();
43+
return;
44+
}
45+
}
46+
});
47+
48+
49+
let templateWxml = geneReactCode(ast);
50+
templateWxml = templateWxml.replace("<InnerTmpOpeningElement>", "");
51+
templateWxml = templateWxml.replace("</InnerTmpOpeningElement>", "");
52+
53+
for (let i = 0; i < childTemplates.length; i++) {
54+
const name = childTemplates[i];
55+
// 如果只使用一个child 小程序会报递归, 然后就不渲染了
56+
const subT = `
57+
<template name="${name}">
58+
<block wx:if="{{t.l(d)}}">{{d}}</block>
59+
<template wx:elif="{{d.tempName}}" is="{{d.tempName}}" data="{{...d}}"/>
60+
<block wx:else>
61+
<block wx:for="{{d}}" wx:key="key">
62+
<block wx:if="{{t.l(item)}}">{{item}}</block>
63+
<template wx:else is="{{item.tempName}}" data="{{...item}}"/>
64+
</block>
65+
</block>
66+
</template>
67+
`;
68+
69+
templateWxml = subT + templateWxml;
70+
}
71+
72+
73+
const utilWxsPath = getRootPathPrefix(finalJSPath) + '/commonwxs.wxs'
74+
75+
templateWxml = `<wxs src="${utilWxsPath}" module="t" />
76+
${templateWxml}
77+
`
78+
79+
newWxOutFiles[`${finalJSPath.replace(".js", "Template.wxml")}`] = templateWxml
80+
81+
82+
// gene all outComp
83+
geneAllOutComp(outComp, finalJSPath, newWxOutFiles);
84+
85+
86+
return newWxOutFiles
87+
}
88+
89+
90+
function geneAllOutComp(outComp, finalJSPath, newWxOutFiles) {
91+
const basename = nodepath.basename(finalJSPath);
92+
const temppath = basename.replace(".js", "Template.wxml");
93+
94+
for (let i = 0; i < outComp.length; i++) {
95+
const name = outComp[i];
96+
97+
const wxmlFilepath = (name === "render"
98+
? finalJSPath.replace(".js", ".wxml")
99+
: finalJSPath.replace(".js", `${name}.wxml`)
100+
);
101+
102+
const wxmlAst = [];
103+
wxmlAst.push(t.jsxText(`<import src="./${temppath}"/>`))
104+
wxmlAst.push(t.jsxText("\n"));
105+
wxmlAst.push(t.jsxText(`<template wx:if="{{(_r && _r.tempName)}}" is="{{_r.tempName}}" data="{{..._r}}"/>`))
106+
let tmpWxmlAst = t.jsxElement(
107+
t.jsxOpeningElement(
108+
t.jsxIdentifier("InnerTmpOpeningElement"),
109+
[]
110+
),
111+
t.jsxClosingElement(t.jsxIdentifier("InnerTmpOpeningElement")),
112+
wxmlAst,
113+
false
114+
);
115+
116+
let WXMLCode = geneReactCode(tmpWxmlAst);
117+
WXMLCode = WXMLCode.replace("<InnerTmpOpeningElement>", "");
118+
WXMLCode = WXMLCode.replace("</InnerTmpOpeningElement>", "");
119+
120+
121+
newWxOutFiles[wxmlFilepath] = WXMLCode
122+
}
123+
}
124+
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import {getModuleInfo} from '../util/cacheModuleInfos'
2+
import {getRootPathPrefix, miscNameToJSName} from "../util/util"
3+
4+
5+
export const handleChanged = (info, finalJSPath) => {
6+
const newWxOutFiles = {}
7+
8+
const {isPageComp, outComp} = info.RFInfo
9+
10+
for (let i = 0; i < outComp.length; i++) {
11+
const name = outComp[i];
12+
13+
const wxssFilepath = (name === "render"
14+
? finalJSPath.replace(".js", ".wxss")
15+
: finalJSPath.replace(".js", `${name}.wxss`)
16+
);
17+
18+
const pageCommonPath = getRootPathPrefix(finalJSPath) + "/pageCommon.wxss"
19+
const compCommonPath = getRootPathPrefix(finalJSPath) + "/compCommon.wxss"
20+
21+
let wxssCode = null
22+
if (name === 'render' && isPageComp) {
23+
wxssCode = `@import '${pageCommonPath}';
24+
@import '${compCommonPath}';`
25+
} else {
26+
wxssCode = `@import '${compCommonPath}';`
27+
}
28+
29+
30+
newWxOutFiles[wxssFilepath] = wxssCode
31+
}
32+
33+
34+
35+
return newWxOutFiles
36+
}

0 commit comments

Comments
 (0)