From 7d85b4262f1b4443c651397d5b8dc8f2ff78caa3 Mon Sep 17 00:00:00 2001 From: Chan Kang Date: Tue, 26 Aug 2025 12:25:43 +0900 Subject: [PATCH 1/5] feat: add VITE_CONFIGURATION_FILENAME constants --- src/constants/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/constants/index.ts b/src/constants/index.ts index a16df06..e871067 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -9,6 +9,8 @@ export const DIST_DIRECTORY_NAME = 'dist'; export const WEB_OUTPUT_DIRECTORY = path.join(PROJECT_DIRECTORY, `/${DIST_DIRECTORY_NAME}/tmp/widgets`); +export const VITE_CONFIGURATION_FILENAME = 'vite.config.mjs'; + export const COLOR_NAME = chalk.bold.blueBright; export const COLOR_ERROR = chalk.bold.red; From bc29b71a40b02372450f6d677345b2fa3d797ea6 Mon Sep 17 00:00:00 2001 From: Chan Kang Date: Tue, 26 Aug 2025 12:26:02 +0900 Subject: [PATCH 2/5] feat: add typescript configurations --- package.json | 17 ++++++++++++++--- pnpm-lock.yaml | 22 ++++++++++++++++++---- rslib.config.ts | 48 ++++++++++++++++++++++++++++++++++++++++++------ tsconfig.json | 11 +++++++++++ 4 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 tsconfig.json diff --git a/package.json b/package.json index 0c09998..4d6aadd 100644 --- a/package.json +++ b/package.json @@ -9,11 +9,21 @@ "scripts": { "build": "rslib build", "watch": "rslib build --watch", - "start": "pnpm build && node ./dist/index.js", + "start": "pnpm build && node ./dist/cli.js", "link": "pnpm build && npm link --force" }, + "main": "dist/index.cjs", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.mjs", + "require": "./dist/index.cjs", + "types": "./dist/index.d.ts" + } + }, "bin": { - "hyper-pwt": "dist/index.js" + "hyper-pwt": "dist/cli.js" }, "keywords": [ "mendix", @@ -27,7 +37,8 @@ "devDependencies": { "@rslib/core": "0.12.2", "@types/node": "22.17.2", - "type-fest": "4.41.0" + "type-fest": "4.41.0", + "typescript": "^5.9.2" }, "dependencies": { "@vitejs/plugin-react-swc": "4.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3ffa0a4..52098b6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,13 +26,16 @@ importers: devDependencies: '@rslib/core': specifier: 0.12.2 - version: 0.12.2 + version: 0.12.2(typescript@5.9.2) '@types/node': specifier: 22.17.2 version: 22.17.2 type-fest: specifier: 4.41.0 version: 4.41.0 + typescript: + specifier: ^5.9.2 + version: 5.9.2 packages: @@ -946,6 +949,11 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} + typescript@5.9.2: + resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} + engines: {node: '>=14.17'} + hasBin: true + undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -1269,11 +1277,13 @@ snapshots: core-js: 3.45.1 jiti: 2.5.1 - '@rslib/core@0.12.2': + '@rslib/core@0.12.2(typescript@5.9.2)': dependencies: '@rsbuild/core': 1.5.0-beta.4 - rsbuild-plugin-dts: 0.12.2(@rsbuild/core@1.5.0-beta.4) + rsbuild-plugin-dts: 0.12.2(@rsbuild/core@1.5.0-beta.4)(typescript@5.9.2) tinyglobby: 0.2.14 + optionalDependencies: + typescript: 5.9.2 '@rspack/binding-darwin-arm64@1.5.0-beta.1': optional: true @@ -1712,7 +1722,7 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.46.4 fsevents: 2.3.3 - rsbuild-plugin-dts@0.12.2(@rsbuild/core@1.5.0-beta.4): + rsbuild-plugin-dts@0.12.2(@rsbuild/core@1.5.0-beta.4)(typescript@5.9.2): dependencies: '@ast-grep/napi': 0.37.0 '@rsbuild/core': 1.5.0-beta.4 @@ -1720,6 +1730,8 @@ snapshots: picocolors: 1.1.1 tinyglobby: 0.2.14 tsconfig-paths: 4.2.0 + optionalDependencies: + typescript: 5.9.2 safe-buffer@5.1.2: {} @@ -1797,6 +1809,8 @@ snapshots: type-fest@4.41.0: {} + typescript@5.9.2: {} + undici-types@6.21.0: {} util-deprecate@1.0.2: {} diff --git a/rslib.config.ts b/rslib.config.ts index f51f381..70632f4 100644 --- a/rslib.config.ts +++ b/rslib.config.ts @@ -4,14 +4,50 @@ export default defineConfig({ lib: [ { format: 'cjs', - bundle: true + bundle: true, + dts: true, + source: { + entry: { + cli: 'src/cli.ts' + } + }, + output: { + filename: { + js: '[name].js' + } + } + }, + { + format: 'esm', + bundle: true, + dts: true, + source: { + entry: { + index: 'src/index.ts' + } + }, + output: { + filename: { + js: '[name].mjs' + } + } + }, + { + format: 'cjs', + bundle: true, + dts: false, + source: { + entry: { + index: 'src/index.ts' + } + }, + output: { + filename: { + js: '[name].cjs' + } + } } ], - source: { - entry: { - index: 'src/cli.ts' - } - }, output: { minify: { js: true, diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..e52987c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "include": ["src/**/*"], + "exclude": ["node_modules"], + "compilerOptions": { + "resolveJsonModule": true, + "esModuleInterop": true, + "lib": ["ESNext"], + "module": "preserve", + "moduleResolution": "bundler" + }, +} \ No newline at end of file From bfca81d90b06a5843e5e1a7fa87620cb1d98d5c9 Mon Sep 17 00:00:00 2001 From: Chan Kang Date: Tue, 26 Aug 2025 12:26:13 +0900 Subject: [PATCH 3/5] feat: add vite custom configuration --- src/commands/build/web/index.ts | 19 ++++++++++--------- src/commands/start/web/index.ts | 9 +++++---- src/configurations/vite/index.ts | 5 +++-- src/index.ts | 13 +++++++++++++ src/utils/getViteUserConfiguration.ts | 17 +++++++++++++++++ 5 files changed, 48 insertions(+), 15 deletions(-) create mode 100644 src/index.ts create mode 100644 src/utils/getViteUserConfiguration.ts diff --git a/src/commands/build/web/index.ts b/src/commands/build/web/index.ts index 7c13170..05a0188 100644 --- a/src/commands/build/web/index.ts +++ b/src/commands/build/web/index.ts @@ -3,7 +3,7 @@ import path from 'path'; import { InlineConfig, UserConfig, build as viteBuild } from 'vite'; import { zip } from 'zip-a-folder'; -import { COLOR_ERROR, COLOR_GREEN, DIST_DIRECTORY_NAME, PROJECT_DIRECTORY, WEB_OUTPUT_DIRECTORY } from '../../../constants'; +import { COLOR_ERROR, COLOR_GREEN, DIST_DIRECTORY_NAME, PROJECT_DIRECTORY, VITE_CONFIGURATION_FILENAME, WEB_OUTPUT_DIRECTORY } from '../../../constants'; import pathIsExists from '../../../utils/pathIsExists'; import getWidgetVersion from '../../../utils/getWidgetVersion'; import showMessage from '../../../utils/showMessage'; @@ -11,9 +11,10 @@ import { getEditorConfigDefaultConfig, getEditorPreviewDefaultConfig, getViteDef import getWidgetName from '../../../utils/getWidgetName'; import getWidgetPackageJson from '../../../utils/getWidgetPackageJson'; import getMendixWidgetDirectory from '../../../utils/getMendixWidgetDirectory'; +import getViteUserConfiguration from '../../../utils/getViteUserConfiguration'; const buildWebCommand = async (isProduction: boolean = false) => { - try { + // try { showMessage('Remove previous builds'); const distDir = path.join(PROJECT_DIRECTORY, DIST_DIRECTORY_NAME); @@ -33,16 +34,16 @@ const buildWebCommand = async (isProduction: boolean = false) => { await fs.mkdir(outputDir); await fs.mkdir(WEB_OUTPUT_DIRECTORY, { recursive: true }); - const customViteConfigPath = path.join(PROJECT_DIRECTORY, 'vite.config.ts'); + const customViteConfigPath = path.join(PROJECT_DIRECTORY, VITE_CONFIGURATION_FILENAME); const viteConfigIsExists = await pathIsExists(customViteConfigPath); let resultViteConfig: UserConfig; if (viteConfigIsExists) { - const userConfig: UserConfig = await import(customViteConfigPath); + const userConfig = await getViteUserConfiguration(customViteConfigPath); - resultViteConfig = await getViteDefaultConfig(isProduction, userConfig); + resultViteConfig = await getViteDefaultConfig(false, userConfig); } else { - resultViteConfig = await getViteDefaultConfig(isProduction); + resultViteConfig = await getViteDefaultConfig(false); } const widgetName = await getWidgetName(); @@ -93,9 +94,9 @@ const buildWebCommand = async (isProduction: boolean = false) => { await fs.copyFile(mpkFileDestPath, mendixMpkFileDestPath); showMessage(`${COLOR_GREEN('Build complete.')}`); - } catch (error) { - showMessage(`${COLOR_ERROR('Build failed.')}\nError occurred: ${COLOR_ERROR((error as Error).message)}`); - } + // } catch (error) { + // showMessage(`${COLOR_ERROR('Build failed.')}\nError occurred: ${COLOR_ERROR((error as Error).stack)}`); + // } }; export default buildWebCommand; \ No newline at end of file diff --git a/src/commands/start/web/index.ts b/src/commands/start/web/index.ts index b662b58..724f177 100644 --- a/src/commands/start/web/index.ts +++ b/src/commands/start/web/index.ts @@ -1,26 +1,27 @@ import fs from 'fs/promises'; import path from 'path'; import { UserConfig, createServer } from 'vite'; +import { PluginOption } from 'vite'; -import { CLI_DIRECTORY, COLOR_ERROR, COLOR_GREEN, PROJECT_DIRECTORY } from "../../../constants"; +import { CLI_DIRECTORY, COLOR_ERROR, COLOR_GREEN, PROJECT_DIRECTORY, VITE_CONFIGURATION_FILENAME } from "../../../constants"; import showMessage from "../../../utils/showMessage"; import getViteWatchOutputDirectory from "../../../utils/getViteWatchOutputDirectory"; import pathIsExists from "../../../utils/pathIsExists"; import { getViteDefaultConfig } from '../../../configurations/vite'; import getWidgetName from '../../../utils/getWidgetName'; -import { PluginOption } from 'vite'; +import getViteUserConfiguration from '../../../utils/getViteUserConfiguration'; const startWebCommand = async () => { try { showMessage('Start widget server'); - const customViteConfigPath = path.join(PROJECT_DIRECTORY, 'vite.config.ts'); + const customViteConfigPath = path.join(PROJECT_DIRECTORY, VITE_CONFIGURATION_FILENAME); const viteConfigIsExists = await pathIsExists(customViteConfigPath); let resultViteConfig: UserConfig; const widgetName = await getWidgetName(); if (viteConfigIsExists) { - const userConfig: UserConfig = await import(customViteConfigPath); + const userConfig = await getViteUserConfiguration(customViteConfigPath); resultViteConfig = await getViteDefaultConfig(false, userConfig); } else { diff --git a/src/configurations/vite/index.ts b/src/configurations/vite/index.ts index 4792c8a..f214deb 100644 --- a/src/configurations/vite/index.ts +++ b/src/configurations/vite/index.ts @@ -5,6 +5,7 @@ import path from "path"; import getWidgetName from "../../utils/getWidgetName"; import { PROJECT_DIRECTORY, WEB_OUTPUT_DIRECTORY } from "../../constants"; import getViteOutputDirectory from "../../utils/getViteOutputDirectory"; +import { PWTConfig } from "../.."; export const getEditorConfigDefaultConfig = async (isProduction: boolean): Promise => { const widgetName = await getWidgetName(); @@ -64,12 +65,12 @@ export const getEditorPreviewDefaultConfig = async (isProduction: boolean): Prom }; }; -export const getViteDefaultConfig = async (isProduction: boolean, userCustomConfig?: UserConfig): Promise => { +export const getViteDefaultConfig = async (isProduction: boolean, userCustomConfig?: PWTConfig): Promise => { const widgetName = await getWidgetName(); const viteOutputDirectory = await getViteOutputDirectory(); return { - plugins: [react()], + plugins: [react(userCustomConfig?.reactPluginOptions || undefined)], define: { 'process.env': {}, 'process.env.NODE_ENV': isProduction ? '"production"' : '"development"' diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..944dae6 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,13 @@ +import type { UserConfig } from "vite"; +import reactPlugin from "@vitejs/plugin-react-swc"; + +export type PWTConfig = UserConfig & { + reactPluginOptions?: Parameters[0]; +}; + +export type PWTConfigFnPromise = () => Promise; +export type PWTConfigFn = () => PWTConfig | Promise; + +export function definePWTConfig(config: PWTConfigFn | PWTConfigFnPromise): PWTConfigFn | PWTConfigFnPromise { + return config; +} diff --git a/src/utils/getViteUserConfiguration.ts b/src/utils/getViteUserConfiguration.ts new file mode 100644 index 0000000..3483564 --- /dev/null +++ b/src/utils/getViteUserConfiguration.ts @@ -0,0 +1,17 @@ +import { PWTConfig, PWTConfigFn, PWTConfigFnPromise } from ".."; + +const getViteUserConfiguration = async (path: string): Promise => { + const getUserConfig = await import(`file://${path}`); + const getUserConfigFn: PWTConfigFn | PWTConfigFnPromise = getUserConfig.default; + const userConfig = getUserConfigFn(); + + if (userConfig instanceof Promise) { + const userConfigValue = await userConfig; + + return userConfigValue; + } + + return userConfig; +}; + +export default getViteUserConfiguration; \ No newline at end of file From 72564b3b7f66da1c4bf2f065c154b211738e00af Mon Sep 17 00:00:00 2001 From: Chan Kang Date: Tue, 26 Aug 2025 12:29:22 +0900 Subject: [PATCH 4/5] feat: add custom build readme --- README.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/README.md b/README.md index 2ea1bdb..6728ef5 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,49 @@ Second, replace pluggable-widgets-tools to hyper-pwt in widget's package.json. ## Custom build configurations +### Web + +Create vite.config.mjs on your pwt root directory. + +```javascript +import { definePWTConfig } from '@repixelcorp/hyper-pwt'; + +export default definePWTConfig(() => { + return { + // Your custom configuration in here. + }; +}); +``` + +hyper-pwt uses the [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react-swc) plugin. The settings for this plugin can be changed as follows. + +```javascript +import { definePWTConfig } from '@repixelcorp/hyper-pwt'; + +export default definePWTConfig(() => { + return { + reactPluginOptions: { + tsDecorators: true, + } + }; +}); +``` + +definePWTConfig also supports asynchronous mode. It can be used as follows. + +```javascript +import { definePWTConfig } from '@repixelcorp/hyper-pwt'; + +export default definePWTConfig(async () => { + const promise = await somethingPromise(); + + return { + }; +}); +``` + +### Native + TODO ## Performance compare with Mendix PWT From 444102d0f46912fb7af66dd9e74ee36db0e3ccaa Mon Sep 17 00:00:00 2001 From: Chan Kang Date: Tue, 26 Aug 2025 12:29:36 +0900 Subject: [PATCH 5/5] feat: bump version to 0.1.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4d6aadd..4acaca3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@repixelcorp/hyper-pwt", - "version": "0.1.1", + "version": "0.1.2", "description": "A faster, more modern, superior alternative for Mendix PWT.", "repository": { "type": "git",