Skip to content

Commit b1a6100

Browse files
committed
fix: 修正 react 框架出码中在严格模式对 methods 和 context 的处理
1 parent 2cf788c commit b1a6100

File tree

3 files changed

+71
-15
lines changed

3 files changed

+71
-15
lines changed

modules/code-generator/src/plugins/component/react/containerInjectContext.ts

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
ICodeStruct,
1111
IContainerInfo,
1212
} from '../../../types';
13+
import { DEFAULT_LINK_AFTER } from '../../../const';
1314

1415
export interface PluginConfig {
1516
fileType: string;
@@ -30,28 +31,56 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
3031
const scope = Scope.createRootScope();
3132

3233
const { inStrictMode } = next.contextData;
33-
if (inStrictMode) {
34+
if (!inStrictMode) {
35+
// 非严格模式下,上下文就是自己
3436
next.chunks.push({
3537
type: ChunkType.STRING,
3638
fileType: cfg.fileType,
3739
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
3840
content: `
39-
_context = this._createContext();
41+
_context = this;
4042
`,
4143
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
4244
});
43-
// TODO: createContext......
4445
} else {
45-
// 非严格模式下,上下文就是自己
46+
// 严格模式下的上下文只保留协议中规定的那些
4647
next.chunks.push({
4748
type: ChunkType.STRING,
4849
fileType: cfg.fileType,
4950
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
5051
content: `
51-
_context = this;
52+
_context = this._createContext();
5253
`,
5354
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
5455
});
56+
57+
next.chunks.push({
58+
type: ChunkType.STRING,
59+
fileType: cfg.fileType,
60+
name: CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod,
61+
content: `
62+
_createContext() {
63+
const self = this;
64+
const context = {
65+
get state() { return self.state; },
66+
setState(newState, callback) { self.setState(newState, callback); },
67+
get dataSourceMap() { return self._dataSourceEngine.dataSourceMap || {}; },
68+
async reloadDataSource() { await self._dataSourceEngine.reloadDataSource(); },
69+
get utils() { return self.utils; },
70+
get page() { return context; },
71+
get component() { return context; },
72+
get props() { return self.props; },
73+
get constants() { return self.constants; },
74+
get $() { return self.$ },
75+
get $$() { return self.$$ },
76+
...this._methods,
77+
};
78+
79+
return context;
80+
}
81+
`,
82+
linkAfter: DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod],
83+
});
5584
}
5685

5786
return next;

modules/code-generator/src/plugins/component/react/containerMethod.ts

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
ICodeStruct,
1212
IContainerInfo,
1313
} from '../../../types';
14+
import { isValidIdentifier } from '../../../utils/validate';
1415

1516
export interface PluginConfig {
1617
fileType: string;
@@ -28,18 +29,37 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
2829
};
2930

3031
const ir = next.ir as IContainerInfo;
32+
const { inStrictMode } = next.contextData;
3133

32-
if (ir.methods) {
33-
const { methods } = ir;
34-
const chunks = Object.keys(methods).map<ICodeChunk>((methodName) => ({
34+
if (!ir.methods) {
35+
return next;
36+
}
37+
38+
// 将这些 methods 都定义到 class 上
39+
const { methods } = ir;
40+
const chunks = Object.keys(methods).map<ICodeChunk>((methodName) => ({
41+
type: ChunkType.STRING,
42+
fileType: cfg.fileType,
43+
name: CLASS_DEFINE_CHUNK_NAME.InsMethod,
44+
content: generateFunction(methods[methodName], { name: methodName, isMember: true }),
45+
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]],
46+
}));
47+
next.chunks.push(...chunks);
48+
49+
// 严格模式下需要将这些方法都挂到上下文中
50+
if (inStrictMode) {
51+
next.chunks.push({
3552
type: ChunkType.STRING,
3653
fileType: cfg.fileType,
37-
name: CLASS_DEFINE_CHUNK_NAME.InsMethod,
38-
content: generateFunction(methods[methodName], { name: methodName, isMember: true }),
39-
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]],
40-
}));
41-
42-
next.chunks.push(...chunks);
54+
name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
55+
content: Object.keys(ir.methods)
56+
.map((methodName) =>
57+
isValidIdentifier(methodName) ? `.${methodName}` : `[${JSON.stringify(methodName)}]`,
58+
)
59+
.map((method) => `this._context${method} = this${method};`)
60+
.join('\n'),
61+
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.ConstructorContent]],
62+
});
4363
}
4464

4565
return next;

modules/code-generator/src/solutions/icejs.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,15 @@ import icejs from '../plugins/project/framework/icejs';
2222

2323
import { prettier } from '../postprocessor';
2424

25-
export default function createIceJsProjectBuilder(): IProjectBuilder {
25+
export type IceJsProjectBuilderOptions = {
26+
inStrictMode?: boolean;
27+
};
28+
29+
export default function createIceJsProjectBuilder(
30+
options?: IceJsProjectBuilderOptions,
31+
): IProjectBuilder {
2632
return createProjectBuilder({
33+
inStrictMode: options?.inStrictMode,
2734
template: icejs.template,
2835
plugins: {
2936
components: [

0 commit comments

Comments
 (0)