@htyf-mp/cli 0.2.2 → 0.2.4
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/package.json +1 -1
- package/src/build.mjs +35 -2
- package/src/project-initializer.mjs +20 -2
- package/src/template-processor.mjs +2 -2
- package/src/webpack.config.mjs +7 -3
package/package.json
CHANGED
package/src/build.mjs
CHANGED
|
@@ -148,6 +148,8 @@ export async function mpBuildShell(newAppInfo, isGodot = false) {
|
|
|
148
148
|
|
|
149
149
|
// 构建 app.json 配置
|
|
150
150
|
const appJson = {
|
|
151
|
+
...newAppInfo,
|
|
152
|
+
rotate: newAppInfo.rotate || 'portrait',
|
|
151
153
|
type: isGodot ? 'game' : 'app', // Godot 项目类型为 'game',普通小程序为 'app'
|
|
152
154
|
engines: '2.0.0',
|
|
153
155
|
name: newAppInfo.name,
|
|
@@ -207,8 +209,39 @@ export async function mpBuildShell(newAppInfo, isGodot = false) {
|
|
|
207
209
|
try {
|
|
208
210
|
if (!isGodot) {
|
|
209
211
|
// ========== 普通小程序构建流程 ==========
|
|
210
|
-
Logger.info('使用
|
|
211
|
-
|
|
212
|
+
Logger.info('使用 React Native 构建小程序包...');
|
|
213
|
+
|
|
214
|
+
// 计算 react-native CLI 路径
|
|
215
|
+
const reactNativePath = path.resolve(__dirname, '../../../.bin/react-native');
|
|
216
|
+
const entryFile = newAppInfo.entry
|
|
217
|
+
? path.resolve(PROJECT_ROOT, newAppInfo.entry)
|
|
218
|
+
: rootIndexPath;
|
|
219
|
+
const bundlePlatform = (CONSTANTS.BUNDLE_PLATFORM || 'ios').toLowerCase();
|
|
220
|
+
const bundleOutput = path.join(mpOptions.extraChunksPath, `${scriptName}.${bundlePlatform}.jsbundle`);
|
|
221
|
+
const assetsDest = path.join(mpOptions.extraChunksPath, 'assets');
|
|
222
|
+
|
|
223
|
+
await fse.ensureDir(path.dirname(bundleOutput));
|
|
224
|
+
await fse.ensureDir(assetsDest);
|
|
225
|
+
|
|
226
|
+
const command = [
|
|
227
|
+
'npx',
|
|
228
|
+
'cross-env',
|
|
229
|
+
`APP_ROOT_INDEX_PATH=${rootIndexPath}`,
|
|
230
|
+
`APP_EXPOSES_OPTIONS=${encodeURI(JSON.stringify(mpOptions))}`,
|
|
231
|
+
'node',
|
|
232
|
+
reactNativePath,
|
|
233
|
+
'bundle',
|
|
234
|
+
'--entry-file',
|
|
235
|
+
rootIndexPath,
|
|
236
|
+
'--platform',
|
|
237
|
+
bundlePlatform,
|
|
238
|
+
'--dev',
|
|
239
|
+
'false',
|
|
240
|
+
'--reset-cache',
|
|
241
|
+
'--minify',
|
|
242
|
+
'false',
|
|
243
|
+
].join(' ');
|
|
244
|
+
console.log('command', command);
|
|
212
245
|
await CommandExecutor.execute(command, {
|
|
213
246
|
description: '构建小程序包',
|
|
214
247
|
timeout: 120000, // 2 分钟超时
|
|
@@ -193,8 +193,26 @@ export class ProjectInitializer {
|
|
|
193
193
|
const projectConfig = this.config.createProjectConfig(appName, displayName, appid);
|
|
194
194
|
|
|
195
195
|
// 写入配置文件
|
|
196
|
-
const configPath = path.join(appRootPath, '
|
|
197
|
-
|
|
196
|
+
const configPath = path.join(appRootPath, 'app.json');
|
|
197
|
+
let existingConfig = {};
|
|
198
|
+
|
|
199
|
+
// 检查 app.json 是否存在
|
|
200
|
+
if (fs.existsSync(configPath)) {
|
|
201
|
+
// 如果存在,读取现有内容
|
|
202
|
+
const existingContent = fs.readFileSync(configPath, 'utf-8');
|
|
203
|
+
try {
|
|
204
|
+
existingConfig = JSON.parse(existingContent);
|
|
205
|
+
} catch (error) {
|
|
206
|
+
Logger.warn('app.json 格式错误,将创建新配置');
|
|
207
|
+
existingConfig = {};
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// 添加 htyf 字段
|
|
212
|
+
existingConfig.htyf = projectConfig;
|
|
213
|
+
|
|
214
|
+
// 写入配置文件
|
|
215
|
+
fs.writeFileSync(configPath, JSON.stringify(existingConfig, undefined, 2));
|
|
198
216
|
|
|
199
217
|
// 清理临时文件
|
|
200
218
|
spinner.text = '正在清理临时文件...';
|
|
@@ -89,7 +89,7 @@ export class TemplateProcessor {
|
|
|
89
89
|
// 复制模板文件
|
|
90
90
|
Object.entries(template.files).forEach(([key, fileName]) => {
|
|
91
91
|
const srcPath = path.join(tempPath, fileName);
|
|
92
|
-
const destPath = path.join(appRootPath, key === 'src' ? './src' : `./${key === 'app' ? 'App.tsx' : key === 'index' ? 'index.js' : key === 'babel' ? 'babel.config.js' : '
|
|
92
|
+
const destPath = path.join(appRootPath, key === 'src' ? './src' : `./${key === 'app' ? 'App.tsx' : key === 'index' ? 'index.js' : key === 'babel' ? 'babel.config.js' : 'app.json'}`);
|
|
93
93
|
|
|
94
94
|
if (fs.existsSync(srcPath)) {
|
|
95
95
|
fse.copySync(srcPath, destPath);
|
|
@@ -125,7 +125,7 @@ export class TemplateProcessor {
|
|
|
125
125
|
// 复制模板文件
|
|
126
126
|
Object.entries(template.files).forEach(([key, fileName]) => {
|
|
127
127
|
const srcPath = path.join(tempPath, fileName);
|
|
128
|
-
const destPath = path.join(appRootPath, key === 'src' ? './src' : `./${key === 'app' ? 'App.tsx' : key === 'index' ? 'index.js' : key === 'babel' ? 'babel.config.js' : '
|
|
128
|
+
const destPath = path.join(appRootPath, key === 'src' ? './src' : `./${key === 'app' ? 'App.tsx' : key === 'index' ? 'index.js' : key === 'babel' ? 'babel.config.js' : 'app.json'}`);
|
|
129
129
|
|
|
130
130
|
if (fs.existsSync(srcPath)) {
|
|
131
131
|
fse.copySync(srcPath, destPath);
|
package/src/webpack.config.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import TerserPlugin from 'terser-webpack-plugin';
|
|
|
7
7
|
import * as Repack from '@callstack/repack';
|
|
8
8
|
import { ExpoModulesPlugin } from '@callstack/repack-plugin-expo-modules';
|
|
9
9
|
import { ReanimatedPlugin } from '@callstack/repack-plugin-reanimated';
|
|
10
|
-
import { HtyfModulesPlugin } from '
|
|
10
|
+
import { HtyfModulesPlugin } from '@htyf-mp/cli/HtyfImportsPlugin.mjs';
|
|
11
11
|
import { getProjectRoot } from './utils.mjs';
|
|
12
12
|
|
|
13
13
|
// 获取当前文件和目录路径
|
|
@@ -149,13 +149,17 @@ export default (env = {}) => {
|
|
|
149
149
|
// Repack主插件,支持extraChunks配置
|
|
150
150
|
new Repack.RepackPlugin({
|
|
151
151
|
platform,
|
|
152
|
-
extraChunks: [
|
|
152
|
+
extraChunks: mpOptions.extraChunksPath ? [
|
|
153
153
|
{
|
|
154
|
+
// 排除 remoteEntry chunk,让它保留在 output.path 中供 Manifest Plugin 使用
|
|
155
|
+
// remoteEntry 文件名由 ModuleFederationPluginV2 的 filename 配置决定
|
|
156
|
+
// 使用 exclude 排除 remoteEntry,其他 chunk 输出到 extraChunksPath
|
|
157
|
+
exclude: mpOptions.filename ? new RegExp(`^${mpOptions.filename.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`) : /^remoteEntry/,
|
|
154
158
|
include: /.*/,
|
|
155
159
|
type: 'remote',
|
|
156
160
|
outputPath: `${mpOptions.extraChunksPath}`,
|
|
157
161
|
},
|
|
158
|
-
],
|
|
162
|
+
] : undefined,
|
|
159
163
|
}),
|
|
160
164
|
// Expo模块支持
|
|
161
165
|
new ExpoModulesPlugin(),
|