(pre: ICodeStruct)
| 56 | }; |
| 57 | |
| 58 | const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => { |
| 59 | const next: ICodeStruct = { |
| 60 | ...pre, |
| 61 | }; |
| 62 | |
| 63 | const ir = next.ir as IContainerInfo; |
| 64 | const rootScope = Scope.createRootScope(); |
| 65 | const { tolerateEvalErrors = true, evalErrorsHandler = '' } = next.contextData; |
| 66 | |
| 67 | // Rax 构建到小程序的时候,不能给组件起起别名,得直接引用,故这里将所有的别名替换掉 |
| 68 | // 先收集下所有的 alias 的映射 |
| 69 | const componentsNameAliasMap = new Map<string, string>(); |
| 70 | next.chunks.forEach((chunk) => { |
| 71 | if (isImportAliasDefineChunk(chunk)) { |
| 72 | componentsNameAliasMap.set(chunk.ext.aliasName, chunk.ext.originalName); |
| 73 | } |
| 74 | }); |
| 75 | |
| 76 | // 注意:这里其实隐含了一个假设:schema 中的 componentName 应该是一个有效的 JS 标识符,而且是大写字母打头的 |
| 77 | // FIXME: 为了快速修复临时加的逻辑,需要用 pre-process 的方式替代处理。 |
| 78 | const mapComponentNameToAliasOrKeepIt = (componentName: string) => componentsNameAliasMap.get(componentName) || componentName; |
| 79 | |
| 80 | // 然后过滤掉所有的别名 chunks |
| 81 | next.chunks = next.chunks.filter((chunk) => !isImportAliasDefineChunk(chunk)); |
| 82 | |
| 83 | // 如果直接按目前的 React 的方式之间出码 JSX 的话,会有 3 个问题: |
| 84 | // 1. 小程序出码的时候,循环变量没法拿到 |
| 85 | // 2. 小程序出码的时候,很容易出现 Uncaught TypeError: Cannot read property 'avatar' of undefined 这样的异常(如下图的 50 行) -- 因为若直接出码,Rax 构建到小程序的时候会立即计算所有在视图中用到的变量 |
| 86 | // 3. 通过 this.xxx 能拿到的东西太多了,而且自定义的 methods 可能会无意间破坏 Rax 框架或小程序框架在页面 this 上的东东 |
| 87 | const customHandlers: HandlerSet<string> = { |
| 88 | expression(input: IPublicTypeJSExpression, scope: IScope) { |
| 89 | return transformJsExpr(generateExpression(input, scope), scope, { |
| 90 | dontWrapEval: !tolerateEvalErrors, |
| 91 | }); |
| 92 | }, |
| 93 | function(input, scope: IScope) { |
| 94 | return transformThis2Context(input.value || 'null', scope); |
| 95 | }, |
| 96 | }; |
| 97 | |
| 98 | // 创建代码生成器 |
| 99 | const commonNodeGenerator = createNodeGenerator({ |
| 100 | handlers: customHandlers, |
| 101 | tagMapping: mapComponentNameToAliasOrKeepIt, |
| 102 | nodePlugins: [generateReactExprInJS, generateConditionReactCtrl, generateRaxLoopCtrl], |
| 103 | attrPlugins: [generateNodeAttrForRax.bind({ cfg })], |
| 104 | }); |
| 105 | |
| 106 | // 生成 JSX 代码 |
| 107 | const jsxContent = commonNodeGenerator(ir, rootScope); |
| 108 | |
| 109 | if (!cfg.ignoreMiniApp) { |
| 110 | next.chunks.push({ |
| 111 | type: ChunkType.STRING, |
| 112 | fileType: cfg.fileType, |
| 113 | name: COMMON_CHUNK_NAME.ExternalDepsImport, |
| 114 | content: "import { isMiniApp as __$$isMiniApp } from 'universal-env';", |
| 115 | linkAfter: [], |
nothing calls this directly
no test coverage detected
searching dependent graphs…