--- description: globs: alwaysApply: false --- # Luckysheet Functionlist Error Prevention **Root Cause Analysis:** - Luckysheet internally references multiple functionlist objects at different namespaces - Timing issues between library loading and object initialization - Incomplete plugin.js loading which should initialize functionlist objects ## **Critical Loading Order (MUST Follow)** ```typescript // ✅ DO: Complete library loading sequence const loadSequence = async () => { // 1. jQuery (Luckysheet dependency) await loadResource("js", "https://code.jquery.com/jquery-3.6.0.min.js", "jquery"); // 2. CSS files (in specific order) await loadResource("css", "/luckysheet/dist/plugins/css/pluginsCss.css", "plugins-css"); await loadResource("css", "/luckysheet/dist/plugins/plugins.css", "plugins-main-css"); await loadResource("css", "/luckysheet/dist/css/luckysheet.css", "luckysheet-css"); await loadResource("css", "/luckysheet/dist/assets/iconfont/iconfont.css", "iconfont-css"); // 3. LuckyExcel (for Excel file processing) await loadResource("js", "/luckysheet/dist/luckyexcel.umd.js", "luckyexcel"); // 4. Plugin JS (CRITICAL: initializes functionlist) await loadResource("js", "/luckysheet/dist/plugins/js/plugin.js", "plugin-js"); // 5. Luckysheet main library await loadResource("js", "/luckysheet/dist/luckysheet.umd.js", "luckysheet"); // 6. CRITICAL: Wait for internal object initialization await new Promise(resolve => setTimeout(resolve, 1000)); }; ``` ## **Multi-Level Functionlist Initialization** ```typescript // ✅ DO: Initialize all possible functionlist reference paths const initializeFunctionlist = () => { try { // Level 1: Core Store objects if (!window.Store) window.Store = {}; if (!window.Store.functionlist) window.Store.functionlist = []; if (!window.Store.luckysheet_function) window.Store.luckysheet_function = {}; // Level 2: Global function objects if (!window.luckysheet_function) window.luckysheet_function = {}; if (!window.functionlist) window.functionlist = []; // Level 3: Luckysheet internal objects if (window.luckysheet) { if (!window.luckysheet.functionlist) window.luckysheet.functionlist = []; if (!window.luckysheet.formula) window.luckysheet.formula = {}; if (!window.luckysheet.formulaCache) window.luckysheet.formulaCache = {}; if (!window.luckysheet.formulaObjects) window.luckysheet.formulaObjects = {}; } // Level 4: Store internal structure if (!window.Store.config) window.Store.config = {}; if (!window.Store.luckysheetfile) window.Store.luckysheetfile = []; if (!window.Store.currentSheetIndex) window.Store.currentSheetIndex = 0; } catch (error) { console.warn("Functionlist initialization warning:", error); } }; ``` ## **TypeScript Window Interface Extension** ```typescript // ✅ DO: Extend Window interface for all Luckysheet globals declare global { interface Window { luckysheet: any; LuckyExcel: any; $: any; // jQuery Store: any; // Luckysheet Store luckysheet_function: any; // Luckysheet function list functionlist: any[]; // Global functionlist } } ``` ## **Critical Timing Requirements** - **MUST** call `initializeFunctionlist()` at three points: 1. After library loading sequence completion 2. After 1000ms wait period for internal initialization 3. Immediately before `luckysheet.create()` call - **MUST** wait at least 1000ms after all libraries are loaded - **MUST** verify all functionlist objects exist before calling `luckysheet.create()` ## **Error Recovery Pattern** ```typescript // ✅ DO: Implement robust error recovery try { // Final verification before luckysheet.create() initializeFunctionlist(); // Verify critical objects exist const verificationResults = { store: !!window.Store, functionlist: !!window.Store?.functionlist, luckysheet: !!window.luckysheet, createFunction: typeof window.luckysheet?.create === "function" }; if (!verificationResults.luckysheet || !verificationResults.createFunction) { throw new Error("Luckysheet not properly initialized"); } window.luckysheet.create(options); } catch (error) { console.error("Luckysheet initialization failed:", error); // Implement retry logic or fallback } ``` ## **Common Anti-Patterns to Avoid** ```typescript // ❌ DON'T: Skip plugin.js loading // plugin.js is CRITICAL for functionlist initialization // ❌ DON'T: Use insufficient wait times await new Promise(resolve => setTimeout(resolve, 100)); // TOO SHORT // ❌ DON'T: Initialize only Store.functionlist // Multiple objects need initialization // ❌ DON'T: Call luckysheet.create() immediately after library load // Internal objects need time to initialize ``` ## **Debugging Checklist** When functionlist errors occur: 1. ✅ Verify all libraries loaded in correct order 2. ✅ Check plugin.js is included and loaded 3. ✅ Confirm 1000ms wait after library loading 4. ✅ Verify all functionlist objects are arrays/objects (not undefined) 5. ✅ Check console for library loading errors 6. ✅ Ensure complete Luckysheet distribution is used (not partial) ## **Critical: Use Official LuckyExcel Pattern** ```typescript // ✅ DO: Follow official LuckyExcel → Luckysheet pattern exactly LuckyExcel.transformExcelToLucky(arrayBuffer, fileName, // Success callback (exportJson: any, luckysheetfile: any) => { // CRITICAL: Use exportJson.sheets directly, no custom validation const luckysheetOptions = { container: 'luckysheet-container', data: exportJson.sheets, // Direct usage - don't modify! title: exportJson.info?.name || fileName, userInfo: exportJson.info?.creator || "User", lang: "ko" }; window.luckysheet.create(luckysheetOptions); }, // Error callback (error: any) => { console.error("LuckyExcel conversion failed:", error); } ); ``` ## **Anti-Pattern: Over-Processing Data** ```typescript // ❌ DON'T: Modify or validate exportJson.sheets structure const validatedSheets = exportJson.sheets.map(sheet => ({ name: sheet?.name || `Sheet${index}`, data: Array.isArray(sheet?.data) ? sheet.data : [], // ... other modifications })); // ❌ DON'T: Use modified data luckysheet.create({ data: validatedSheets }); ``` The root cause of functionlist errors is often data structure mismatch between LuckyExcel output and Luckysheet expectations. Using exportJson.sheets directly maintains the proper internal structure that Luckysheet requires. This pattern successfully resolves the "Cannot read properties of undefined (reading 'functionlist')" error by ensuring complete library loading sequence and multi-level functionlist initialization.