forked from zhouruizhe/gmTouringMiniApp
Initial commit: gmTouringMiniApp project
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,21 @@
|
||||
import { mkdirSync, writeFileSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import process from 'node:process'
|
||||
|
||||
const projectRoot = process.cwd()
|
||||
const outputRoot = resolve(projectRoot, 'dist/dev/mp-weixin')
|
||||
|
||||
mkdirSync(outputRoot, { recursive: true })
|
||||
|
||||
const placeholder = {
|
||||
note: 'This directory is generated by uni-app. Run `pnpm dev:mp-weixin` before compiling in WeChat DevTools.',
|
||||
}
|
||||
|
||||
writeFileSync(
|
||||
resolve(outputRoot, 'README.generated.json'),
|
||||
`${JSON.stringify(placeholder, null, 2)}\n`,
|
||||
'utf8',
|
||||
)
|
||||
|
||||
console.log(`微信开发目录已准备:${outputRoot}`)
|
||||
console.log('下一步运行:pnpm dev:mp-weixin')
|
||||
@@ -0,0 +1,31 @@
|
||||
import { spawn } from 'node:child_process'
|
||||
import { resolve } from 'node:path'
|
||||
import process from 'node:process'
|
||||
|
||||
const projectRoot = process.cwd()
|
||||
const uniCli = resolve(projectRoot, 'node_modules/@dcloudio/vite-plugin-uni/bin/uni.js')
|
||||
|
||||
// Some macOS sessions expose a low launchd file-watch limit even when the
|
||||
// shell's ulimit is high. Polling keeps uni-app builds reliable in that case.
|
||||
const child = spawn(process.execPath, [uniCli, ...process.argv.slice(2)], {
|
||||
cwd: projectRoot,
|
||||
env: {
|
||||
...process.env,
|
||||
CHOKIDAR_USEPOLLING: process.env.CHOKIDAR_USEPOLLING || '1',
|
||||
},
|
||||
stdio: 'inherit',
|
||||
})
|
||||
|
||||
child.on('error', (error) => {
|
||||
console.error(`无法启动 uni-app CLI:${error.message}`)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
child.on('exit', (code, signal) => {
|
||||
if (signal) {
|
||||
process.kill(process.pid, signal)
|
||||
return
|
||||
}
|
||||
|
||||
process.exit(code ?? 1)
|
||||
})
|
||||
@@ -0,0 +1,141 @@
|
||||
import { existsSync, readFileSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import process from 'node:process'
|
||||
|
||||
const projectRoot = process.cwd()
|
||||
const outputDirectory = process.argv[2] ?? 'dist/dev/mp-weixin'
|
||||
const outputRoot = resolve(projectRoot, outputDirectory)
|
||||
const expectedPages = [
|
||||
'pages/map/index',
|
||||
'pages/assistant/index',
|
||||
'pages/itinerary/index',
|
||||
'pages/planner/index',
|
||||
'pages/poi/detail',
|
||||
]
|
||||
const expectedTabPages = [
|
||||
'pages/map/index',
|
||||
'pages/assistant/index',
|
||||
'pages/planner/index',
|
||||
]
|
||||
const expectedTabIcons = [
|
||||
'static/tabbar/map.png',
|
||||
'static/tabbar/map-selected.png',
|
||||
'static/tabbar/assistant.png',
|
||||
'static/tabbar/assistant-selected.png',
|
||||
'static/tabbar/planner.png',
|
||||
'static/tabbar/planner-selected.png',
|
||||
]
|
||||
const requiredFiles = [
|
||||
'app.json',
|
||||
'app.js',
|
||||
'app.wxss',
|
||||
'project.config.json',
|
||||
...expectedPages.flatMap(page => ['json', 'js', 'wxml', 'wxss'].map(extension => `${page}.${extension}`)),
|
||||
...expectedTabIcons,
|
||||
]
|
||||
|
||||
const missingFiles = requiredFiles.filter(file => !existsSync(resolve(outputRoot, file)))
|
||||
if (missingFiles.length > 0) {
|
||||
console.error(`微信小程序产物不完整:${outputRoot}`)
|
||||
missingFiles.forEach(file => console.error(`- 缺少 ${file}`))
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const appConfig = JSON.parse(readFileSync(resolve(outputRoot, 'app.json'), 'utf8'))
|
||||
const expectedPrivateInfos = ['getLocation', 'startLocationUpdate', 'onLocationChange']
|
||||
const configuredPrivateInfos = appConfig.requiredPrivateInfos ?? []
|
||||
if (JSON.stringify(configuredPrivateInfos) !== JSON.stringify(expectedPrivateInfos)) {
|
||||
console.error(`定位隐私接口声明错误:期望 ${expectedPrivateInfos.join(', ')},实际为 ${configuredPrivateInfos.join(', ') || '未配置'}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const locationPermissionDescription = appConfig.permission?.['scope.userLocation']?.desc ?? ''
|
||||
const locationPermissionDescriptionLength = Array.from(locationPermissionDescription).length
|
||||
if (locationPermissionDescriptionLength < 1 || locationPermissionDescriptionLength > 30) {
|
||||
console.error('app.json 缺少 scope.userLocation 用途说明。')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const missingPages = expectedPages.filter(page => !appConfig.pages?.includes(page))
|
||||
if (missingPages.length > 0) {
|
||||
console.error('app.json 未注册全部业务页面:')
|
||||
missingPages.forEach(page => console.error(`- ${page}`))
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const unexpectedPages = appConfig.pages?.filter(page => !expectedPages.includes(page)) ?? []
|
||||
if (unexpectedPages.length > 0 || appConfig.pages?.length !== expectedPages.length) {
|
||||
console.error('app.json 包含未纳入本期范围的页面:')
|
||||
unexpectedPages.forEach(page => console.error(`- ${page}`))
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (appConfig.pages?.[0] !== 'pages/map/index') {
|
||||
console.error(`微信小程序启动页错误:期望 pages/map/index,实际为 ${appConfig.pages?.[0] ?? '未配置'}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const forbiddenPages = appConfig.pages?.filter(page => [
|
||||
'pages/index/index',
|
||||
'pages/hi',
|
||||
'pages/unocss/index',
|
||||
'pages/uview-plus/index',
|
||||
].includes(page)) ?? []
|
||||
|
||||
if (forbiddenPages.length > 0) {
|
||||
console.error('微信小程序产物仍包含模板演示页面:')
|
||||
forbiddenPages.forEach(page => console.error(`- ${page}`))
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const tabPages = appConfig.tabBar?.list?.map(item => item.pagePath) ?? []
|
||||
if (JSON.stringify(tabPages) !== JSON.stringify(expectedTabPages)) {
|
||||
console.error(`tabBar 页面错误:期望 ${expectedTabPages.join(', ')},实际为 ${tabPages.join(', ') || '未配置'}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (!['black', 'white'].includes(appConfig.tabBar?.borderStyle)) {
|
||||
console.error(`tabBar.borderStyle 只能为 black 或 white,实际为 ${appConfig.tabBar?.borderStyle ?? '未配置'}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const configuredIcons = appConfig.tabBar.list.flatMap(item => [item.iconPath, item.selectedIconPath])
|
||||
if (JSON.stringify(configuredIcons) !== JSON.stringify(expectedTabIcons)) {
|
||||
console.error('tabBar 图标配置与预期不一致。')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const ideConfigPath = resolve(projectRoot, 'project.config.json')
|
||||
if (!existsSync(ideConfigPath)) {
|
||||
console.error('项目根目录缺少 project.config.json,微信开发者工具无法按项目根目录导入。')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const ideConfig = JSON.parse(readFileSync(ideConfigPath, 'utf8'))
|
||||
if (ideConfig.compileType !== 'miniprogram') {
|
||||
console.error(`project.config.json 的 compileType 必须为 miniprogram,实际为 ${ideConfig.compileType ?? '未配置'}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (ideConfig.miniprogramRoot !== 'dist/dev/mp-weixin/') {
|
||||
console.error(`project.config.json 的 miniprogramRoot 错误:${ideConfig.miniprogramRoot ?? '未配置'}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (ideConfig.srcMiniprogramRoot !== ideConfig.miniprogramRoot) {
|
||||
console.error('project.config.json 的 srcMiniprogramRoot 必须与 miniprogramRoot 一致。')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const outputIdeConfig = JSON.parse(readFileSync(resolve(outputRoot, 'project.config.json'), 'utf8'))
|
||||
if (outputIdeConfig.compileType !== 'miniprogram') {
|
||||
console.error(`编译产物 project.config.json 的 compileType 必须为 miniprogram,实际为 ${outputIdeConfig.compileType ?? '未配置'}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (!ideConfig.appid || !outputIdeConfig.appid || ideConfig.appid !== outputIdeConfig.appid) {
|
||||
console.error('根目录与编译产物的微信 AppID 不一致,请同步 project.config.json 与 .env.local。')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
console.log(`微信开发者工具产物检查通过:${outputRoot}`)
|
||||
Reference in New Issue
Block a user