Fix Luckysheet functionlist error and improve file processing
This commit is contained in:
@@ -1,5 +1,194 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user