Files
gongxue-base/apps/taro/config/index.ts
2026-07-12 19:26:57 +08:00

135 lines
4.1 KiB
TypeScript

import type { UserConfigExport } from '@tarojs/cli';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const portal = process.env.TARO_APP_PORTAL?.trim() || 'student';
const taroEnv = process.env.TARO_ENV?.trim() || 'h5';
const releaseMode = process.env.TARO_APP_RELEASE_MODE?.trim().toLowerCase() || 'preview';
const configDir = path.dirname(fileURLToPath(import.meta.url));
const supportedPortals = new Set(['student', 'tenant-admin', 'platform-admin']);
if (!supportedPortals.has(portal)) throw new Error(`Unsupported Taro portal: ${portal}`);
if (!/^[a-z0-9-]+$/i.test(taroEnv)) throw new Error(`Unsupported Taro target: ${taroEnv}`);
if (releaseMode !== 'preview' && releaseMode !== 'production') throw new Error(`Unsupported Taro release mode: ${releaseMode}`);
const outputRoot = `dist/${taroEnv}-${portal}`;
function publicBuildValue(name: string) {
return process.env[name]?.trim() || '';
}
function normalizedHostname(value: string) {
return value.trim().toLowerCase().replace(/^\[|\]$/g, '').replace(/\.$/, '');
}
function isLoopbackHostname(value: string) {
const hostname = normalizedHostname(value);
return hostname === 'localhost'
|| hostname.endsWith('.localhost')
|| hostname === '::1'
|| hostname === '0.0.0.0'
|| /^127(?:\.\d{1,3}){3}$/.test(hostname);
}
function isPlaceholderHostname(value: string) {
const hostname = normalizedHostname(value);
return ['example', 'test', 'local'].some(suffix => hostname === suffix || hostname.endsWith(`.${suffix}`));
}
function isProductionWeappApiBaseUrl(value: string) {
try {
const parsed = new URL(value);
return parsed.protocol === 'https:'
&& Boolean(parsed.hostname)
&& !isLoopbackHostname(parsed.hostname)
&& !isPlaceholderHostname(parsed.hostname);
} catch {
return false;
}
}
const apiBaseUrl = publicBuildValue('TARO_APP_API_BASE_URL')
|| (releaseMode === 'production' ? '' : 'http://127.0.0.1:8787');
const configuredTenantCode = publicBuildValue('TARO_APP_TENANT_CODE');
const requestedWeappTenantMode = publicBuildValue('TARO_APP_WEAPP_TENANT_MODE').toLowerCase();
if (taroEnv === 'weapp' && requestedWeappTenantMode && !['fixed', 'launch'].includes(requestedWeappTenantMode)) {
throw new Error('TARO_APP_WEAPP_TENANT_MODE must be fixed or launch');
}
const weappTenantMode = taroEnv === 'weapp'
? requestedWeappTenantMode || (releaseMode === 'production' || configuredTenantCode ? 'fixed' : 'launch')
: '';
const tenantCode = taroEnv === 'weapp' && weappTenantMode === 'launch' ? '' : configuredTenantCode;
if (taroEnv === 'weapp' && releaseMode === 'production' && !isProductionWeappApiBaseUrl(apiBaseUrl)) {
throw new Error('TARO_APP_API_BASE_URL must use a non-placeholder HTTPS host for a production WeApp build');
}
const publicBuildConfig = {
portal,
target: taroEnv,
releaseMode,
weappTenantMode,
apiBaseUrl,
supabaseUrl: publicBuildValue('TARO_APP_SUPABASE_URL'),
supabasePublishableKey: publicBuildValue('TARO_APP_SUPABASE_PUBLISHABLE_KEY'),
tenantCode,
};
export default {
projectName: 'tiku-saas-taro',
date: '2026-06-29',
designWidth: 750,
deviceRatio: {
640: 2.34 / 2,
750: 1,
828: 1.81 / 2,
},
sourceRoot: 'src',
outputRoot,
framework: 'react',
compiler: {
type: 'webpack5',
prebundle: {
enable: false,
},
},
alias: {
'@': path.resolve(configDir, '..', 'src'),
},
defineConstants: {
__TARO_PUBLIC_BUILD_CONFIG__: JSON.stringify(publicBuildConfig),
},
copy: {
patterns: [
{
from: path.resolve(configDir, '..', 'src', 'assets'),
to: path.resolve(configDir, '..', outputRoot, 'assets'),
},
],
options: {},
},
h5: {
publicPath: '/',
staticDirectory: 'static',
devServer: {
host: '127.0.0.1',
allowedHosts: ['localhost', '127.0.0.1'],
},
output: {
filename: 'js/[name].[contenthash:8].js',
chunkFilename: 'js/[name].[contenthash:8].js',
},
router: {
mode: 'browser',
},
},
mini: {
postcss: {
pxtransform: {
enable: true,
config: {},
},
cssModules: {
enable: false,
},
},
},
} satisfies UserConfigExport;