diff --git a/README.md b/README.md index 947a8c3..09f0c03 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,8 @@ # UserScript Project Template -[![GitHub license](https://img.shields.io/github/license/JosunLP/UserScriptProjectTemplate?style=for-the-badge)](https://github.com/JosunLP/UserScriptProjectTemplate/blob/main/LICENSE) -[![GitHub issues](https://img.shields.io/github/issues/JosunLP/UserScriptProjectTemplate?style=for-the-badge)](https://github.com/JosunLP/UserScriptProjectTemplate/issues) -[![GitHub stars](https://img.shields.io/github/stars/JosunLP/UserScriptProjectTemplate?style=for-the-badge)](https://github.com/JosunLP/UserScriptProjectTemplate/stargazers) -[![GitHub forks](https://img.shields.io/github/forks/JosunLP/UserScriptProjectTemplate?style=for-the-badge)](https://github.com/JosunLP/UserScriptProjectTemplate/network) - -[![TypeScript](https://img.shields.io/badge/TypeScript-5.4+-blue?logo=typescript&style=for-the-badge)](https://www.typescriptlang.org/) -[![Vite](https://img.shields.io/badge/Vite-7.0+-646CFF?logo=vite&style=for-the-badge)](https://vitejs.dev/) -[![ESLint](https://img.shields.io/badge/ESLint-8.57+-4B32C3?logo=eslint&style=for-the-badge)](https://eslint.org/) -[![Prettier](https://img.shields.io/badge/Prettier-3.6+-F7B93E?logo=prettier&style=for-the-badge)](https://prettier.io/) -[![Node.js](https://img.shields.io/badge/Node.js-18+-339933?logo=node.js&style=for-the-badge)](https://nodejs.org/) - -[![Tampermonkey](https://img.shields.io/badge/Tampermonkey-Compatible-00485B?logo=tampermonkey&style=for-the-badge)](https://www.tampermonkey.net/) -[![Greasemonkey](https://img.shields.io/badge/Greasemonkey-Compatible-FF6600?logo=firefox&style=for-the-badge)](https://www.greasespot.net/) -[![Violentmonkey](https://img.shields.io/badge/Violentmonkey-Compatible-663399?logo=violentmonkey&style=for-the-badge)](https://violentmonkey.github.io/) -[![Mobile Support](https://img.shields.io/badge/Mobile-Support-00C851?logo=android&style=for-the-badge)](https://github.com/JosunLP/UserScriptProjectTemplate#mobile-browser-support) - -[![Last Commit](https://img.shields.io/github/last-commit/JosunLP/UserScriptProjectTemplate?style=for-the-badge)](https://github.com/JosunLP/UserScriptProjectTemplate/commits) -[![Contributors](https://img.shields.io/github/contributors/JosunLP/UserScriptProjectTemplate?style=for-the-badge)](https://github.com/JosunLP/UserScriptProjectTemplate/graphs/contributors) -[![Repository Size](https://img.shields.io/github/repo-size/JosunLP/UserScriptProjectTemplate?style=for-the-badge)](https://github.com/JosunLP/UserScriptProjectTemplate) +[![GitHub license](https://img.shields.io/github/license/JosunLP/UserScriptProjectTemplate)](https://github.com/JosunLP/UserScriptProjectTemplate/blob/main/LICENSE) +[![GitHub issues](https://img.shields.io/github/issues/JosunLP/UserScriptProjectTemplate)](https://github.com/JosunLP/UserScriptProjectTemplate/issues) +[![GitHub stars](https://img.shields.io/github/stars/JosunLP/UserScriptProjectTemplate)](https://github.com/JosunLP/UserScriptProjectTemplate/stargazers) ## Description @@ -26,19 +10,19 @@ A modern, production-ready template for building UserScripts using TypeScript an ## Features -- ๐Ÿš€ **Modern Tech Stack:** TypeScript, Vite, ESLint, Prettier -- ๐Ÿ›ก๏ธ **Type Safety:** Strict TypeScript configuration with comprehensive UserScript API definitions -- ๐Ÿ”ง **Development Tools:** ESLint, Prettier, automated build pipeline -- ๐ŸŽฏ **Environment Support:** Separate development and production configurations -- ๐Ÿ“ฆ **Modular Architecture:** Component system with reusable utilities -- ๐Ÿ’พ **Storage Management:** Type-safe wrapper for GM_setValue/GM_getValue -- ๐Ÿ› ๏ธ **Build System:** Optimized Vite configuration with automatic header generation -- ๐ŸŽจ **DOM Utilities:** Helper functions for element manipulation and waiting -- ๐Ÿ”’ **Error Handling:** Comprehensive error boundary system -- โšก **Event System:** Type-safe event emitter for module communication -- ๐Ÿ“ฑ **Mobile Support:** Touch-optimized interface with mobile browser detection -- ๐Ÿค **Touch Gestures:** Built-in touch event handling and gesture recognition -- ๐Ÿ“ฒ **Responsive Design:** Mobile-first CSS with safe area support for notched devices +โ€ข ๐Ÿš€ **Modern Tech Stack:** TypeScript, Vite, ESLint, Prettier +โ€ข ๐Ÿ›ก๏ธ **Type Safety:** Strict TypeScript configuration with comprehensive UserScript API definitions +โ€ข ๐Ÿ”ง **Development Tools:** ESLint, Prettier, automated build pipeline +โ€ข ๐ŸŽฏ **Environment Support:** Separate development and production configurations +โ€ข ๐Ÿ“ฆ **Modular Architecture:** Component system with reusable utilities +โ€ข ๐Ÿ’พ **Storage Management:** Type-safe wrapper for GM_setValue/GM_getValue +โ€ข ๐Ÿ› ๏ธ **Build System:** Optimized Vite configuration with automatic header generation +โ€ข ๐ŸŽจ **DOM Utilities:** Helper functions for element manipulation and waiting +โ€ข ๐Ÿ”’ **Error Handling:** Comprehensive error boundary system +โ€ข โšก **Event System:** Type-safe event emitter for module communication +โ€ข ๐Ÿ“ฑ **Mobile Support:** Touch-optimized interface with mobile browser detection +โ€ข ๐Ÿค **Touch Gestures:** Built-in touch event handling and gesture recognition +โ€ข ๐Ÿ“ฒ **Responsive Design:** Mobile-first CSS with safe area support for notched devices ## Installation @@ -80,9 +64,9 @@ src/ tools/ โ”œโ”€โ”€ userScriptHeader.ts # UserScript header generator +โ””โ”€โ”€ userScriptHeader.js # Compiled header generator assets/ # Icons and static resources -โ””โ”€โ”€ icon.afdesign ``` ### Configuration @@ -126,25 +110,6 @@ npm run clean # Clean dist folder npm run type-check # TypeScript type checking ``` -### Build Optimization - -The template features advanced build optimization for production: - -| Build Type | File Size | Compressed | Features | -| --------------- | --------- | ---------- | -------------------------------------- | -| **Development** | ~115 KB | ~30 KB | Source maps, debug info, readable code | -| **Production** | ~25 KB | ~6 KB | Minified, tree-shaken, optimized | - -**Production optimizations include:** - -- โšก **Terser minification** with aggressive compression settings -- ๐ŸŒณ **Tree-shaking** to remove unused code -- ๐ŸŽฏ **Dead code elimination** for **DEV** blocks -- ๐Ÿ“ฆ **Module inlining** for single-file output -- ๐Ÿ”ง **Property mangling** for smaller variable names -- ๐Ÿš€ **ES2020 target** for modern JavaScript features -- ๐Ÿ’พ **GZIP compression** reducing size by ~75% - ### Development Workflow 1. **Configure your script** in `header.config.json` @@ -275,10 +240,10 @@ console.log('Portrait mode:', MobileUtils.isPortrait()); ## UserScript Compatibility -- **Tampermonkey:** Full support with all GM\_\* APIs -- **Greasemonkey:** Compatible with standard UserScript APIs -- **Violentmonkey:** Full compatibility -- **Safari:** Works with userscript managers +โ€ข **Tampermonkey:** Full support with all GM\_\* APIs +โ€ข **Greasemonkey:** Compatible with standard UserScript APIs +โ€ข **Violentmonkey:** Full compatibility +โ€ข **Safari:** Works with userscript managers ### Mobile Browser Support @@ -296,11 +261,11 @@ console.log('Portrait mode:', MobileUtils.isPortrait()); ### Mobile Features -- **Touch Gestures:** Tap, swipe, and pinch detection -- **Responsive Design:** Mobile-first CSS with viewport adaptation -- **Safe Area Support:** Automatic handling of notched devices -- **Orientation Detection:** Portrait/landscape change handling -- **Mobile-Optimized UI:** Touch-friendly buttons and menus +โ€ข **Touch Gestures:** Tap, swipe, and pinch detection +โ€ข **Responsive Design:** Mobile-first CSS with viewport adaptation +โ€ข **Safe Area Support:** Automatic handling of notched devices +โ€ข **Orientation Detection:** Portrait/landscape change handling +โ€ข **Mobile-Optimized UI:** Touch-friendly buttons and menus ## Contributing @@ -313,12 +278,12 @@ console.log('Portrait mode:', MobileUtils.isPortrait()); ## Development Guidelines -- Follow TypeScript best practices -- Use meaningful variable and function names -- Add proper error handling -- Write self-documenting code -- Follow the established project structure -- Run `npm run validate` before committing +โ€ข Follow TypeScript best practices +โ€ข Use meaningful variable and function names +โ€ข Add proper error handling +โ€ข Write self-documenting code +โ€ข Follow the established project structure +โ€ข Run `npm run validate` before committing ## License @@ -328,9 +293,23 @@ This project is licensed under the [MIT License](https://opensource.org/licenses **_Jonas Pfalzgraf_** -- Email: [info@josunlp.de](mailto:info@josunlp.de) -- GitHub: [@JosunLP](https://github.com/JosunLP) -- Website: [josunlp.de](https://josunlp.de) +โ€ข Email: [info@josunlp.de](mailto:info@josunlp.de) +โ€ข GitHub: [@JosunLP](https://github.com/JosunLP) + +## Changelog + +### v0.0.1 (Current) + +โ€ข โœจ Modern TypeScript setup with strict type checking +โ€ข ๐Ÿ›ก๏ธ Comprehensive UserScript API definitions +โ€ข ๐ŸŽจ Modular architecture with utilities and components +โ€ข ๐Ÿ”ง ESLint and Prettier configuration +โ€ข ๐Ÿ“ฆ Optimized Vite build system +โ€ข ๐Ÿš€ Environment-based configuration +โ€ข ๐Ÿ’พ Type-safe storage management +โ€ข ๐ŸŽฏ Event-driven module system +โ€ข โšก DOM manipulation utilities +โ€ข ๐Ÿ› ๏ธ Automated header generation --- diff --git a/package.json b/package.json index af697bd..2cc8412 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "dev:header": "npm run build-userScriptHeader", "dev:build": "vite build --mode development && npm run build-userScriptHeader", "build": "vite build && npm run build-userScriptHeader", - "build:prod": "npm run clean && vite build --mode production && npm run build-userScriptHeader", + "build:prod": "vite build --mode production && npm run build-userScriptHeader", "build-tooling": "tsc ./tools/userScriptHeader.ts --resolveJsonModule --esModuleInterop", "build-userScriptHeader": "npm run build-tooling && node ./tools/userScriptHeader.js", "validate": "npm run type-check && npm run lint", diff --git a/src/index.ts b/src/index.ts index af7f181..933ce8d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -25,14 +25,6 @@ class App extends EventEmitter { constructor() { super(); - - // Development-only debug information - if (__DEV__) { - console.log('๐Ÿ”ง UserScript starting in development mode'); - console.log('๐Ÿ“ฆ Version:', __VERSION__); - console.log('๐Ÿ• Build time:', __BUILD_TIME__); - } - this.initialize(); } diff --git a/src/modules/example.ts b/src/modules/example.ts index bc0ea7a..e6254d4 100644 --- a/src/modules/example.ts +++ b/src/modules/example.ts @@ -22,7 +22,6 @@ interface ExampleModuleEvents { export class ExampleModule extends EventEmitter { private isInitialized = false; private actionCount = 0; - private lastActionTime = 0; constructor() { super(); @@ -37,7 +36,6 @@ export class ExampleModule extends EventEmitter { // Load persistent data this.actionCount = Storage.get('exampleModule.actionCount', 0) || 0; - this.lastActionTime = Storage.get('exampleModule.lastActionTime', 0) || 0; // Wait for required DOM elements (example) await this.waitForPageElements(); @@ -166,11 +164,9 @@ export class ExampleModule extends EventEmitter { public performAction(trigger: string): void { this.actionCount++; const timestamp = Date.now(); - this.lastActionTime = timestamp; - // Store the updated count and last action time + // Store the updated count Storage.set('exampleModule.actionCount', this.actionCount); - Storage.set('exampleModule.lastActionTime', timestamp); // Emit event this.emit('actionPerformed', { action: trigger, timestamp }); @@ -209,7 +205,7 @@ export class ExampleModule extends EventEmitter { const stats = { initialized: this.isInitialized, actionCount: this.actionCount, - lastAction: this.lastActionTime, + lastAction: Storage.get('exampleModule.lastActionTime', 0), }; const message = [ @@ -234,7 +230,6 @@ export class ExampleModule extends EventEmitter { Storage.remove('exampleModule.actionCount'); Storage.remove('exampleModule.lastActionTime'); this.actionCount = 0; - this.lastActionTime = 0; console.log('๐Ÿงน Example module data reset'); this.showNotification('Module data reset!'); } diff --git a/src/types/userscript.d.ts b/src/types/userscript.d.ts index f7d4011..d97c422 100644 --- a/src/types/userscript.d.ts +++ b/src/types/userscript.d.ts @@ -94,15 +94,6 @@ declare global { * UnsafeWindow for accessing page's global scope */ const unsafeWindow: Window & typeof globalThis; - - /** - * Build-time constants injected by Vite - */ - const __DEV__: boolean; - const __VERSION__: string; - const __DEBUG__: boolean; - const __USERSCRIPT__: boolean; - const __BUILD_TIME__: string; } export {}; diff --git a/vite.config.ts b/vite.config.ts index 45ea70d..697ba68 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,7 +1,7 @@ -import { resolve } from 'path'; -import { defineConfig } from 'vite'; -import tsconfigPaths from 'vite-tsconfig-paths'; -import pkgjsn from './package.json'; +import { resolve } from "path"; +import { defineConfig } from "vite"; +import tsconfigPaths from "vite-tsconfig-paths"; +import pkgjsn from "./package.json"; export default defineConfig(({ mode }) => { const isDev = mode === 'development'; @@ -9,106 +9,18 @@ export default defineConfig(({ mode }) => { return { build: { rollupOptions: { - input: resolve(__dirname, 'src/index.ts'), + input: resolve(__dirname, "src/index.ts"), output: { entryFileNames: `${pkgjsn.name}${isDev ? '.dev' : ''}.user.js`, - dir: resolve(__dirname, 'dist'), - // Disable code splitting - everything in one file for UserScript - inlineDynamicImports: true, - manualChunks: undefined, - // Optimize output format - format: 'iife', - // Remove unnecessary comments in production - banner: isDev ? undefined : '', - footer: isDev ? undefined : '', - }, - // Prevent any external dependencies - external: [], - // Tree-shaking optimizations - treeshake: { - moduleSideEffects: false, - propertyReadSideEffects: false, - unknownGlobalSideEffects: false, + dir: resolve(__dirname, "dist"), }, }, - sourcemap: isDev ? 'inline' : false, + sourcemap: isDev ? "inline" : false, minify: isDev ? false : 'terser', - // Enhanced Terser options for maximum compression - terserOptions: isDev - ? undefined - : { - compress: { - drop_console: false, // Keep console for UserScript debugging - drop_debugger: true, - pure_funcs: ['console.debug'], - passes: 2, - unsafe: true, - unsafe_arrows: true, - unsafe_comps: true, - unsafe_math: true, - unsafe_methods: true, - unsafe_proto: true, - unsafe_regexp: true, - unsafe_undefined: true, - hoist_funs: true, - hoist_props: true, - hoist_vars: false, - if_return: true, - join_vars: true, - sequences: true, - side_effects: true, - switches: true, - typeofs: true, - booleans: true, - collapse_vars: true, - comparisons: true, - computed_props: true, - conditionals: true, - dead_code: true, - directives: true, - evaluate: true, - expression: false, - global_defs: {}, - keep_fargs: false, - keep_infinity: false, - loops: true, - negate_iife: true, - properties: true, - reduce_funcs: true, - reduce_vars: true, - toplevel: true, - unused: true, - }, - mangle: { - toplevel: true, - safari10: false, - properties: { - regex: /^_/, - }, - }, - format: { - comments: false, - beautify: false, - }, - ecma: 2020, - toplevel: true, - safari10: false, - ie8: false, - }, - // Ensure all assets are inlined - assetsInlineLimit: Number.MAX_SAFE_INTEGER, - // Disable CSS code splitting - cssCodeSplit: false, - // Target modern browsers for better optimization - target: ['es2020', 'chrome80', 'firefox78', 'safari14'], - // Report compressed file sizes - reportCompressedSize: true, - // Chunk size warnings - chunkSizeWarningLimit: 500, }, plugins: [tsconfigPaths()], resolve: { - extensions: ['.tsx', '.ts', '.js'], + extensions: [".tsx", ".ts", ".js"], alias: { '@': resolve(__dirname, 'src'), }, @@ -116,31 +28,6 @@ export default defineConfig(({ mode }) => { define: { __DEV__: isDev, __VERSION__: JSON.stringify(pkgjsn.version), - // Production optimizations - 'process.env.NODE_ENV': JSON.stringify(isDev ? 'development' : 'production'), - // Remove debug code in production - __DEBUG__: isDev, - // UserScript environment flags - __USERSCRIPT__: true, - __BUILD_TIME__: JSON.stringify(new Date().toISOString()), - }, - // Optimize dependencies - optimizeDeps: { - include: [], - exclude: [], - }, - // Enable esbuild optimizations - esbuild: { - target: 'es2020', - legalComments: 'none', - ...(isDev - ? {} - : { - drop: ['debugger'], - minifyIdentifiers: true, - minifySyntax: true, - minifyWhitespace: true, - }), }, }; });