Skip to content

Commit 2cf788c

Browse files
committed
fix: 🐛 解决出码缺乏对于 i18n 数据的 params 的处理的问题
alibaba#288Closes: alibaba#288
1 parent 57657fd commit 2cf788c

File tree

93 files changed

+2552
-591
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+2552
-591
lines changed

modules/code-generator/jest.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ module.exports = {
66
collectCoverage: false,
77
collectCoverageFrom: ['src/**/*.{ts,tsx}', '!**/node_modules/**', '!**/vendor/**'],
88
testMatch: ['<rootDir>/tests/**/*.test.ts'],
9+
setupFiles: ['./jest.setup.js'],
910
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// 对于 standalone 模式的专门 polyfills
2+
if (process.env.TEST_TARGET === 'standalone') {
3+
// 模拟浏览器环境
4+
global.window = global;
5+
global.self = global;
6+
7+
// 将所有测试用例里面的 './src' 都替换为 './dist/standalone'
8+
jest.mock('./src', () => require('./dist/standalone'));
9+
}
10+
11+
// 如果在调试模式下,则不限制超时时间
12+
jest.setTimeout(typeof v8debug === 'object' ? Infinity : 30 * 1000);

modules/code-generator/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
"lodash-es": "^4.17.21",
8686
"mock-fs": "^5.1.2",
8787
"moment": "^2.29.1",
88+
"nanomatch": "^1.2.13",
8889
"node-fetch": "2.x",
8990
"path-browserify": "^1.0.1",
9091
"prettier": "^2.5.1",
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/usr/bin/env node
2+
3+
// @ts-check
4+
const program = require('commander');
5+
const { spawnSync } = require('child_process');
6+
const glob = require('glob');
7+
const fs = require('fs');
8+
const path = require('path');
9+
const _ = require('lodash');
10+
11+
program
12+
.option('--npm <npm>', 'specify the npm command location or alias')
13+
.arguments('<project>')
14+
.action((project, options) => {
15+
try {
16+
if (!fs.existsSync(project)) {
17+
throw new Error(`Project ${project} does not exist`);
18+
}
19+
20+
const getProjectActualPath = [
21+
() => path.resolve(process.cwd(), project),
22+
() =>
23+
path.resolve(
24+
process.cwd(),
25+
path.join(
26+
project,
27+
path.dirname(glob.sync('*/package.json', { cwd: project })[0] || ''),
28+
),
29+
),
30+
]
31+
.map((x) => _.memoize(x))
32+
.find((x) => fs.existsSync(path.join(x(), 'package.json')));
33+
34+
if (!getProjectActualPath) {
35+
throw new Error(`Project ${project} is not a valid project(no package.json)`);
36+
}
37+
38+
const projectActualPath = getProjectActualPath();
39+
if (path.resolve(process.cwd(), project) !== projectActualPath) {
40+
console.log('Changing directory to', path.relative(process.cwd(), projectActualPath));
41+
}
42+
43+
process.chdir(projectActualPath);
44+
45+
const npm = options.npm || 'npm';
46+
const cmd = `${npm} install && ${npm} start`;
47+
console.log('# %s', cmd);
48+
spawnSync(cmd, { stdio: 'inherit', shell: true });
49+
} catch (err) {
50+
console.log(err);
51+
process.exit(1);
52+
}
53+
});
54+
55+
program.parse(process.argv);

modules/code-generator/src/cli/solutions/example-solution.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,7 @@ export default function createHelloWorldProjectBuilder() {
638638
CodeGen.plugins.react.reactCommonDeps(),
639639
CodeGen.plugins.common.esmodule({ fileType: 'jsx' }),
640640
CodeGen.plugins.react.containerClass(),
641+
CodeGen.plugins.react.containerInjectContext(),
641642
CodeGen.plugins.react.containerInjectUtils(),
642643
CodeGen.plugins.react.containerInjectDataSourceEngine(),
643644
CodeGen.plugins.react.containerInjectI18n(),
@@ -659,6 +660,7 @@ export default function createHelloWorldProjectBuilder() {
659660
CodeGen.plugins.react.reactCommonDeps(),
660661
CodeGen.plugins.common.esmodule({ fileType: 'jsx' }),
661662
CodeGen.plugins.react.containerClass(),
663+
CodeGen.plugins.react.containerInjectContext(),
662664
CodeGen.plugins.react.containerInjectUtils(),
663665
CodeGen.plugins.react.containerInjectDataSourceEngine(),
664666
CodeGen.plugins.react.containerInjectI18n(),

modules/code-generator/src/generator/ModuleBuilder.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
CodeGeneratorError,
66
ICodeChunk,
77
ICompiledModule,
8+
IContextData,
89
IModuleBuilder,
910
IParseResult,
1011
ISchemaParser,
@@ -23,6 +24,7 @@ export function createModuleBuilder(
2324
plugins: BuilderComponentPlugin[];
2425
postProcessors: PostProcessor[];
2526
mainFileName?: string;
27+
contextData?: IContextData;
2628
} = {
2729
plugins: [],
2830
postProcessors: [],
@@ -41,7 +43,13 @@ export function createModuleBuilder(
4143

4244
let files: ResultFile[] = [];
4345

44-
const { chunks } = await chunkGenerator.run(input);
46+
const { chunks } = await chunkGenerator.run(input, {
47+
ir: input,
48+
chunks: [],
49+
depNames: [],
50+
contextData: options.contextData || {},
51+
});
52+
4553
chunks.forEach((fileChunkList) => {
4654
const content = linker.link(fileChunkList);
4755
const file = createResultFile(

modules/code-generator/src/generator/ProjectBuilder.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { SchemaParser } from '../parser/SchemaParser';
1414
import { createResultDir, addDirectory, addFile } from '../utils/resultHelper';
1515

1616
import { createModuleBuilder } from './ModuleBuilder';
17-
import { ProjectPreProcessor, ProjectPostProcessor } from '../types/core';
17+
import { ProjectPreProcessor, ProjectPostProcessor, IContextData } from '../types/core';
1818
import { CodeGeneratorError } from '../types/error';
1919

2020
interface IModuleInfo {
@@ -36,6 +36,10 @@ export interface ProjectBuilderInitOptions {
3636
projectPreProcessors?: ProjectPreProcessor[];
3737
/** 项目级别的后置处理器 */
3838
projectPostProcessors?: ProjectPostProcessor[];
39+
/** 是否处于严格模式 */
40+
inStrictMode?: boolean;
41+
/** 一些额外的上下文数据 */
42+
extraContextData?: Record<string, unknown>;
3943
}
4044

4145
export class ProjectBuilder implements IProjectBuilder {
@@ -57,20 +61,30 @@ export class ProjectBuilder implements IProjectBuilder {
5761
/** 项目级别的后置处理器 */
5862
private projectPostProcessors: ProjectPostProcessor[];
5963

64+
/** 是否处于严格模式 */
65+
public readonly inStrictMode: boolean;
66+
67+
/** 一些额外的上下文数据 */
68+
public readonly extraContextData: IContextData;
69+
6070
constructor({
6171
template,
6272
plugins,
6373
postProcessors,
6474
schemaParser = new SchemaParser(),
6575
projectPreProcessors = [],
6676
projectPostProcessors = [],
77+
inStrictMode = false,
78+
extraContextData = {},
6779
}: ProjectBuilderInitOptions) {
6880
this.template = template;
6981
this.plugins = plugins;
7082
this.postProcessors = postProcessors;
7183
this.schemaParser = schemaParser;
7284
this.projectPreProcessors = projectPreProcessors;
7385
this.projectPostProcessors = projectPostProcessors;
86+
this.inStrictMode = inStrictMode;
87+
this.extraContextData = extraContextData;
7488
}
7589

7690
async generateProject(originalSchema: ProjectSchema | string): Promise<ResultDir> {
@@ -264,6 +278,10 @@ export class ProjectBuilder implements IProjectBuilder {
264278
builders[pluginName] = createModuleBuilder({
265279
plugins: this.plugins[pluginName],
266280
postProcessors: this.postProcessors,
281+
contextData: {
282+
inStrictMode: this.inStrictMode,
283+
...this.extraContextData,
284+
},
267285
...options,
268286
});
269287
}

modules/code-generator/src/index.ts

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,8 @@ import i18n from './plugins/project/i18n';
2525
import utils from './plugins/project/utils';
2626
import prettier from './postprocessor/prettier';
2727

28-
// 引入常用工具
29-
import * as utilsCommon from './utils/common';
30-
import * as utilsCompositeType from './utils/compositeType';
31-
import * as utilsJsExpression from './utils/jsExpression';
32-
import * as utilsJsSlot from './utils/jsSlot';
33-
import * as utilsNodeToJSX from './utils/nodeToJSX';
34-
import * as utilsResultHelper from './utils/resultHelper';
35-
import * as utilsTemplateHelper from './utils/templateHelper';
36-
import * as utilsValidate from './utils/validate';
37-
import * as utilsSchema from './utils/schema';
28+
// 引入全局常用工具
29+
import * as globalUtils from './utils';
3830

3931
import * as CONSTANTS from './const';
4032

@@ -85,17 +77,7 @@ export default {
8577
postprocessor: {
8678
prettier,
8779
},
88-
utils: {
89-
common: utilsCommon,
90-
compositeType: utilsCompositeType,
91-
jsExpression: utilsJsExpression,
92-
jsSlot: utilsJsSlot,
93-
nodeToJSX: utilsNodeToJSX,
94-
resultHelper: utilsResultHelper,
95-
templateHelper: utilsTemplateHelper,
96-
validate: utilsValidate,
97-
schema: utilsSchema,
98-
},
80+
utils: globalUtils,
9981
chunkNames: {
10082
COMMON_CHUNK_NAME,
10183
CLASS_DEFINE_CHUNK_NAME,

modules/code-generator/src/plugins/component/rax/containerClass.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -134,19 +134,6 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
134134
],
135135
});
136136

137-
next.chunks.push({
138-
type: ChunkType.STRING,
139-
fileType: FileType.JSX,
140-
name: CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod,
141-
content: `
142-
_i18nText(t) {
143-
const locale = this._context.getLocale();
144-
return t[locale] ?? t[String(locale).replace('-', '_')] ?? t[t.use || 'zh_CN'] ?? t.en_US;
145-
}
146-
`,
147-
linkAfter: [RAX_CHUNK_NAME.ClassRenderEnd],
148-
});
149-
150137
next.chunks.push({
151138
type: ChunkType.STRING,
152139
fileType: FileType.JSX,

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

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

1415
export interface PluginConfig {
1516
fileType: string;
@@ -46,6 +47,16 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
4647
linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport],
4748
});
4849

50+
next.chunks.push({
51+
type: ChunkType.STRING,
52+
fileType: cfg.fileType,
53+
name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
54+
content: `
55+
__$$i18n._inject2(this);
56+
`,
57+
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.ConstructorContent]],
58+
});
59+
4960
next.chunks.push({
5061
type: ChunkType.STRING,
5162
fileType: cfg.fileType,

0 commit comments

Comments
 (0)