@blocklet/pages-kit-block-studio 0.4.118 → 0.4.119
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/constants/index.js +2 -1
- package/lib/cjs/middlewares/init-resource-router.js +16 -0
- package/lib/cjs/middlewares/init-uploader-router.js +3 -0
- package/lib/cjs/plugins/vite-plugin-block-studio.js +4 -13
- package/lib/cjs/plugins/vite-plugin-code-splitter.js +341 -0
- package/lib/cjs/tsconfig.tsbuildinfo +1 -1
- package/lib/cjs/utils/helper.js +7 -1
- package/lib/esm/constants/index.js +1 -0
- package/lib/esm/middlewares/init-resource-router.js +17 -1
- package/lib/esm/middlewares/init-uploader-router.js +3 -0
- package/lib/esm/plugins/vite-plugin-block-studio.js +4 -13
- package/lib/esm/plugins/vite-plugin-code-splitter.js +335 -0
- package/lib/esm/tsconfig.tsbuildinfo +1 -1
- package/lib/esm/utils/helper.js +5 -0
- package/lib/types/constants/index.d.ts +1 -0
- package/lib/types/plugins/vite-plugin-block-studio.d.ts +1 -0
- package/lib/types/plugins/vite-plugin-code-splitter.d.ts +7 -0
- package/lib/types/tsconfig.tsbuildinfo +1 -1
- package/lib/types/utils/helper.d.ts +3 -0
- package/package.json +3 -3
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.PAGES_KIT_STATE_STATE_DIR = exports.IGNORE_WATCH_PREFIX = exports.DEFAULT_BLOCK_ENTRY_FILES_PATTERN = exports.NANOID_LENGTH = exports.PREVIEW_IMAGE_DIR = exports.METADATA_FILE_NAME = exports.libDir = exports.NEW_BLOCK_TEMPLATE_METADATA_PATH = exports.NEW_BLOCK_TEMPLATE_PATH = exports.MEDIA_KIT_RESOURCE_TYPE = exports.MEDIA_KIT_DID = exports.PAGES_KIT_BLOCK_STUDIO_RESOURCE_TYPE = exports.PAGES_KIT_BLOCK_STUDIO_DID = exports.PAGES_KIT_RESOURCE_TYPE = exports.PAGES_KIT_DID = void 0;
|
|
6
|
+
exports.PAGES_KIT_STATE_STATE_DIR = exports.IGNORE_WATCH_PREFIX = exports.DEFAULT_BLOCK_ENTRY_FILES_PATTERN = exports.NANOID_LENGTH = exports.EDIT_COMPONENT_FILE_NAME_REGEX = exports.PREVIEW_IMAGE_DIR = exports.METADATA_FILE_NAME = exports.libDir = exports.NEW_BLOCK_TEMPLATE_METADATA_PATH = exports.NEW_BLOCK_TEMPLATE_PATH = exports.MEDIA_KIT_RESOURCE_TYPE = exports.MEDIA_KIT_DID = exports.PAGES_KIT_BLOCK_STUDIO_RESOURCE_TYPE = exports.PAGES_KIT_BLOCK_STUDIO_DID = exports.PAGES_KIT_RESOURCE_TYPE = exports.PAGES_KIT_DID = void 0;
|
|
7
7
|
const path_1 = __importDefault(require("path"));
|
|
8
8
|
exports.PAGES_KIT_DID = 'z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o';
|
|
9
9
|
exports.PAGES_KIT_RESOURCE_TYPE = 'page';
|
|
@@ -16,6 +16,7 @@ exports.NEW_BLOCK_TEMPLATE_METADATA_PATH = path_1.default.join(__dirname, 'new-b
|
|
|
16
16
|
exports.libDir = 'lib';
|
|
17
17
|
exports.METADATA_FILE_NAME = '@metadata.json';
|
|
18
18
|
exports.PREVIEW_IMAGE_DIR = '@preview-images';
|
|
19
|
+
exports.EDIT_COMPONENT_FILE_NAME_REGEX = /@edit-component\.(ts|tsx|js|jsx)$/;
|
|
19
20
|
exports.NANOID_LENGTH = 16;
|
|
20
21
|
exports.DEFAULT_BLOCK_ENTRY_FILES_PATTERN = 'src/**/index.{ts,tsx}';
|
|
21
22
|
exports.IGNORE_WATCH_PREFIX = ['@del-*', '@tmp-*', '.*', 'staging', 'production', '@backup-*'];
|
|
@@ -44,6 +44,7 @@ const component_1 = require("@blocklet/sdk/lib/component");
|
|
|
44
44
|
const child_process_1 = require("child_process");
|
|
45
45
|
const express_1 = require("express");
|
|
46
46
|
const fs_1 = __importDefault(require("fs"));
|
|
47
|
+
const get_1 = __importDefault(require("lodash/get"));
|
|
47
48
|
const set_1 = __importDefault(require("lodash/set"));
|
|
48
49
|
const path_1 = __importStar(require("path"));
|
|
49
50
|
const helper_1 = require("../utils/helper");
|
|
@@ -141,6 +142,7 @@ exports.initResourceRouter.post('/', async (req, res) => {
|
|
|
141
142
|
FORCE_COLOR: '1',
|
|
142
143
|
BLOCK_FILTER: componentIds.join(','),
|
|
143
144
|
NODE_OPTIONS: '--max_old_space_size=16384',
|
|
145
|
+
NODE_ENV: 'production',
|
|
144
146
|
},
|
|
145
147
|
});
|
|
146
148
|
// save current build process
|
|
@@ -187,6 +189,20 @@ exports.initResourceRouter.post('/', async (req, res) => {
|
|
|
187
189
|
(0, set_1.default)(metadata, 'renderer.type', 'react-component');
|
|
188
190
|
(0, set_1.default)(metadata, 'renderer.chunks', chunksMap[jsName] || []);
|
|
189
191
|
}
|
|
192
|
+
// get edit component code
|
|
193
|
+
try {
|
|
194
|
+
const editComponentJsName = `${(0, helper_1.getEditComponentBlockName)(blockName)}.js`;
|
|
195
|
+
const editComponentCode = fs_1.default.readFileSync((0, path_1.join)(codeDir, editComponentJsName), 'utf8');
|
|
196
|
+
if (editComponentCode) {
|
|
197
|
+
// add edit component code
|
|
198
|
+
(0, set_1.default)(metadata, 'renderer.editComponent', editComponentCode);
|
|
199
|
+
// append edit component chunks
|
|
200
|
+
(0, set_1.default)(metadata, 'renderer.chunks', Array.from(new Set([...(0, get_1.default)(metadata, 'renderer.chunks', []), ...(chunksMap[editComponentJsName] || [])])));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
// ignore error
|
|
205
|
+
}
|
|
190
206
|
// write metadata to metadataPath
|
|
191
207
|
const metadataYmlPath = path_1.default.join(componentsDir, `${metadata.name || 'unnamed'}.${metadata.id}.yml`);
|
|
192
208
|
fs_1.default.writeFileSync(metadataYmlPath, (0, helper_1.generateYaml)(metadata));
|
|
@@ -95,4 +95,7 @@ exports.initUploaderRouter.use('/uploads', (0, uploader_server_1.initProxyToMedi
|
|
|
95
95
|
exports.initUploaderRouter.use('/chunks', dynamicResourceMiddleware, staticResourceMiddleware, (_req, res) => {
|
|
96
96
|
res.status(404).send('CHUNK NOT FOUND').end();
|
|
97
97
|
});
|
|
98
|
+
exports.initUploaderRouter.use('/.well-known/chunks', dynamicResourceMiddleware, staticResourceMiddleware, (_req, res) => {
|
|
99
|
+
res.status(404).send('CHUNK NOT FOUND').end();
|
|
100
|
+
});
|
|
98
101
|
exports.default = exports.initUploaderRouter;
|
|
@@ -55,6 +55,7 @@ const vite_plugin_css_injected_by_js_1 = __importDefault(require("vite-plugin-cs
|
|
|
55
55
|
const vite_plugin_node_polyfills_1 = require("vite-plugin-node-polyfills");
|
|
56
56
|
const vite_plugin_react_pages_1 = __importStar(require("vite-plugin-react-pages"));
|
|
57
57
|
const helper_1 = require("../utils/helper");
|
|
58
|
+
const vite_plugin_code_splitter_1 = require("./vite-plugin-code-splitter");
|
|
58
59
|
const vite_plugin_html_transform_1 = require("./vite-plugin-html-transform");
|
|
59
60
|
const vite_plugin_import_transform_1 = require("./vite-plugin-import-transform");
|
|
60
61
|
// const BUILTIN_MODULES_VAR = '__PAGES_KIT_BUILTIN_MODULES__';
|
|
@@ -115,6 +116,7 @@ function initBlockStudioPlugins(options) {
|
|
|
115
116
|
const workingDir = options?.cwd || process.cwd();
|
|
116
117
|
const entryFilesPattern = options?.entryFilesPattern || (0, helper_1.getBlockEntryFilesPattern)();
|
|
117
118
|
const transpileBuiltinModule = options?.transpileBuiltinModule ?? true;
|
|
119
|
+
const ignoreSplitEditComponent = options?.ignoreSplitEditComponent ?? false;
|
|
118
120
|
// 处理 blockExternals 参数
|
|
119
121
|
let externalMappings = defaultBlockExternals;
|
|
120
122
|
if (typeof options?.blockExternals === 'function') {
|
|
@@ -197,6 +199,7 @@ function initBlockStudioPlugins(options) {
|
|
|
197
199
|
async config(_config) {
|
|
198
200
|
const name = await Promise.resolve(`${`${workingDir}/package.json`}`).then(s => __importStar(require(s))).then((res) => res.name).catch(() => 'MyLib');
|
|
199
201
|
return {
|
|
202
|
+
mode: 'production',
|
|
200
203
|
resolve: {
|
|
201
204
|
alias: {
|
|
202
205
|
// crypto: 'crypto-browserify',
|
|
@@ -312,19 +315,7 @@ function initBlockStudioPlugins(options) {
|
|
|
312
315
|
}),
|
|
313
316
|
// initHtmlPreviewTransformPlugin(),
|
|
314
317
|
(0, vite_plugin_css_injected_by_js_1.default)(),
|
|
315
|
-
|
|
316
|
-
// typescript({
|
|
317
|
-
// declaration: true,
|
|
318
|
-
// emitDeclarationOnly: true,
|
|
319
|
-
// noForceEmit: true,
|
|
320
|
-
// declarationDir: path.resolve(workingDir, 'lib/types'),
|
|
321
|
-
// rootDir: path.resolve(workingDir),
|
|
322
|
-
// }),
|
|
323
|
-
// initRemoteScriptLocalizerPlugin({
|
|
324
|
-
// tempDir: 'temp/remote-scripts', // 可选,默认值
|
|
325
|
-
// maxConcurrent: 5, // 可选,默认值
|
|
326
|
-
// timeout: 30 * 1000, // 可选,默认值 30 秒
|
|
327
|
-
// }),
|
|
318
|
+
ignoreSplitEditComponent ? undefined : (0, vite_plugin_code_splitter_1.vitePluginCodeSplitter)(),
|
|
328
319
|
{
|
|
329
320
|
name: 'post-build-file-transpiler',
|
|
330
321
|
apply: 'build',
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.vitePluginCodeSplitter = vitePluginCodeSplitter;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
10
|
+
const constants_1 = require("../constants");
|
|
11
|
+
const helper_1 = require("../utils/helper");
|
|
12
|
+
/**
|
|
13
|
+
* 分析组件文件结构
|
|
14
|
+
* @param sourceFile TypeScript源文件
|
|
15
|
+
*/
|
|
16
|
+
function analyzeComponent(sourceFile) {
|
|
17
|
+
const result = {};
|
|
18
|
+
// 访问AST节点
|
|
19
|
+
function visit(node) {
|
|
20
|
+
// 找到默认导出
|
|
21
|
+
if (typescript_1.default.isExportAssignment(node)) {
|
|
22
|
+
result.defaultExport = {
|
|
23
|
+
pos: node.pos,
|
|
24
|
+
end: node.end,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
// 检查函数声明的默认导出
|
|
28
|
+
if (typescript_1.default.isFunctionDeclaration(node) && node.modifiers) {
|
|
29
|
+
const isExport = node.modifiers.some((m) => m.kind === typescript_1.default.SyntaxKind.ExportKeyword);
|
|
30
|
+
const isDefault = node.modifiers.some((m) => m.kind === typescript_1.default.SyntaxKind.DefaultKeyword);
|
|
31
|
+
if (isExport && isDefault) {
|
|
32
|
+
result.defaultExport = {
|
|
33
|
+
pos: node.pos,
|
|
34
|
+
end: node.end,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// 找到命名导出 - EditComponent
|
|
39
|
+
if (typescript_1.default.isVariableStatement(node) && node.modifiers?.some((m) => m.kind === typescript_1.default.SyntaxKind.ExportKeyword)) {
|
|
40
|
+
const { declarations } = node.declarationList;
|
|
41
|
+
for (const decl of declarations) {
|
|
42
|
+
if (typescript_1.default.isIdentifier(decl.name) && decl.name.text === helper_1.EDIT_COMPONENT_NAME) {
|
|
43
|
+
result.editComponent = {
|
|
44
|
+
pos: node.pos,
|
|
45
|
+
end: node.end,
|
|
46
|
+
};
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// 检查导出声明
|
|
52
|
+
if (typescript_1.default.isExportDeclaration(node) && node.exportClause) {
|
|
53
|
+
if (typescript_1.default.isNamedExports(node.exportClause)) {
|
|
54
|
+
const hasEditComponent = node.exportClause.elements.some((element) => typescript_1.default.isExportSpecifier(element) && element.name.text === helper_1.EDIT_COMPONENT_NAME);
|
|
55
|
+
if (hasEditComponent) {
|
|
56
|
+
result.editComponent = {
|
|
57
|
+
pos: node.pos,
|
|
58
|
+
end: node.end,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// 处理导出的箭头函数/函数表达式
|
|
64
|
+
if (typescript_1.default.isVariableStatement(node)) {
|
|
65
|
+
const { declarations } = node.declarationList;
|
|
66
|
+
for (const decl of declarations) {
|
|
67
|
+
if (typescript_1.default.isIdentifier(decl.name) && decl.name.text === helper_1.EDIT_COMPONENT_NAME) {
|
|
68
|
+
if (node.modifiers?.some((m) => m.kind === typescript_1.default.SyntaxKind.ExportKeyword)) {
|
|
69
|
+
result.editComponent = {
|
|
70
|
+
pos: node.pos,
|
|
71
|
+
end: node.end,
|
|
72
|
+
};
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// 递归处理所有子节点
|
|
79
|
+
typescript_1.default.forEachChild(node, visit);
|
|
80
|
+
}
|
|
81
|
+
// 开始遍历
|
|
82
|
+
visit(sourceFile);
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 转换代码,使用TypeScript编译器API
|
|
87
|
+
*/
|
|
88
|
+
function transformCode(code, renderType) {
|
|
89
|
+
// 创建源文件
|
|
90
|
+
const sourceFile = typescript_1.default.createSourceFile('temp.tsx', code, typescript_1.default.ScriptTarget.Latest, true);
|
|
91
|
+
// 分析源代码结构
|
|
92
|
+
const analysis = analyzeComponent(sourceFile);
|
|
93
|
+
if (renderType === 'view') {
|
|
94
|
+
// 移除 EditComponent
|
|
95
|
+
if (analysis.editComponent) {
|
|
96
|
+
// 根据位置替换为空内容
|
|
97
|
+
const beforeEdit = code.substring(0, analysis.editComponent.pos);
|
|
98
|
+
const afterEdit = code.substring(analysis.editComponent.end);
|
|
99
|
+
return beforeEdit + afterEdit;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else if (renderType === 'setting') {
|
|
103
|
+
// 移除或替换默认导出,直接导出EditComponent
|
|
104
|
+
if (analysis.defaultExport && analysis.editComponent) {
|
|
105
|
+
// 编辑模式,保持命名导出,但让EditComponent同时也作为默认导出
|
|
106
|
+
const defaultExport = `
|
|
107
|
+
// Export EditComponent as both named export and default
|
|
108
|
+
export { ${helper_1.EDIT_COMPONENT_NAME} as default };
|
|
109
|
+
`;
|
|
110
|
+
const beforeDefault = code.substring(0, analysis.defaultExport.pos);
|
|
111
|
+
const afterDefault = code.substring(analysis.defaultExport.end);
|
|
112
|
+
// 替换默认导出为EditComponent
|
|
113
|
+
return beforeDefault + defaultExport + afterDefault;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// 如果没有进行修改,返回原始代码
|
|
117
|
+
return code;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* 进一步增强版本:通过完整的AST转换
|
|
121
|
+
*/
|
|
122
|
+
function transformCodeWithPrinter(code, renderType) {
|
|
123
|
+
try {
|
|
124
|
+
// 创建源文件
|
|
125
|
+
const sourceFile = typescript_1.default.createSourceFile('temp.tsx', code, typescript_1.default.ScriptTarget.Latest, true);
|
|
126
|
+
// 创建转换器上下文
|
|
127
|
+
const transformerFactory = (context) => {
|
|
128
|
+
return (sourceFile) => {
|
|
129
|
+
// 访问并转换节点
|
|
130
|
+
const visitor = (node) => {
|
|
131
|
+
// view模式:移除EditComponent相关代码
|
|
132
|
+
if (renderType === 'view') {
|
|
133
|
+
// 移除 export const EditComponent 声明
|
|
134
|
+
if (typescript_1.default.isVariableStatement(node) && node.modifiers?.some((m) => m.kind === typescript_1.default.SyntaxKind.ExportKeyword)) {
|
|
135
|
+
const { declarations } = node.declarationList;
|
|
136
|
+
if (declarations.some((d) => typescript_1.default.isIdentifier(d.name) && d.name.text === helper_1.EDIT_COMPONENT_NAME)) {
|
|
137
|
+
return typescript_1.default.factory.createEmptyStatement();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// 移除 export { EditComponent } 形式的导出
|
|
141
|
+
if (typescript_1.default.isExportDeclaration(node) && node.exportClause && typescript_1.default.isNamedExports(node.exportClause)) {
|
|
142
|
+
const { elements } = node.exportClause;
|
|
143
|
+
if (elements.some((e) => typescript_1.default.isExportSpecifier(e) && e.name.text === helper_1.EDIT_COMPONENT_NAME)) {
|
|
144
|
+
// 如果只有EditComponent一个导出,就完全移除
|
|
145
|
+
if (elements.length === 1) {
|
|
146
|
+
return typescript_1.default.factory.createEmptyStatement();
|
|
147
|
+
}
|
|
148
|
+
// 否则创建新的导出声明,但不包含EditComponent
|
|
149
|
+
const newElements = elements.filter((e) => !(typescript_1.default.isExportSpecifier(e) && e.name.text === helper_1.EDIT_COMPONENT_NAME));
|
|
150
|
+
return typescript_1.default.factory.createExportDeclaration(node.modifiers, node.isTypeOnly, typescript_1.default.factory.createNamedExports(newElements), node.moduleSpecifier);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// setting模式:直接导出EditComponent
|
|
155
|
+
if (renderType === 'setting') {
|
|
156
|
+
// 找到默认导出节点进行替换
|
|
157
|
+
if (typescript_1.default.isExportAssignment(node) && node.isExportEquals === false) {
|
|
158
|
+
// 替换 export default xxx 形式为 export { EditComponent as default }
|
|
159
|
+
return typescript_1.default.factory.createExportDeclaration(undefined, false, typescript_1.default.factory.createNamedExports([
|
|
160
|
+
typescript_1.default.factory.createExportSpecifier(false, typescript_1.default.factory.createIdentifier(helper_1.EDIT_COMPONENT_NAME), typescript_1.default.factory.createIdentifier('default')),
|
|
161
|
+
]));
|
|
162
|
+
}
|
|
163
|
+
// 处理 export default function Xxx() {} 形式
|
|
164
|
+
if (typescript_1.default.isFunctionDeclaration(node) &&
|
|
165
|
+
node.modifiers?.some((m) => m.kind === typescript_1.default.SyntaxKind.ExportKeyword) &&
|
|
166
|
+
node.modifiers?.some((m) => m.kind === typescript_1.default.SyntaxKind.DefaultKeyword)) {
|
|
167
|
+
// 创建新的默认导出,导出EditComponent作为default
|
|
168
|
+
return typescript_1.default.factory.createExportDeclaration(undefined, false, typescript_1.default.factory.createNamedExports([
|
|
169
|
+
typescript_1.default.factory.createExportSpecifier(false, typescript_1.default.factory.createIdentifier(helper_1.EDIT_COMPONENT_NAME), typescript_1.default.factory.createIdentifier('default')),
|
|
170
|
+
]));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return typescript_1.default.visitEachChild(node, visitor, context);
|
|
174
|
+
};
|
|
175
|
+
return typescript_1.default.visitNode(sourceFile, visitor);
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
// 转换代码
|
|
179
|
+
const result = typescript_1.default.transform(sourceFile, [transformerFactory]);
|
|
180
|
+
const printer = typescript_1.default.createPrinter({ newLine: typescript_1.default.NewLineKind.LineFeed });
|
|
181
|
+
if (result.transformed.length > 0) {
|
|
182
|
+
const transformedSourceFile = result.transformed[0];
|
|
183
|
+
// TypeScript 类型保证
|
|
184
|
+
if (transformedSourceFile) {
|
|
185
|
+
const transformedCode = printer.printFile(transformedSourceFile);
|
|
186
|
+
result.dispose(); // 清理资源
|
|
187
|
+
return transformedCode;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
result.dispose();
|
|
191
|
+
return code;
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
helper_1.logger.error('Error transforming with printer:', error);
|
|
195
|
+
// 如果高级转换失败,回退到简单转换
|
|
196
|
+
return transformCode(code, renderType);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* 检查文件是否包含EditComponent导出
|
|
201
|
+
*/
|
|
202
|
+
function hasEditComponentExportInEntryFile(filePath) {
|
|
203
|
+
try {
|
|
204
|
+
if (!fs_1.default.existsSync(filePath)) {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
// 读取文件内容
|
|
208
|
+
const content = fs_1.default.readFileSync(filePath, 'utf-8');
|
|
209
|
+
// 创建源文件
|
|
210
|
+
const sourceFile = typescript_1.default.createSourceFile(filePath, content, typescript_1.default.ScriptTarget.Latest, true);
|
|
211
|
+
// 使用已有的analyzeComponent函数分析
|
|
212
|
+
const analysis = analyzeComponent(sourceFile);
|
|
213
|
+
// 如果存在EditComponent导出,则返回true
|
|
214
|
+
return !!analysis.editComponent;
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
helper_1.logger.warn(`Error checking EditComponent in ${filePath}:`, error);
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// 检查目录中是否存在@edit-component文件
|
|
222
|
+
function findEditComponentFileInDir(filePath) {
|
|
223
|
+
const dirPath = path_1.default.dirname(filePath);
|
|
224
|
+
// 获取目录中的所有文件
|
|
225
|
+
try {
|
|
226
|
+
const files = fs_1.default.readdirSync(dirPath);
|
|
227
|
+
// 检查是否有匹配的文件
|
|
228
|
+
const file = files.find((file) => constants_1.EDIT_COMPONENT_FILE_NAME_REGEX.test(file));
|
|
229
|
+
if (file) {
|
|
230
|
+
return path_1.default.join(dirPath, file);
|
|
231
|
+
}
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
helper_1.logger.warn(`Failed to check @edit-component file in ${dirPath}: ${error}`);
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Vite 插件:组件代码拆分器
|
|
241
|
+
* 用于自动将组件文件拆分为视图组件和编辑组件
|
|
242
|
+
*/
|
|
243
|
+
function vitePluginCodeSplitter() {
|
|
244
|
+
return {
|
|
245
|
+
name: 'vite-plugin-code-splitter',
|
|
246
|
+
config(config) {
|
|
247
|
+
// 只有在构建模式且lib配置存在时处理
|
|
248
|
+
if (config.build && config.build.lib && typeof config.build.lib === 'object') {
|
|
249
|
+
const libConfig = config.build.lib;
|
|
250
|
+
if (libConfig.entry && typeof libConfig.entry === 'object' && !Array.isArray(libConfig.entry)) {
|
|
251
|
+
// 创建新的入口列表
|
|
252
|
+
const newEntry = {};
|
|
253
|
+
Object.entries(libConfig.entry).forEach(([key, filePath]) => {
|
|
254
|
+
// 对于普通模块路径,添加URL参数
|
|
255
|
+
if (typeof filePath === 'string') {
|
|
256
|
+
let editComponentFilePath = null;
|
|
257
|
+
// 检测文件是否包含EditComponent
|
|
258
|
+
let hasEditComponent = false;
|
|
259
|
+
try {
|
|
260
|
+
// 使用TypeScript分析文件
|
|
261
|
+
hasEditComponent = hasEditComponentExportInEntryFile(filePath);
|
|
262
|
+
// 记录检测到的文件
|
|
263
|
+
const fileName = path_1.default.basename(filePath);
|
|
264
|
+
if (hasEditComponent) {
|
|
265
|
+
helper_1.logger.info(`Found EditComponent in ${fileName}`);
|
|
266
|
+
editComponentFilePath = filePath;
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
helper_1.logger.debug(`No EditComponent found in ${fileName}`);
|
|
270
|
+
editComponentFilePath = findEditComponentFileInDir(filePath);
|
|
271
|
+
// 检查是否存在独立的@edit-component文件
|
|
272
|
+
if (editComponentFilePath) {
|
|
273
|
+
hasEditComponent = true;
|
|
274
|
+
helper_1.logger.info(`Found separate @edit-component file for ${editComponentFilePath}`);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
helper_1.logger.warn(`Failed to check EditComponent in ${filePath}: ${err}`);
|
|
280
|
+
}
|
|
281
|
+
// 视图组件总是保留
|
|
282
|
+
newEntry[key] = `${filePath}?renderType=view`;
|
|
283
|
+
// 只为包含EditComponent的文件创建编辑入口
|
|
284
|
+
if (hasEditComponent) {
|
|
285
|
+
newEntry[(0, helper_1.getEditComponentBlockName)(key)] = `${editComponentFilePath}?renderType=setting`;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
// 更新配置
|
|
290
|
+
libConfig.entry = newEntry;
|
|
291
|
+
helper_1.logger.info('Auto-split components enabled, entries updated');
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return config;
|
|
295
|
+
},
|
|
296
|
+
resolveId(id) {
|
|
297
|
+
// 处理带有 renderType 参数的模块 ID
|
|
298
|
+
if (id.includes('?renderType=')) {
|
|
299
|
+
return id; // 标记为需要处理的虚拟模块
|
|
300
|
+
}
|
|
301
|
+
return null;
|
|
302
|
+
},
|
|
303
|
+
load(id) {
|
|
304
|
+
if (!id.includes('?renderType=')) {
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
try {
|
|
308
|
+
// 解析 id,提取文件路径和查询参数
|
|
309
|
+
const [filePath, query] = id.split('?');
|
|
310
|
+
const params = new URLSearchParams(query);
|
|
311
|
+
const renderType = params.get('renderType');
|
|
312
|
+
if (!filePath || !renderType || (renderType !== 'view' && renderType !== 'setting')) {
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
// 确保文件存在
|
|
316
|
+
if (!fs_1.default.existsSync(filePath)) {
|
|
317
|
+
helper_1.logger.error(`File not found: ${filePath}`);
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
// 读取文件内容
|
|
321
|
+
const code = fs_1.default.readFileSync(filePath, 'utf-8');
|
|
322
|
+
// 根据渲染类型进行代码转换
|
|
323
|
+
// logger.info(`Splitting code for ${renderType}: ${filePath}`);
|
|
324
|
+
try {
|
|
325
|
+
// 首先尝试使用高级转换
|
|
326
|
+
return transformCodeWithPrinter(code, renderType);
|
|
327
|
+
}
|
|
328
|
+
catch (transformError) {
|
|
329
|
+
helper_1.logger.warn(`Advanced transform failed, falling back to basic transform: ${transformError}`);
|
|
330
|
+
// 如果失败,回退到基本转换
|
|
331
|
+
return transformCode(code, renderType);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
catch (error) {
|
|
335
|
+
helper_1.logger.error(`Error processing module ${id}:`, error);
|
|
336
|
+
}
|
|
337
|
+
return null;
|
|
338
|
+
},
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
exports.default = vitePluginCodeSplitter;
|