修复导览点位可见性与构建门禁
This commit is contained in:
61
scripts/finalize-h5-build-policy.cjs
Normal file
61
scripts/finalize-h5-build-policy.cjs
Normal file
@@ -0,0 +1,61 @@
|
||||
const { loadEnv } = require('vite')
|
||||
|
||||
const tencentMapKeyPlaceholder = '__REPLACE_WITH_TENCENT_MAP_WEB_KEY__'
|
||||
const tencentMapKeyPattern = /^[A-Z0-9]{5}(?:-[A-Z0-9]{5}){4,6}$/i
|
||||
|
||||
const isUsableTencentMapKey = (value) => (
|
||||
tencentMapKeyPattern.test(value)
|
||||
&& value !== tencentMapKeyPlaceholder
|
||||
)
|
||||
|
||||
const resolveH5BuildPolicy = ({
|
||||
args = [],
|
||||
projectRoot,
|
||||
environment = process.env,
|
||||
loadProductionEnv = (root) => loadEnv('production', root, '')
|
||||
}) => {
|
||||
const flags = new Set(args)
|
||||
const requireTencentMapKey = flags.has('--require-tencent-map-key')
|
||||
const allowPlaceholder = flags.has('--allow-placeholder')
|
||||
|
||||
if (requireTencentMapKey && allowPlaceholder) {
|
||||
throw new Error('H5 build cannot require a Tencent map key and allow its placeholder at the same time.')
|
||||
}
|
||||
|
||||
if (!requireTencentMapKey) {
|
||||
return {
|
||||
allowPlaceholder,
|
||||
requireTencentMapKey,
|
||||
tencentMapKey: ''
|
||||
}
|
||||
}
|
||||
|
||||
const productionEnv = loadProductionEnv(projectRoot)
|
||||
const tencentMapKey = (
|
||||
environment.VITE_TENCENT_MAP_KEY
|
||||
|| productionEnv.VITE_TENCENT_MAP_KEY
|
||||
|| ''
|
||||
).trim()
|
||||
|
||||
if (!isUsableTencentMapKey(tencentMapKey)) {
|
||||
throw new Error([
|
||||
'Production H5 build requires a well-formed non-placeholder VITE_TENCENT_MAP_KEY.',
|
||||
'Inject it through CI or an ignored .env.production.local file.'
|
||||
].join(' '))
|
||||
}
|
||||
|
||||
return {
|
||||
allowPlaceholder,
|
||||
requireTencentMapKey,
|
||||
tencentMapKey
|
||||
}
|
||||
}
|
||||
|
||||
const isTextBuildFile = (filePath) => /\.(?:js|mjs|html|json|css|txt|svg|xml|map)$/i.test(filePath)
|
||||
|
||||
module.exports = {
|
||||
isTextBuildFile,
|
||||
isUsableTencentMapKey,
|
||||
resolveH5BuildPolicy,
|
||||
tencentMapKeyPlaceholder
|
||||
}
|
||||
@@ -1,29 +1,36 @@
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
const { spawnSync } = require('node:child_process')
|
||||
|
||||
require('./copy-h5-nav-assets.cjs')
|
||||
const {
|
||||
isTextBuildFile,
|
||||
resolveH5BuildPolicy,
|
||||
tencentMapKeyPlaceholder
|
||||
} = require('./finalize-h5-build-policy.cjs')
|
||||
|
||||
const projectRoot = path.resolve(__dirname, '..')
|
||||
const h5Root = path.join(projectRoot, 'dist', 'build', 'h5')
|
||||
const placeholder = '__REPLACE_WITH_TENCENT_MAP_WEB_KEY__'
|
||||
const placeholder = tencentMapKeyPlaceholder
|
||||
const badPatterns = [
|
||||
'http://1.92.206.90:9000',
|
||||
'1.92.206.90',
|
||||
'guide.whaoyue.com',
|
||||
placeholder
|
||||
]
|
||||
const args = new Set(process.argv.slice(2))
|
||||
const requireTencentMapKey = args.has('--require-tencent-map-key')
|
||||
const allowPlaceholder = args.has('--allow-placeholder')
|
||||
const tencentMapKey = (process.env.VITE_TENCENT_MAP_KEY || '').trim()
|
||||
const {
|
||||
allowPlaceholder,
|
||||
requireTencentMapKey,
|
||||
tencentMapKey
|
||||
} = resolveH5BuildPolicy({
|
||||
args: process.argv.slice(2),
|
||||
projectRoot
|
||||
})
|
||||
|
||||
require('./copy-h5-nav-assets.cjs')
|
||||
|
||||
if (!fs.existsSync(h5Root)) {
|
||||
throw new Error(`H5 build output not found: ${h5Root}`)
|
||||
}
|
||||
|
||||
const isTextFile = (filePath) => /\.(?:js|mjs|html|json|css|txt|svg|xml)$/i.test(filePath)
|
||||
|
||||
const walkFiles = (dir, files = []) => {
|
||||
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||
const filePath = path.join(dir, entry.name)
|
||||
@@ -42,16 +49,21 @@ const walkFiles = (dir, files = []) => {
|
||||
}
|
||||
|
||||
const allFiles = walkFiles(h5Root)
|
||||
const textFiles = allFiles.filter(isTextFile)
|
||||
const textFiles = allFiles.filter(isTextBuildFile)
|
||||
const placeholderFiles = textFiles.filter((file) => fs.readFileSync(file, 'utf8').includes(placeholder))
|
||||
const hasUsableTencentMapKey = tencentMapKey.length > 0 && tencentMapKey !== placeholder
|
||||
const hasUsableTencentMapKey = tencentMapKey.length > 0
|
||||
const missingTencentMapKeyMessage = [
|
||||
'Production H5 build requires a well-formed non-placeholder VITE_TENCENT_MAP_KEY.',
|
||||
'Inject it through CI or an ignored .env.production.local file.'
|
||||
].join(' ')
|
||||
|
||||
if (requireTencentMapKey && !hasUsableTencentMapKey) {
|
||||
throw new Error(missingTencentMapKeyMessage)
|
||||
}
|
||||
|
||||
if (placeholderFiles.length > 0) {
|
||||
if (!hasUsableTencentMapKey) {
|
||||
const message = [
|
||||
'H5 build output still contains Tencent map key placeholder.',
|
||||
'Please set VITE_TENCENT_MAP_KEY before production build.'
|
||||
].join(' ')
|
||||
const message = `H5 build output still contains Tencent map key placeholder. ${missingTencentMapKeyMessage}`
|
||||
|
||||
if (requireTencentMapKey && !allowPlaceholder) {
|
||||
throw new Error(message)
|
||||
@@ -108,8 +120,8 @@ for (const file of textFiles) {
|
||||
}
|
||||
|
||||
if (badMatches.length > 0) {
|
||||
if (allowPlaceholder && badMatches.every((item) => item.pattern === placeholder)) {
|
||||
console.warn('[finalize-h5-build] Tencent map key placeholder is allowed for this build.')
|
||||
if (allowPlaceholder) {
|
||||
console.warn('[finalize-h5-build] Test H5 build allows non-production source hosts and the Tencent map key placeholder.')
|
||||
} else {
|
||||
console.error(JSON.stringify(badMatches.slice(0, 20), null, 2))
|
||||
throw new Error('H5 build output contains forbidden test host, old domain, or placeholder.')
|
||||
|
||||
Reference in New Issue
Block a user