use IIFE for entry points.

This commit is contained in:
2025-07-03 18:24:31 +09:00
parent 5926c08da5
commit 83f29b8e63
12 changed files with 64 additions and 51 deletions

6
package-lock.json generated
View File

@@ -1638,9 +1638,9 @@
} }
}, },
"node_modules/@types/node-forge": { "node_modules/@types/node-forge": {
"version": "1.3.11", "version": "1.3.12",
"resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.12.tgz",
"integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", "integrity": "sha512-a0ToKlRVnUw3aXKQq2F+krxZKq7B8LEQijzPn5RdFAMatARD2JX9o8FBpMXOOrjob0uc13aN+V/AXniOXW4d9A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {

View File

@@ -10,7 +10,6 @@
"prebuild:prod": "npm run gen", "prebuild:prod": "npm run gen",
"build": "cross-env NODE_ENV=development rspack build", "build": "cross-env NODE_ENV=development rspack build",
"build:prod": "cross-env NODE_ENV=production rspack build", "build:prod": "cross-env NODE_ENV=production rspack build",
"dts-gen": "kintone-dts-gen",
"lint": "eslint src --ext .js,.jsx,.ts,.tsx", "lint": "eslint src --ext .js,.jsx,.ts,.tsx",
"upload": "env-cmd --silent kintone-plugin-uploader dist/plugin.zip --watch --waiting-dialog-ms 3000" "upload": "env-cmd --silent kintone-plugin-uploader dist/plugin.zip --watch --waiting-dialog-ms 3000"
}, },

View File

@@ -9,6 +9,8 @@ const isDev = process.env.NODE_ENV === 'development';
const targets = ['last 2 versions', '> 0.2%', 'not dead', 'Firefox ESR']; const targets = ['last 2 versions', '> 0.2%', 'not dead', 'Firefox ESR'];
export default defineConfig({ export default defineConfig({
mode: isDev ? 'development' : 'production',
devtool: isDev ? 'inline-cheap-module-source-map' : false,
entry: { config: './src/config/index.tsx', desktop: './src/desktop/index.tsx' }, entry: { config: './src/config/index.tsx', desktop: './src/desktop/index.tsx' },
output: { output: {
path: './plugin/js', path: './plugin/js',
@@ -17,7 +19,6 @@ export default defineConfig({
resolve: { resolve: {
extensions: ['...', '.ts', '.tsx', '.jsx'], extensions: ['...', '.ts', '.tsx', '.jsx'],
}, },
devtool: isDev ? 'inline-cheap-module-source-map' : false,
module: { module: {
rules: [ rules: [
{ {

1
src/common/constants.ts Normal file
View File

@@ -0,0 +1 @@
export const DOCX_CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';

View File

@@ -1,8 +1,5 @@
import invariant from 'tiny-invariant'; import invariant from 'tiny-invariant';
export const PLUGIN_ID = kintone.$PLUGIN_ID;
invariant(PLUGIN_ID, 'The PLUGIN_ID is not available. Please ensure you are on a Kintone plugin page.');
const KintoneUserLanguages = ['en', 'ja', 'zh', 'zh-TW', 'es', 'pt-BR', 'th'] as const; const KintoneUserLanguages = ['en', 'ja', 'zh', 'zh-TW', 'es', 'pt-BR', 'th'] as const;
export type KintoneUserLanguages = (typeof KintoneUserLanguages)[number]; export type KintoneUserLanguages = (typeof KintoneUserLanguages)[number];
export const LANGUAGE = kintone.getLoginUser().language as KintoneUserLanguages; export const LANGUAGE = kintone.getLoginUser().language as KintoneUserLanguages;
@@ -10,5 +7,3 @@ invariant(
KintoneUserLanguages.includes(LANGUAGE), KintoneUserLanguages.includes(LANGUAGE),
`Unsupported language: ${LANGUAGE}. Supported languages are: ${KintoneUserLanguages.join(', ')}`, `Unsupported language: ${LANGUAGE}. Supported languages are: ${KintoneUserLanguages.join(', ')}`,
); );
export const DOCX_CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';

View File

@@ -40,7 +40,7 @@
color: #f6f6f6; color: #f6f6f6;
} }
/* Row for the settings */ /* Row for the settings */
/* /*
<div class="kintoneplugin-row">Settings 1</div> <div class="kintoneplugin-row">Settings 1</div>
<div class="kintoneplugin-row">Settings 2</div> <div class="kintoneplugin-row">Settings 2</div>
@@ -49,7 +49,7 @@
margin-bottom: 24px; margin-bottom: 24px;
} }
/* Heading for each settings*/ /* Heading for each settings */
/* Heading */ /* Heading */
/* /*
<div class="kintoneplugin-label">Heading for the setting</div> <div class="kintoneplugin-label">Heading for the setting</div>
@@ -79,7 +79,7 @@
color: #888; color: #888;
} }
/* Required settings*/ /* Required settings */
/* /*
<div class="kintoneplugin-label">Title<span class="kintoneplugin-require">*</span></div> <div class="kintoneplugin-label">Title<span class="kintoneplugin-require">*</span></div>
*/ */

View File

@@ -5,11 +5,16 @@ import ErrorFallback from '../common/ErrorFallback';
import Loading from '../common/Loading'; import Loading from '../common/Loading';
import Settings from './Settings'; import Settings from './Settings';
const ConfigApp: React.FC = () => { interface ConfigAppProps {
pluginId: string;
}
const ConfigApp: React.FC<ConfigAppProps> = (props) => {
const { pluginId } = props;
return ( return (
<ErrorBoundary FallbackComponent={ErrorFallback}> <ErrorBoundary FallbackComponent={ErrorFallback}>
<React.Suspense fallback={<Loading />}> <React.Suspense fallback={<Loading />}>
<Settings /> <Settings pluginId={pluginId} />
</React.Suspense> </React.Suspense>
</ErrorBoundary> </ErrorBoundary>
); );

View File

@@ -3,7 +3,6 @@ import React from 'react';
import { KintoneRestAPIClient } from '@kintone/rest-api-client'; import { KintoneRestAPIClient } from '@kintone/rest-api-client';
import moize from 'moize'; import moize from 'moize';
import invariant from 'tiny-invariant'; import invariant from 'tiny-invariant';
import { PLUGIN_ID } from '../common/global';
import { naturalCompare } from '../common/stringUtils'; import { naturalCompare } from '../common/stringUtils';
import { KintoneFormFieldProperties } from '../common/types'; import { KintoneFormFieldProperties } from '../common/types';
import KintonePluginAlert from '../common/ui/KintonePluginAlert'; import KintonePluginAlert from '../common/ui/KintonePluginAlert';
@@ -23,8 +22,13 @@ const cachedFormFieldsProperties = moize.promise(async (appId: number): Promise<
return properties; return properties;
}); });
const Settings: React.FC = () => { interface SettingsProps {
const config = kintone.plugin.app.getConfig(PLUGIN_ID); pluginId: string;
}
const Settings: React.FC<SettingsProps> = (props) => {
const { pluginId } = props;
const config = kintone.plugin.app.getConfig(pluginId);
const appId = kintone.app.getId(); const appId = kintone.app.getId();
invariant(appId, 'The app ID is not available. Please ensure you are on a Kintone app page.'); invariant(appId, 'The app ID is not available. Please ensure you are on a Kintone app page.');
const properties = React.use(cachedFormFieldsProperties(appId)); const properties = React.use(cachedFormFieldsProperties(appId));

View File

@@ -6,11 +6,13 @@ import ConfigApp from './ConfigApp';
import '../common/ui/51-modern-default.css'; import '../common/ui/51-modern-default.css';
const root = document.getElementById('plugin-config-root'); ((PLUGIN_ID) => {
invariant(root, 'The plugin configuration root element "plugin-config-root" is not found.'); const root = document.getElementById('plugin-config-root');
invariant(root, 'The plugin configuration root element "plugin-config-root" is not found.');
ReactDOM.createRoot(root).render( ReactDOM.createRoot(root).render(
<React.StrictMode> <React.StrictMode>
<ConfigApp /> <ConfigApp pluginId={PLUGIN_ID} />
</React.StrictMode>, </React.StrictMode>,
); );
})(kintone.$PLUGIN_ID);

View File

@@ -6,15 +6,16 @@ import Loading from '../common/Loading';
import MenuPanel from './MenuPanel'; import MenuPanel from './MenuPanel';
interface DesktopAppProps { interface DesktopAppProps {
pluginId: string;
event: kintone.events.AppRecordDetailShowEvent | kintone.events.MobileAppRecordDetailShowEvent; event: kintone.events.AppRecordDetailShowEvent | kintone.events.MobileAppRecordDetailShowEvent;
} }
const DesktopApp: React.FC<DesktopAppProps> = (props) => { const DesktopApp: React.FC<DesktopAppProps> = (props) => {
const { event } = props; const { pluginId, event } = props;
return ( return (
<ErrorBoundary FallbackComponent={ErrorFallback}> <ErrorBoundary FallbackComponent={ErrorFallback}>
<React.Suspense fallback={<Loading />}> <React.Suspense fallback={<Loading />}>
<MenuPanel event={event} /> <MenuPanel pluginId={pluginId} event={event} />
</React.Suspense> </React.Suspense>
</ErrorBoundary> </ErrorBoundary>
); );

View File

@@ -9,7 +9,8 @@ import { saveAs } from 'file-saver';
import moize from 'moize'; import moize from 'moize';
import PizZip from 'pizzip'; import PizZip from 'pizzip';
import invariant from 'tiny-invariant'; import invariant from 'tiny-invariant';
import { DOCX_CONTENT_TYPE, LANGUAGE, PLUGIN_ID } from '../common/global'; import { DOCX_CONTENT_TYPE } from '../common/constants';
import { LANGUAGE } from '../common/kintoneUtils';
import { KintoneFormFieldProperties } from '../common/types'; import { KintoneFormFieldProperties } from '../common/types';
import KintonePluginAlert from '../common/ui/KintonePluginAlert'; import KintonePluginAlert from '../common/ui/KintonePluginAlert';
import KintonePluginButton from '../common/ui/KintonePluginButton'; import KintonePluginButton from '../common/ui/KintonePluginButton';
@@ -19,6 +20,7 @@ interface TemplateData {
} }
interface MenuPanelProps { interface MenuPanelProps {
pluginId: string;
event: kintone.events.AppRecordDetailShowEvent | kintone.events.MobileAppRecordDetailShowEvent; event: kintone.events.AppRecordDetailShowEvent | kintone.events.MobileAppRecordDetailShowEvent;
} }
@@ -181,10 +183,10 @@ const record2data = (properties: KintoneFormFieldProperties, record: Partial<Kin
}; };
const MenuPanel: React.FC<MenuPanelProps> = (props) => { const MenuPanel: React.FC<MenuPanelProps> = (props) => {
const { event } = props; const { pluginId, event } = props;
const appId = event.appId; const appId = event.appId;
const properties = React.use(cachedFormFieldsProperties(appId)); const properties = React.use(cachedFormFieldsProperties(appId));
const config = kintone.plugin.app.getConfig(PLUGIN_ID); const config = kintone.plugin.app.getConfig(pluginId);
const template: string = config.template ?? ''; const template: string = config.template ?? '';
if (template === '') { if (template === '') {
return ( return (
@@ -218,6 +220,7 @@ const MenuPanel: React.FC<MenuPanelProps> = (props) => {
</KintonePluginAlert> </KintonePluginAlert>
); );
} }
const handleOnClickOutputButton = (e: React.MouseEvent<HTMLButtonElement>) => { const handleOnClickOutputButton = (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault(); e.preventDefault();
const client = new KintoneRestAPIClient(); const client = new KintoneRestAPIClient();

View File

@@ -6,27 +6,29 @@ import DesktopApp from './DesktopApp';
import '../common/ui/51-modern-default.css'; import '../common/ui/51-modern-default.css';
kintone.events.on( ((PLUGIN_ID) => {
['app.record.detail.show', 'mobile.app.record.detail.show'], kintone.events.on(
async (event: kintone.events.AppRecordDetailShowEvent | kintone.events.MobileAppRecordDetailShowEvent) => { ['app.record.detail.show', 'mobile.app.record.detail.show'],
const spaceElement = async (event: kintone.events.AppRecordDetailShowEvent | kintone.events.MobileAppRecordDetailShowEvent) => {
event.type === 'app.record.detail.show' const spaceElement =
? kintone.app.record.getHeaderMenuSpaceElement() event.type === 'app.record.detail.show'
: kintone.mobile.app.getHeaderSpaceElement(); ? kintone.app.record.getHeaderMenuSpaceElement()
invariant( : kintone.mobile.app.getHeaderSpaceElement();
spaceElement, invariant(
'The header menu space element is not available. Please ensure you are on a Kintone app record detail page.', spaceElement,
); 'The header menu space element is not available. Please ensure you are on a Kintone app record detail page.',
);
const root = document.createElement('div'); const root = document.createElement('div');
spaceElement.appendChild(root); spaceElement.appendChild(root);
ReactDOM.createRoot(root).render( ReactDOM.createRoot(root).render(
<React.StrictMode> <React.StrictMode>
<DesktopApp event={event} /> <DesktopApp pluginId={PLUGIN_ID} event={event} />
</React.StrictMode>, </React.StrictMode>,
); );
return event; return event;
}, },
); );
})(kintone.$PLUGIN_ID);