update
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,6 +9,7 @@ lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-iife
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
# data-fetch-plugin
|
||||
# kintone-data-aggregator-plugin
|
||||
|
||||
1. コマンド:
|
||||
- `package.json`ファイルを開き、`scripts`内の`upload`コマンドのパラメータを接続する必要があるkintoneドメインに変更してください。
|
||||
|
||||
1
components.d.ts
vendored
1
components.d.ts
vendored
@@ -2,6 +2,7 @@
|
||||
// @ts-nocheck
|
||||
// Generated by unplugin-vue-components
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
// biome-ignore lint: disable
|
||||
export {}
|
||||
|
||||
/* prettier-ignore */
|
||||
|
||||
4327
package-lock.json
generated
4327
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -1,13 +1,11 @@
|
||||
{
|
||||
"name": "data-fetch-plugin",
|
||||
"name": "kintone-data-aggregator-plugin",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"preview": "vite preview",
|
||||
"build": "vite build && npm run pkg",
|
||||
"vite:build": "vite build",
|
||||
"build": "vite build && npm run pkg",
|
||||
"build-upload": "npm run build && npm run upload",
|
||||
"build-up2":"npm run build && npm run upload2",
|
||||
"pkg": "kintone-plugin-packer --ppk private.ppk --out dist/plugin.zip dist/src",
|
||||
@@ -15,7 +13,7 @@
|
||||
"upload2": "kintone-plugin-uploader --base-url https://alicorn.cybozu.com --username maxz --password 7ld7i8vd dist/plugin.zip "
|
||||
},
|
||||
"dependencies": {
|
||||
"@kintone/rest-api-client": "^5.7.0",
|
||||
"@kintone/rest-api-client": "^5.7.5",
|
||||
"kintone-ui-component": "1.18.0",
|
||||
"rollup-plugin-css-only": "^4.5.2",
|
||||
"vue": "^3.5.13",
|
||||
@@ -26,9 +24,11 @@
|
||||
"@kintone/dts-gen": "^8.1.1",
|
||||
"@kintone/plugin-packer": "^8.1.3",
|
||||
"@kintone/plugin-uploader": "^9.1.2",
|
||||
"@types/node-rsa": "^1.1.4",
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
"@vue/tsconfig": "^0.7.0",
|
||||
"eslint": "^8.57.0",
|
||||
"node-rsa": "^1.1.1",
|
||||
"rollup-plugin-copy": "^3.5.0",
|
||||
"typescript": "^5.7.3",
|
||||
"unplugin-vue-components": "^28.0.0",
|
||||
|
||||
26
private.ppk
26
private.ppk
@@ -1,15 +1,15 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQCF7z/zsYmoe+L1AYTeCYvy9yBXlsXOniTzox6svsXunibVP3y+
|
||||
f1jEwu2cnTdp/GABOzsVHNSrYGedRDlwG93Y8qxe7qNKLZAFL6ujmJ0FJixuYrh4
|
||||
xvaWR6SlKIbws+803qAyE6dUN893xeZeJdWGelZNBsCZu8Nwmi28k1flzQIDAQAB
|
||||
AoGAbWJchJZ2qtejIB5BeWWqmqAiFebZXkniO+j44HReCue3J2pWYu52fRwGG2Z7
|
||||
H2AyuE67jh6hweVWOibCEkFwCM+MwkSpKNRyFqJwdzZGoMm/oT67dDGYELrmNCx/
|
||||
9G5DdLgLXsA2dAANxTybaK8wg123Hhrh7NwJDETn9OC+uzECQQDeJTq4OSK9qUw9
|
||||
RCpgijpVdnzc4hC0CNjKe/+z8bQOPVcX7zLcggwX/7i2UmNxBxfYFrCN8XIGJNGN
|
||||
VXMpUdCjAkEAmliRAdgAJvoMvaS+gCcJt9tU18F2aunnGudpdwMWDFYdsnztLSJQ
|
||||
uLPsPQM0TJJYwXWZ+akQuReqXeKg4WgmzwJBAMZAg38VvqN1C81BoHA37IeJDzYx
|
||||
qqaBnrhWoYV+GCr9I1UA7GtOxGxGlBpivMyKgAUher+y0wgYo8t2jyg5E/ECQCRH
|
||||
JO42AvMmWtBIZK5ifppEZ1C/HEJM8BEWy2c5xnjn1NsbGfQ92JNRVvmQQz6sN0hh
|
||||
h+tynYej1Ft05TOV82kCQQCDd0/JtINW3Myj2nWIe8c9IjsBUtNOkaCa13tGOzwJ
|
||||
3G8Bg0GzdVSC73OnEaguC72kBvyGO4enUFkOq6p6kmFQ
|
||||
MIICXAIBAAKBgQCIkxa8JuBndXN0U/Fo+iX97nm03VYx0L4BBOfiUEB0innnLntF
|
||||
Nm6IN7gaR+D1G4CGV6NkM/s7xRUPDFLRFQM0DUTw/Su40jcFdHNLbTntlrzh6lGb
|
||||
ihPRficSP4Bu0nacTrLwEYwSp17Z95Ly2EliznuWh7ShaABaP6dfiy6SWwIDAQAB
|
||||
AoGAA9N7E5JTPxK/RUcEwFghsFd5+WMqAwNCD20/wctVwu4ONDfNJEc+GXrWIYZZ
|
||||
+wPmOd1Cqo/6PdZrnJxPxaO9DzFQelK4a+/5fXzOJm04d22Y8ezDJi9lsZ+wRG/8
|
||||
ViEchiTB2ZZsRy8MPCVNyW2i1XOKPVZHAbH8hRDx3atbFmECQQD7G9NeNf32cwke
|
||||
pDTa5bFoOQ9BOL44c1buf1eTIvY/aPBJG426ZXVEbCtknLBBiWj6+ESNKd7Zu8RE
|
||||
cNgALnbNAkEAizwhFEJTn1TK7zyC3BqysPkDgMpe6naBnnNI3DjsYZpTKdhP5auw
|
||||
cYe1nCyJgGdsY3OU1a8EOttOYxm4dAcdxwJAa483spsd9XrA5Ucg/MJ2g1Ytmppb
|
||||
oIKHMhGJyZSoNfEVO7t5seXTnUNYMviK5wec2COP+Yd91XYAU/CiFTHR4QJAH3xF
|
||||
brNg/ZLLITZp0SQobGSjKiiZNiP+Q7qGK2aj7Z5cWAYWazVb/RBXPS3FGkhI9mRY
|
||||
r8mYB0c4fqh+UZ6aWQJBAMkM+Zs5Htt8xWnX4MLcGUlBLuUq2012NtMDWqH1GPd9
|
||||
R5cyDpj2YCr3Wm6cASE7W2VXq6no8rMuoFm5vp4kR3c=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
12
scripts/privateKey.ts
Normal file
12
scripts/privateKey.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
'use strict';
|
||||
// @ts-ignore
|
||||
import RSA from 'node-rsa';
|
||||
|
||||
/**
|
||||
* Create a private key for a kintone plugin
|
||||
* Copy from https://github.com/kintone/js-sdk/blob/main/packages/create-plugin/src/privateKey.ts
|
||||
*/
|
||||
export const generatePrivateKey = () => {
|
||||
const key = new RSA({ b: 1024 });
|
||||
return key.exportKey('pkcs1-private');
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createApp } from 'vue';
|
||||
import Config from './components/Config.vue';
|
||||
import i18n from './i18n/index';
|
||||
import i18n from './i18n';
|
||||
|
||||
createApp(Config, { pluginId: kintone.$PLUGIN_ID }).use(i18n).mount('#app');
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
"./node_modules/@kintone/dts-gen/kintone.d.ts",
|
||||
],
|
||||
"compilerOptions": {
|
||||
"resolveJsonModule": true,
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
|
||||
143
vite.config.ts
143
vite.config.ts
@@ -1,10 +1,32 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import copy from "rollup-plugin-copy";
|
||||
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 { generatePrivateKey } from './scripts/privateKey';
|
||||
const packageJson = require('./package.json');
|
||||
|
||||
// 从 package.json 读取 kintone-ui-component 版本信息
|
||||
const kucVersion = packageJson.dependencies['kintone-ui-component'];
|
||||
const formattedVersion = kucVersion.replace(/\./g, '-'); // 例如:1.22.0 -> 1-22-0
|
||||
|
||||
// 判断是否为生产环境构建
|
||||
const isProd = process.env.BUILD_MODE === 'production';
|
||||
const buildMode = isProd ? 'production' : 'development';
|
||||
console.log(`Building IIFE versions in ${buildMode} mode...`);
|
||||
|
||||
// 检查 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',
|
||||
@@ -12,24 +34,28 @@ function replaceKucTagsPlugin() {
|
||||
if (id.endsWith('.vue')) {
|
||||
const content = await fs.promises.readFile(id, 'utf-8');
|
||||
|
||||
const usedComponent = {}
|
||||
const usedComponent = {};
|
||||
|
||||
// 替换 <kuc-*> 为带有版本号的形式 <kuc-[version]-*>
|
||||
let res = content
|
||||
.replace(/<\/kuc-([a-zA-Z0-9-]+)(?![0-9-])>/g, (match, p1) => `</kuc-${p1}-1-18-0>`)
|
||||
.replace(/<kuc-([a-zA-Z0-9-]+)(?![0-9-])([^>]*)>/g, (match, p1, p2) => {
|
||||
.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}-1-18-0${p2}>`
|
||||
return `<kuc-${p1}-${formattedVersion}${p2}>`;
|
||||
});
|
||||
|
||||
// 如果有 KUC 组件,自动生成 import 脚本
|
||||
if (Object.keys(usedComponent).length) {
|
||||
let importScript = '<script lang="ts">'
|
||||
let importScript = '<script lang="ts">';
|
||||
Object.keys(usedComponent).forEach((key) => {
|
||||
const keyPascal = key.split('-')
|
||||
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
||||
.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 += `import * as Kuc${keyPascal} from "kintone-ui-component/lib/${key}";`;
|
||||
});
|
||||
importScript += '</script>';
|
||||
res = importScript + res;
|
||||
@@ -37,52 +63,121 @@ function replaceKucTagsPlugin() {
|
||||
|
||||
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.iife.config.ts', { stdio: 'inherit', env: { ...process.env, PLATFORM: 'desktop' } });
|
||||
|
||||
// Build mobile IIFE
|
||||
console.log('Building mobile IIFE...');
|
||||
child_process.execSync('npx vite build --config vite.iife.config.ts', { stdio: 'inherit', env: { ...process.env, PLATFORM: 'mobile' } });
|
||||
|
||||
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: {
|
||||
isCustomElement: (tag) => tag.startsWith("kuc-"),
|
||||
}
|
||||
}
|
||||
// 将以 kuc- 开头的标签识别为自定义元素,避免 Vue 的警告
|
||||
isCustomElement: (tag) => tag.startsWith('kuc-'),
|
||||
},
|
||||
},
|
||||
}),
|
||||
Components(),
|
||||
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()
|
||||
replaceKucTagsPlugin(), // 自定义标签替换插件
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, 'src'),
|
||||
'@': path.resolve(__dirname, 'src'), // 配置 @ 别名指向 src 目录
|
||||
},
|
||||
},
|
||||
build: {
|
||||
rollupOptions: {
|
||||
input: {
|
||||
config: path.resolve(__dirname, 'index.html'),
|
||||
desktop: path.resolve(__dirname, 'src/js/desktop.ts'),
|
||||
mobile: path.resolve(__dirname, 'src/js/mobile.ts'),
|
||||
},
|
||||
output: {
|
||||
entryFileNames: (chunkInfo) => {
|
||||
return 'src/js/[name].js'; // 默认处理为 JS 文件
|
||||
return 'src/js/[name].js'; // 将入口文件输出为 JS 文件
|
||||
},
|
||||
assetFileNames: 'src/[ext]/[name].[ext]',
|
||||
assetFileNames: 'src/[ext]/[name].[ext]', // 设置资源文件输出路径
|
||||
},
|
||||
},
|
||||
sourcemap: 'inline',
|
||||
}
|
||||
})
|
||||
sourcemap: isProd ? false : 'inline', // 生产环境关闭 sourcemap,开发环境使用 inline
|
||||
minify: isProd ? 'terser' : false, // 生产环境使用 terser 混淆,开发环境不混淆
|
||||
...(isProd && {
|
||||
terserOptions: {
|
||||
compress: {
|
||||
drop_console: true, // 移除 console
|
||||
drop_debugger: true, // 移除 debugger
|
||||
pure_funcs: ['console.log'], // 移除 console.log
|
||||
},
|
||||
mangle: {
|
||||
toplevel: true, // 混淆顶级作用域的变量名
|
||||
},
|
||||
format: {
|
||||
comments: false, // 移除注释
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
72
vite.iife.config.ts
Normal file
72
vite.iife.config.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import * as path from 'path';
|
||||
import { defineConfig, UserConfig } from 'vite';
|
||||
const packageJson = require('./package.json');
|
||||
|
||||
/**
|
||||
* 生成 IIFE 配置的工厂函数
|
||||
* @param platform 'desktop' | 'mobile'
|
||||
*/
|
||||
function createIIFEConfig(platform: 'desktop' | 'mobile'): UserConfig {
|
||||
// 判断是否为生产环境构建
|
||||
const isProd = process.env.BUILD_MODE === 'production';
|
||||
|
||||
return {
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, 'src'),
|
||||
},
|
||||
},
|
||||
define: {
|
||||
'process.env.NODE_ENV': JSON.stringify('production'),
|
||||
'process.env': JSON.stringify({}),
|
||||
global: 'window',
|
||||
},
|
||||
build: {
|
||||
lib: {
|
||||
entry: path.resolve(__dirname, `src/js/${platform}.ts`),
|
||||
name: `${packageJson.name.replaceAll('-', '_')}_${platform}_iife`,
|
||||
formats: ['iife'],
|
||||
fileName: () => `${platform}.js`,
|
||||
},
|
||||
rollupOptions: {
|
||||
external: ['kintone'], // kintone 是网站提供的 api,需要处理
|
||||
output: {
|
||||
globals: {
|
||||
kintone: 'kintone',
|
||||
},
|
||||
},
|
||||
},
|
||||
outDir: path.resolve(__dirname, `dist-iife/${platform}`), // 输出到 dist-iife 目录
|
||||
sourcemap: isProd ? false : 'inline', // 生产环境关闭,开发环境使用 inline
|
||||
minify: isProd ? 'terser' : false, // 生产环境使用 terser 混淆,开发环境不混淆
|
||||
...(isProd && {
|
||||
terserOptions: {
|
||||
compress: {
|
||||
drop_console: true, // 移除 console
|
||||
drop_debugger: true, // 移除 debugger
|
||||
pure_funcs: ['console.log'], // 移除 console.log
|
||||
},
|
||||
mangle: {
|
||||
toplevel: true, // 混淆顶级作用域的变量名
|
||||
},
|
||||
format: {
|
||||
comments: false, // 移除注释
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// 根据环境变量决定构建哪个平台
|
||||
const platform = process.env.PLATFORM as 'desktop' | 'mobile';
|
||||
|
||||
if (!platform || !['desktop', 'mobile'].includes(platform)) {
|
||||
throw new Error('Please specify PLATFORM environment variable: desktop or mobile');
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一的 IIFE 构建配置
|
||||
* 用于将 desktop.ts 和 mobile.ts 打包为 IIFE 格式
|
||||
*/
|
||||
export default defineConfig(createIIFEConfig(platform));
|
||||
Reference in New Issue
Block a user