fix: 修正 react 框架出码中在严格模式对 methods 和 context 的处理

This commit is contained in:
Clarence-pan 2022-04-10 19:12:44 +08:00 committed by Clarence Pan
parent 2cf788c171
commit b1a61006bb
3 changed files with 78 additions and 22 deletions

View File

@ -10,6 +10,7 @@ import {
ICodeStruct,
IContainerInfo,
} from '../../../types';
import { DEFAULT_LINK_AFTER } from '../../../const';
export interface PluginConfig {
fileType: string;
@ -30,18 +31,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
const scope = Scope.createRootScope();
const { inStrictMode } = next.contextData;
if (inStrictMode) {
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
content: `
_context = this._createContext();
`,
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
});
// TODO: createContext......
} else {
if (!inStrictMode) {
// 非严格模式下,上下文就是自己
next.chunks.push({
type: ChunkType.STRING,
@ -52,6 +42,45 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
`,
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
});
} else {
// 严格模式下的上下文只保留协议中规定的那些
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
content: `
_context = this._createContext();
`,
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
});
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod,
content: `
_createContext() {
const self = this;
const context = {
get state() { return self.state; },
setState(newState, callback) { self.setState(newState, callback); },
get dataSourceMap() { return self._dataSourceEngine.dataSourceMap || {}; },
async reloadDataSource() { await self._dataSourceEngine.reloadDataSource(); },
get utils() { return self.utils; },
get page() { return context; },
get component() { return context; },
get props() { return self.props; },
get constants() { return self.constants; },
get $() { return self.$ },
get $$() { return self.$$ },
...this._methods,
};
return context;
}
`,
linkAfter: DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod],
});
}
return next;

View File

@ -11,6 +11,7 @@ import {
ICodeStruct,
IContainerInfo,
} from '../../../types';
import { isValidIdentifier } from '../../../utils/validate';
export interface PluginConfig {
fileType: string;
@ -28,18 +29,37 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
};
const ir = next.ir as IContainerInfo;
const { inStrictMode } = next.contextData;
if (ir.methods) {
const { methods } = ir;
const chunks = Object.keys(methods).map<ICodeChunk>((methodName) => ({
if (!ir.methods) {
return next;
}
// 将这些 methods 都定义到 class 上
const { methods } = ir;
const chunks = Object.keys(methods).map<ICodeChunk>((methodName) => ({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: CLASS_DEFINE_CHUNK_NAME.InsMethod,
content: generateFunction(methods[methodName], { name: methodName, isMember: true }),
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]],
}));
next.chunks.push(...chunks);
// 严格模式下需要将这些方法都挂到上下文中
if (inStrictMode) {
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: CLASS_DEFINE_CHUNK_NAME.InsMethod,
content: generateFunction(methods[methodName], { name: methodName, isMember: true }),
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]],
}));
next.chunks.push(...chunks);
name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
content: Object.keys(ir.methods)
.map((methodName) =>
isValidIdentifier(methodName) ? `.${methodName}` : `[${JSON.stringify(methodName)}]`,
)
.map((method) => `this._context${method} = this${method};`)
.join('\n'),
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.ConstructorContent]],
});
}
return next;

View File

@ -22,8 +22,15 @@ import icejs from '../plugins/project/framework/icejs';
import { prettier } from '../postprocessor';
export default function createIceJsProjectBuilder(): IProjectBuilder {
export type IceJsProjectBuilderOptions = {
inStrictMode?: boolean;
};
export default function createIceJsProjectBuilder(
options?: IceJsProjectBuilderOptions,
): IProjectBuilder {
return createProjectBuilder({
inStrictMode: options?.inStrictMode,
template: icejs.template,
plugins: {
components: [