Files
kintone-vue-template/vite.config.ts
2025-10-17 14:34:26 +08:00

171 lines
5.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import copy from 'rollup-plugin-copy';
import * as path from 'path';
import * as fs from 'fs';
import * as child_process from 'child_process';
import Components from 'unplugin-vue-components/vite';
import RSA from 'node-rsa';
// 从 package.json 读取 kintone-ui-component 版本信息
const packageJson = JSON.parse(fs.readFileSync(path.resolve(__dirname, 'package.json'), 'utf-8'));
const kucVersion = packageJson.dependencies['kintone-ui-component'];
const formattedVersion = kucVersion.replace(/\./g, '-'); // 例如1.22.0 -> 1-22-0
/**
* 生成 kintone 插件的私钥
*/
export const generatePrivateKey = () => {
const key = new RSA({ b: 1024 });
return key.exportKey('pkcs1-private');
};
// 检查 private.ppk 是否存在,如果不存在则生成
const privateKeyPath = path.resolve(__dirname, 'private.ppk');
if (!fs.existsSync(privateKeyPath)) {
const privateKey = generatePrivateKey();
fs.writeFileSync(privateKeyPath, privateKey);
}
/**
* 自定义插件 vite-plugin-replace-tags替换 KUC 组件标签为包含版本号的标签,并自动导入组件
*/
function replaceKucTagsPlugin() {
return {
name: 'vite-plugin-replace-tags',
async load(id) {
if (id.endsWith('.vue')) {
const content = await fs.promises.readFile(id, 'utf-8');
const usedComponent = {};
// 替换 <kuc-*> 为带有版本号的形式 <kuc-[version]-*>
let res = content
.replace(new RegExp(`</kuc-([a-zA-Z0-9-]+)(?![0-9-])>`, 'g'), (match, p1) => `</kuc-${p1}-${formattedVersion}>`)
.replace(new RegExp(`<kuc-([a-zA-Z0-9-]+)(?![0-9-])([^>]*)>`, 'g'), (match, p1, p2) => {
usedComponent[p1] = true;
return `<kuc-${p1}-${formattedVersion}${p2}>`;
});
// 如果有 KUC 组件,自动生成 import 脚本
if (Object.keys(usedComponent).length) {
let importScript = '<script lang="ts">';
Object.keys(usedComponent).forEach((key) => {
const keyPascal = key.split('-')
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join('');
// 特殊处理 multi-choice 组件名称
if (key === 'multi-choice') {
key = 'multichoice';
}
importScript += `import * as Kuc${keyPascal} from "kintone-ui-component/lib/${key}";`;
});
importScript += '</script>';
res = importScript + res;
}
return res;
}
},
};
}
/**
* 自定义插件 iife-builder构建 desktop.ts 和 mobile.ts 的 IIFE 版本
*/
function buildIIFEVersions() {
return {
name: 'iife-builder',
buildStart() {
console.log('Building IIFE versions...');
try {
// Build desktop IIFE
console.log('Building desktop IIFE...');
child_process.execSync('npx vite build --config vite.desktop.config.ts', { stdio: 'inherit' });
// Build mobile IIFE
console.log('Building mobile IIFE...');
child_process.execSync('npx vite build --config vite.mobile.config.ts', { stdio: 'inherit' });
console.log('IIFE builds completed successfully.');
} catch (error) {
console.error('Error building IIFE versions:', error);
throw error;
}
},
generateBundle(options, bundle) {
// 将 IIFE 版本复制到主构建目录覆盖原有文件
const desktopIIFEPath = path.resolve(__dirname, 'dist-iife/desktop/desktop.js');
const mobileIIFEPath = path.resolve(__dirname, 'dist-iife/mobile/mobile.js');
const destDir = path.resolve(__dirname, 'dist/src/js');
if (fs.existsSync(desktopIIFEPath)) {
fs.mkdirSync(destDir, { recursive: true });
fs.copyFileSync(desktopIIFEPath, path.join(destDir, 'desktop.js'));
console.log('Copied desktop.js to dist/src/js/');
}
if (fs.existsSync(mobileIIFEPath)) {
fs.mkdirSync(destDir, { recursive: true });
fs.copyFileSync(mobileIIFEPath, path.join(destDir, 'mobile.js'));
console.log('Copied mobile.js to dist/src/js/');
}
// 清理临时的 dist-iife 目录
if (fs.existsSync(path.resolve(__dirname, 'dist-iife'))) {
fs.rmSync(path.resolve(__dirname, 'dist-iife'), { recursive: true, force: true });
console.log('Cleaned up dist-iife directory');
}
},
};
}
// https://vite.dev/config/
export default defineConfig({
plugins: [
buildIIFEVersions(),
vue({
template: {
compilerOptions: {
// 将以 kuc- 开头的标签识别为自定义元素,避免 Vue 的警告
isCustomElement: (tag) => tag.startsWith('kuc-'),
},
},
}),
Components(), // 自动导入 Vue 组件
copy({
// 将打包 plugin 需要的文件复制到 dist 里面
targets: [
{ src: 'dist/index.html', dest: 'dist/src/html', rename: 'config.html' },
{ src: 'src/manifest.json', dest: 'dist/src' },
{ src: 'src/assets/*.js', dest: 'dist/src/js' },
{ src: 'src/assets/*.png', dest: 'dist/src/image' },
{ src: 'src/css/*', dest: 'dist/src/css' },
{ src: 'node_modules/kintone-ui-component/umd/kuc.min.js', dest: 'dist/src/js' },
],
hook: 'writeBundle' // 指定在何时复制文件
}),
replaceKucTagsPlugin(), // 自定义标签替换插件
],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'), // 配置 @ 别名指向 src 目录
},
},
build: {
rollupOptions: {
input: {
config: path.resolve(__dirname, 'index.html'),
},
output: {
entryFileNames: (chunkInfo) => {
return 'src/js/[name].js'; // 将入口文件输出为 JS 文件
},
assetFileNames: 'src/[ext]/[name].[ext]', // 设置资源文件输出路径
},
},
sourcemap: 'inline', // 生成内联 sourcemap 用于调试
},
});