128 lines
3.2 KiB
TypeScript
128 lines
3.2 KiB
TypeScript
import fs from 'node:fs';
|
||
import path from 'node:path';
|
||
import { defineConfig, transformWithEsbuild, type Plugin } from 'vite';
|
||
import uni from '@dcloudio/vite-plugin-uni';
|
||
|
||
/** 此路径根据自己项目路径修改;默认为 uniapp 插件市场导入路径;*/
|
||
import viteVueUnocss, { unocss, flex, pseudo, border } from './unocss/a-hua-unocss';
|
||
|
||
const isAlipay = () => process.env.UNI_PLATFORM === 'mp-alipay';
|
||
|
||
/**
|
||
* 支付宝旧 Babel(CE1000)对箭头函数 / 模板字符串 / ?? / ?. / catch{} 等解析不稳。
|
||
* 仅 mp-alipay 构建时把产物降到 es2015(保留 const/let;esbuild 不支持 const→es5)。
|
||
*/
|
||
const ALIPAY_ESBUILD_OPTIONS = {
|
||
loader: 'js' as const,
|
||
target: 'es2015',
|
||
sourcemap: false as const,
|
||
supported: {
|
||
arrow: false,
|
||
'template-literal': false,
|
||
'optional-chain': false,
|
||
'nullish-coalescing': false,
|
||
'optional-catch-binding': false,
|
||
'object-rest-spread': false,
|
||
'class-field': false
|
||
}
|
||
};
|
||
|
||
const needsAlipayTransform = (source: string) =>
|
||
source.includes('=>') ||
|
||
source.includes('`') ||
|
||
source.includes('?.') ||
|
||
source.includes('??') ||
|
||
/catch\s*\{/.test(source);
|
||
|
||
const walkJsFiles = (dir: string, files: string[] = []) => {
|
||
if (!fs.existsSync(dir)) return files;
|
||
for (const name of fs.readdirSync(dir)) {
|
||
const fullPath = path.join(dir, name);
|
||
if (fs.statSync(fullPath).isDirectory()) {
|
||
walkJsFiles(fullPath, files);
|
||
} else if (name.endsWith('.js')) {
|
||
files.push(fullPath);
|
||
}
|
||
}
|
||
return files;
|
||
};
|
||
|
||
const transformAlipayOutputDir = async (root: string) => {
|
||
const files = walkJsFiles(root);
|
||
let changed = 0;
|
||
for (const file of files) {
|
||
const source = fs.readFileSync(file, 'utf8');
|
||
if (!needsAlipayTransform(source)) continue;
|
||
try {
|
||
const result = await transformWithEsbuild(source, file, ALIPAY_ESBUILD_OPTIONS);
|
||
if (result.code && result.code !== source) {
|
||
fs.writeFileSync(file, result.code, 'utf8');
|
||
changed += 1;
|
||
}
|
||
} catch (error: any) {
|
||
console.warn('[alipay-es-compat] skip', file, error?.message || error);
|
||
}
|
||
}
|
||
console.log(`[alipay-es-compat] ${root} transformed ${changed} file(s)`);
|
||
};
|
||
|
||
function alipayEsCompatPlugin(): Plugin {
|
||
return {
|
||
name: 'cashier-alipay-es-compat',
|
||
apply: 'build',
|
||
enforce: 'post',
|
||
async renderChunk(code) {
|
||
if (!isAlipay() || !needsAlipayTransform(code)) return null;
|
||
const result = await transformWithEsbuild(code, 'chunk.js', ALIPAY_ESBUILD_OPTIONS);
|
||
return { code: result.code, map: null };
|
||
},
|
||
async closeBundle() {
|
||
if (!isAlipay()) return;
|
||
const roots = [
|
||
path.resolve(__dirname, 'unpackage/dist/dev/mp-alipay'),
|
||
path.resolve(__dirname, 'unpackage/dist/build/mp-alipay')
|
||
];
|
||
for (const root of roots) {
|
||
await transformAlipayOutputDir(root);
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
export default defineConfig({
|
||
build: isAlipay()
|
||
? {
|
||
target: 'es2015',
|
||
cssTarget: 'chrome61'
|
||
}
|
||
: undefined,
|
||
plugins: [
|
||
uni(),
|
||
alipayEsCompatPlugin(),
|
||
viteVueUnocss({
|
||
presets: [
|
||
unocss(),
|
||
flex(),
|
||
pseudo(),
|
||
border({
|
||
width: 1,
|
||
style: 'solid',
|
||
color: 'currentColor'
|
||
})
|
||
],
|
||
prefix: ['li'],
|
||
exclude: ['node_modules', 'uni_modules'],
|
||
theme: {
|
||
generator: true,
|
||
colors: {
|
||
veryCool: '#37A5FF',
|
||
brand: {
|
||
primary: '#37A5FF',
|
||
DEFAULT: '#942192'
|
||
}
|
||
}
|
||
}
|
||
})
|
||
]
|
||
});
|