<think>我们遇到的问题是模拟器中运行Cocos Creator项目时出现的脚本文件加载错误。错误信息包括:
1. "ScriptEngine::onGetStringFromFile stream not found, possible missing file."
2. "ScriptEngine::runScript script stream, buffer is empty!"
3. "Failed to invoke require"
这些错误通常表明在尝试加载某个JavaScript文件时,文件不存在或者路径不正确,导致无法读取文件内容。
根据错误堆栈,问题发生在`jsb_global.cpp`的299行,这是在Cocos2d-x引擎的C++部分,当执行`require`函数时发生的。
可能的原因:
1. 脚本文件路径错误,或者文件确实不存在。
2. 在构建过程中,某些脚本文件没有被正确复制到构建目录。
3. 脚本文件被其他进程锁定,无法读取(在Windows上可能发生)。
4. 脚本文件内容为空。
解决方案:
步骤1:检查文件路径
确保在代码中`require`的文件路径是正确的,并且文件确实存在于项目中。
步骤2:检查构建设置
在Cocos Creator中,检查构建发布设置,确保需要加载的脚本文件被包含在构建中。
步骤3:清理并重新构建
清理构建目录并重新构建项目,有时候构建过程中可能出现文件复制遗漏。
步骤4:检查文件内容
确保被加载的脚本文件内容不为空。
步骤5:使用绝对路径
在模拟器中,相对路径可能基于不同的当前工作目录。尝试使用绝对路径来加载脚本。
步骤6:调试require
在代码中打印出`require`尝试加载的路径,以便确认。
由于错误发生在C++层的`require`调用,我们可以在JavaScript层进行一些调试,比如在调用`require`之前先检查文件是否存在(在原生环境中,可以使用jsb.fileUtils来判断)。
但是,请注意,在模拟器环境中,我们可能无法直接使用jsb.fileUtils,因为模拟器运行在浏览器环境中。因此,我们需要区分环境。
我们可以写一个辅助函数来安全地检查文件是否存在:
```javascript
function isFileExist(path) {
if (cc.sys.isNative) {
// 在原生环境中使用jsb.fileUtils
return jsb.fileUtils.isFileExist(path);
} else {
// 在浏览器环境中,我们无法直接检查文件是否存在,但可以尝试通过AJAX请求(注意跨域问题)
// 由于模拟器环境实际上是浏览器,我们可以尝试发送一个HEAD请求
return new Promise((resolve) => {
const xhr = new XMLHttpRequest();
xhr.open('HEAD', path);
xhr.onload = () => {
resolve(xhr.status === 200);
};
xhr.onerror = () => {
resolve(false);
};
xhr.send();
});
}
}
```
但是,由于错误发生在模拟器(浏览器环境),我们可以尝试在模拟器环境中通过AJAX检查文件是否存在。
然而,更直接的方法是查看构建后的目录结构,确认文件是否被正确部署。
另外,错误信息中提到了`c:\users\nantas\fireball-x\cocos2d-x-lite_245\cocos\scripting\js-bindings\manual\jsb_global.cpp`,这提示我们可能是Cocos2d-x引擎内部的问题,但更可能是我们的项目配置或代码问题。
考虑到错误发生在模拟器,我们可以尝试以下操作:
1. 在Cocos Creator中,打开项目设置,检查脚本的加载路径。
2. 确保在构建发布时,选择了正确的平台,并且构建路径没有非法字符。
如果以上步骤不能解决问题,我们可以尝试在代码中避免使用`require`,而是使用Cocos Creator的`cc.assetManager`来加载脚本,但注意`require`是Node.js和Webpack中的函数,在浏览器中并不原生支持,Cocos Creator在构建时会处理`require`,但在模拟器中可能没有正确打包。
由于我们无法直接修改引擎的C++代码,所以重点在于检查我们的项目代码和构建配置。
具体到代码,我们可能需要在某个地方使用了`require`来加载一个文件,而这个文件在模拟器环境下不存在。我们需要找到这个调用。
根据错误堆栈,错误发生在`jsb_global.cpp`的299行,这通常是在调用`require`时触发的。因此,我们需要检查代码中所有使用`require`的地方。
在Cocos Creator中,我们通常使用`require`来加载一个JSON文件或者一个JavaScript模块。例如:
```javascript
const config = require('../../config.json');
```
如果这个`config.json`文件没有被正确复制到构建目录,那么在模拟器中运行就会报错。
因此,解决方案如下:
1. 检查所有`require`语句,确认被加载的文件在构建目录中存在。
2. 如果文件是JSON,确保在构建发布时,该文件被包含在资源中。
另外,Cocos Creator在构建时,只有`assets`目录下的文件会被复制到构建目录中。因此,确保被`require`的文件在`assets`目录下。
如果问题仍然存在,我们可以尝试使用绝对路径。在Cocos Creator中,我们可以使用`cc.url.raw`来获取资源的绝对路径,然后通过`cc.assetManager`加载,而不是使用`require`。
例如,加载一个JSON文件:
```javascript
cc.assetManager.loadRes('config', (err, jsonAsset) => {
if (err) {
console.error(err);
return;
}
const config = jsonAsset.json;
});
```
这样,就不需要使用`require`,而是使用Cocos Creator的资源管理系统,可以避免路径问题。
但是,如果必须使用`require`(例如加载一个JavaScript模块),那么我们需要确保该模块被包含在构建中,并且路径正确。
总结步骤:
1. 检查构建目录中是否有缺失的文件。
2. 将需要`require`的文件放在`assets`目录下。
3. 使用相对路径时,注意当前文件的位置。
4. 避免使用动态`require`(例如`require(variable)`),因为构建工具可能无法处理。
如果问题仍然存在,请提供具体的代码行,以便进一步分析。
由于我们无法直接看到代码,这里只能给出一般性建议。
但是,根据错误信息,我们还可以尝试:
1. 更新Cocos Creator到最新版本(2.4.13可能存在已知问题)。
2. 重新安装Cocos Creator。
最后,如果问题只出现在模拟器中,而在真机上正常,那么可能是模拟器的问题,可以尝试重启模拟器或者清除模拟器缓存。
由于问题描述中没有提供具体的代码,我们无法给出具体的代码修改。但是,我们可以提供一个通用的文件存在检查函数,并在使用`require`前进行检查(仅原生环境有效):
```javascript
if (cc.sys.isNative) {
const filePath = 'path/to/file.js';
if (jsb.fileUtils.isFileExist(filePath)) {
const module = require(filePath);
} else {
cc.error(`File not found: ${filePath}`);
}
} else {
// 在浏览器环境,我们只能尝试,如果失败则捕获异常
try {
const module = require('path/to/file.js');
} catch (e) {
cc.error(e);
}
}
```
但是,请注意,在浏览器环境中,`require`是由构建工具(如webpack)处理的,所以通常不会出现文件不存在的情况,因为构建工具会打包所有依赖。因此,问题可能只出现在模拟器环境,而模拟器环境实际上是一个特殊的浏览器环境,它模拟了原生环境的部分行为。
因此,我们重点检查模拟器构建中,文件是否被正确部署。
由于问题复杂,如果以上方法都不能解决,建议在Cocos论坛或GitHub上提交问题,并提供最小复现项目。
下面,我们给出一个在Cocos Creator中安全加载JSON文件的例子,使用`cc.assetManager`代替`require`:
假设我们有一个JSON文件`assets/resources/config.json`,我们可以这样加载:
```javascript
cc.assetManager.loadRes('resources/config', (err, jsonAsset) => {
if (err) {
console.error('Failed to load config:', err);
return;
}
console.log('Config loaded:', jsonAsset.json);
});
```
这样就不需要`require`,避免了上述错误。
如果问题出在加载JavaScript模块,我们可以考虑将模块放在`assets`目录下,然后通过`require`的相对路径加载,并确保在构建后该模块被复制到构建目录的对应位置。
最后,如果问题仍然无法解决,请检查Cocos Creator项目的`settings.json`和`project.json`配置,确保没有不正确的设置。
由于问题描述有限,我们只能提供这些建议。
§§相关问题§§:
1. 在Cocos Creator中,如何正确加载外部JavaScript模块?
2. Cocos Creator的构建流程中,资源是如何被处理的?
3. 在Cocos2d-x中,`require`函数的实现原理是什么?
4. 如何调试Cocos Creator模拟器中的脚本加载错误?</think>## 解决 "ScriptEngine::onGetStringFromFile stream not found" 错误
这个错误表明 Cocos Creator 模拟器在尝试加载脚本文件时找不到文件或文件内容为空。这通常发生在资源路径不正确、文件未包含在构建中或资源加载逻辑有缺陷时。
### 解决方案
#### 1. 增强资源路径处理
```javascript
// 在 loadScript 函数中添加路径验证
function loadScript(path) {
return new Promise((resolve, reject) => {
// 添加路径验证
if (!path || typeof path !== 'string') {
return reject(new Error('Invalid script path'));
}
// 在原生平台使用文件系统API检查文件是否存在
if (cc.sys.isNative && cc.sys.__globalAdapter?.isFileExist) {
if (!cc.sys.__globalAdapter.isFileExist(path)) {
console.error(`[FileCheck] File not found: ${path}`);
return reject(new Error(`File not found: ${path}`));
}
}
// 原始加载逻辑...
});
}
```
#### 2. 修复资源加载逻辑
```javascript
// 修改 SDK 加载器,添加更健壮的路径处理
async function loadGravityEngineSDK() {
// 使用绝对路径和相对路径组合
const sdkPaths = [
// 绝对路径
cc.path.join(cc.game.path, 'assets/_plugs/lib/gravityengine.mg.cocoscreator.min.js'),
cc.path.join(cc.game.path, '_plugs/lib/gravityengine.mg.cocoscreator.min.js'),
// 相对路径
'./assets/_plugs/lib/gravityengine.mg.cocoscreator.min.js',
'../_plugs/lib/gravityengine.mg.cocoscreator.min.js',
'lib/gravityengine.mg.cocoscreator.min.js'
];
// 添加调试日志
console.log('[SDK] Searching paths:', sdkPaths);
for (const path of sdkPaths) {
try {
const normalizedPath = cc.path.normalize(path);
console.log(`[SDK] Trying path: ${normalizedPath}`);
// 关键修复:在加载 SDK 前确保全局对象完整
ensureGlobalEnvironment();
// JSB 特殊处理:使用 require 加载
if (cc.sys.isNative && cc.sys.__globalAdapter?.require) {
console.log('[SDK] Using native require');
cc.sys.__globalAdapter.require(normalizedPath);
console.log('[SDK] Native require loaded:', normalizedPath);
} else {
console.log('[SDK] Using loadScript');
await loadScript(normalizedPath);
console.log('[SDK] Loaded from:', normalizedPath);
}
// 关键修复:加载后再次检查全局对象
ensureGlobalEnvironment();
initGravityEngine();
return;
} catch (e) {
console.warn('[SDK] Load failed:', path, e.message);
}
}
console.error('[SDK] All paths failed');
handleSDKLoadFailure();
}
```
#### 3. 添加文件存在性检查
```javascript
// 在场景加载器中添加文件检查
async function loadStartScene() {
try {
// 检查场景文件是否存在
const scenePath = 'db://assets/start.fire';
if (cc.sys.isNative) {
const fileUtils = cc.sys.__globalAdapter?.fileUtils;
if (fileUtils && !fileUtils.isFileExist(scenePath)) {
console.error(`[Scene] File not found: ${scenePath}`);
throw new Error(`Scene file not found: ${scenePath}`);
}
}
// 原始加载逻辑...
} catch (error) {
// 错误处理...
}
}
```
#### 4. 增强 require 错误处理
```javascript
// 在环境修复部分增强 require 函数
(function() {
// ... 其他环境修复代码 ...
// 增强 require 函数
if (typeof globalObj.require === 'undefined') {
defineGlobal('require', function(module) {
// 添加模块路径检查
if (!module || typeof module !== 'string') {
console.error('[Require] Invalid module name');
return {};
}
// 尝试从不同位置加载
const searchPaths = [
module,
`${module}.js`,
`src/${module}`,
`assets/${module}`,
`scripts/${module}`
];
for (const path of searchPaths) {
try {
if (globalObj.__modules && globalObj.__modules[path]) {
return globalObj.__modules[path];
}
// 在原生平台检查文件是否存在
if (cc.sys.isNative && cc.sys.__globalAdapter?.isFileExist) {
if (cc.sys.__globalAdapter.isFileExist(path)) {
return cc.sys.__globalAdapter.require(path);
}
}
} catch (e) {
console.warn(`[Require] Load attempt failed for ${path}:`, e);
}
}
console.error(`[Require] Module '${module}' not found in any location`);
return {};
});
}
})();
```
### 完整修复后的代码
```javascript
// ====== 环境修复与全局对象安全 ======
(function() {
// 安全获取全局对象的函数
const getGlobalObject = () => {
if (typeof globalThis !== 'undefined') return globalThis;
try {
const globalFromFn = Function('return this')();
if (globalFromFn) return globalFromFn;
} catch (e) {
console.warn('[EnvFix] Function constructor blocked in strict mode');
}
if (typeof global !== 'undefined') return global;
if (typeof window !== 'undefined') return window;
if (typeof self !== 'undefined') return self;
if (typeof cc !== 'undefined' && cc.sys && cc.sys.__globalAdapter) {
return cc.sys.__globalAdapter;
}
console.error('[EnvFix] Unable to determine global object, creating new');
return {};
};
const globalObj = getGlobalObject();
const defineGlobal = (name, value) => {
if (typeof globalObj[name] === 'undefined') {
Object.defineProperty(globalObj, name, {
value,
writable: true,
configurable: true,
enumerable: true
});
console.log(`[EnvFix] Defined global: ${name}`);
}
};
defineGlobal('global', globalObj);
defineGlobal('self', globalObj);
defineGlobal('globalThis', globalObj);
defineGlobal('window', globalObj);
// 原生平台特殊处理
if (cc && cc.sys && cc.sys.isNative) {
if (typeof XMLHttpRequest === 'undefined') {
defineGlobal('XMLHttpRequest', function() {
return cc.loader.getXMLHttpRequest();
});
}
if (typeof document === 'undefined') {
defineGlobal('document', {
createElement: () => ({ appendChild: () => {} }),
head: { appendChild: () => {} },
body: { appendChild: () => {} }
});
}
if (typeof location === 'undefined') {
defineGlobal('location', {
href: 'file://',
protocol: 'file:',
hostname: 'localhost',
host: 'localhost',
origin: 'file://'
});
}
console.log('[EnvFix] Native environment patched');
}
// 增强 require 函数
if (typeof globalObj.require === 'undefined') {
defineGlobal('require', function(module) {
if (!module || typeof module !== 'string') {
console.error('[Require] Invalid module name');
return {};
}
// 尝试从不同位置加载
const searchPaths = [
module,
`${module}.js`,
`src/${module}`,
`assets/${module}`,
`scripts/${module}`
];
for (const path of searchPaths) {
try {
if (globalObj.__modules && globalObj.__modules[path]) {
return globalObj.__modules[path];
}
// 在原生平台检查文件是否存在
if (cc.sys.isNative && cc.sys.__globalAdapter?.isFileExist) {
if (cc.sys.__globalAdapter.isFileExist(path)) {
return cc.sys.__globalAdapter.require(path);
}
}
} catch (e) {
console.warn(`[Require] Load attempt failed for ${path}:`, e);
}
}
console.error(`[Require] Module '${module}' not found in any location`);
return {};
});
}
})();
// ====== 引擎初始化保护系统 ======
const EngineReady = (function() {
let _promise = null;
let _resolve = null;
let _isReady = false;
let _checkInterval = null;
const safeCheckEngine = () => {
if (cc && cc.game && cc.game._isEngineInited) {
return true;
}
if (cc && cc.game && cc.game.once) {
const eventName = cc.game.EVENT_ENGINE_INITED || 'engine-inited';
cc.game.once(eventName, () => {
_resolve && _resolve();
_isReady = true;
_checkInterval && clearInterval(_checkInterval);
});
return true;
}
return false;
};
return {
get isReady() { return _isReady; },
get promise() { return _promise; },
init() {
if (!_promise) {
_promise = new Promise(resolve => {
_resolve = () => {
_isReady = true;
resolve();
_checkInterval && clearInterval(_checkInterval);
};
if (safeCheckEngine()) return;
_checkInterval = setInterval(() => {
safeCheckEngine() && _resolve();
}, 100);
});
}
return _promise;
},
safeAccess(callback) {
if (this.isReady) {
try {
const result = callback();
if (result instanceof Promise) {
return result;
}
return Promise.resolve(result);
} catch (e) {
console.error('[EngineSafe] Sync error:', e);
return Promise.reject(e);
}
} else {
return this.promise.then(callback).catch(e => {
console.error('[EngineSafe] Async error:', e);
return Promise.reject(e);
});
}
}
};
})();
EngineReady.init();
// ====== 游戏主入口 ======
async function gameMainEntry() {
try {
console.log('[Main] Waiting for engine initialization...');
await EngineReady.promise;
console.log('[Main] Engine ready');
await EngineReady.safeAccess(() => {
if (cc.view) {
cc.view.enableRetina(true);
cc.view.resizeWithBrowserSize(true);
cc.view.setDesignResolutionSize(960, 640, cc.ResolutionPolicy.SHOW_ALL);
}
});
await loadGravityEngineSDK();
await loadStartScene();
} catch (error) {
console.error('[Main] Initialization failed:', error);
try {
cc.director.loadScene('start');
} catch (fallbackError) {
displayErrorFallback('启动失败\n请重启应用');
}
}
}
// 错误显示后备方案
function displayErrorFallback(message) {
try {
const errorDiv = document.createElement('div');
errorDiv.style.cssText = `
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: black;
color: white;
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
font: 24px Arial, sans-serif;
text-align: center;
white-space: pre-line;
padding: 20px;
`;
errorDiv.textContent = message;
document.body.appendChild(errorDiv);
} catch (e) {
console.error('[Fallback] Display failed:', e);
}
}
// ====== SDK加载器增强版 ======
async function loadGravityEngineSDK() {
// 使用多种可能的路径
const sdkPaths = [
cc.path.join(cc.game.path, 'assets/_plugs/lib/gravityengine.mg.cocoscreator.min.js'),
cc.path.join(cc.game.path, '_plugs/lib/gravityengine.mg.cocoscreator.min.js'),
'./assets/_plugs/lib/gravityengine.mg.cocoscreator.min.js',
'../_plugs/lib/gravityengine.mg.cocoscreator.min.js',
'lib/gravityengine.mg.cocoscreator.min.js'
];
console.log('[SDK] Searching paths:', sdkPaths);
for (const path of sdkPaths) {
try {
const normalizedPath = cc.path.normalize(path);
console.log(`[SDK] Trying path: ${normalizedPath}`);
// 在原生平台检查文件是否存在
if (cc.sys.isNative && cc.sys.__globalAdapter?.isFileExist) {
if (!cc.sys.__globalAdapter.isFileExist(normalizedPath)) {
console.warn(`[FileCheck] File not found: ${normalizedPath}`);
continue;
}
}
ensureGlobalEnvironment();
if (cc.sys.isNative && cc.sys.__globalAdapter?.require) {
cc.sys.__globalAdapter.require(normalizedPath);
console.log('[SDK] Native require loaded:', normalizedPath);
} else {
await loadScript(normalizedPath);
console.log('[SDK] Loaded from:', normalizedPath);
}
ensureGlobalEnvironment();
initGravityEngine();
return;
} catch (e) {
console.warn('[SDK] Load failed:', path, e.message);
}
}
console.error('[SDK] All paths failed');
handleSDKLoadFailure();
}
function loadScript(path) {
return new Promise((resolve, reject) => {
if (!path || typeof path !== 'string') {
return reject(new Error('Invalid script path'));
}
// 优先使用 Cocos 的加载系统
if (cc.assetManager?.loadScript) {
cc.assetManager.loadScript(path, (err) => {
if (err) {
// 原生平台特殊处理
if (cc.sys.isNative) {
try {
const jsb = cc.sys.__globalAdapter;
if (jsb && jsb.require) {
jsb.require(path);
return resolve();
}
} catch (nativeError) {
reject(nativeError);
}
}
reject(err);
} else {
resolve();
}
});
return;
}
// 后备方案:直接创建 script 标签
try {
const script = document.createElement('script');
script.src = path;
script.onload = () => resolve();
script.onerror = () => reject(new Error(`Failed to load ${path}`));
document.head.appendChild(script);
} catch (e) {
reject(e);
}
});
}
function initGravityEngine() {
let GravityEngine = null;
if (typeof globalThis.GravityEngine === 'function') {
GravityEngine = globalThis.GravityEngine;
}
else if (typeof window.GravityEngine === 'function') {
GravityEngine = window.GravityEngine;
}
else if (typeof global.GravityEngine === 'function') {
GravityEngine = global.GravityEngine;
}
else if (typeof self.GravityEngine === 'function') {
GravityEngine = self.GravityEngine;
}
else {
console.error('[SDK] GravityEngine not found');
return;
}
try {
GravityEngine.init({
appId: '624768904',
enableLog: true
});
} catch (e) {
console.error('[SDK] Init failed:', e);
}
}
function handleSDKLoadFailure() {
console.warn('[SDK] Using fallback analytics');
window.GravityEngine = {
init: () => console.warn('SDK unavailable'),
trackEvent: () => {}
};
}
// ====== 场景加载器 ======
async function loadStartScene() {
try {
// 检查场景文件是否存在
const scenePath = 'db://assets/start.fire';
if (cc.sys.isNative) {
const fileUtils = cc.sys.__globalAdapter?.fileUtils;
if (fileUtils && !fileUtils.isFileExist(scenePath)) {
console.error(`[Scene] File not found: ${scenePath}`);
throw new Error(`Scene file not found: ${scenePath}`);
}
}
await new Promise((resolve) => {
if (!cc.assetManager?.loadBundle) {
return resolve();
}
cc.assetManager.loadBundle('main', (err) => {
if (err) console.error('[Scene] Bundle load error:', err);
resolve();
});
});
if (cc.director?.loadScene) {
cc.director.loadScene('start');
} else {
throw new Error('Director unavailable');
}
} catch (error) {
console.error('[Scene] Load failed:', error);
try {
cc.director.loadScene('start');
} catch (e) {
throw new Error('Fallback scene load failed');
}
}
}
// ====== UI_Entry组件 ======
const { ccclass, property } = cc._decorator;
@ccclass
export default class UI_Entry extends cc.Component {
// ... 其他代码保持不变 ...
}
// ====== 启动游戏 ======
if (cc?.game?.run) {
cc.game.run(() => {
ensureGlobalEnvironment();
gameMainEntry();
});
} else {
setTimeout(() => {
ensureGlobalEnvironment();
gameMainEntry();
}, 1000);
}
```
### 关键修复说明
1. **路径处理增强**:
- 使用 `cc.path.join()` 和 `cc.path.normalize()` 确保路径正确
- 添加多种可能的路径组合,提高文件查找成功率
- 在加载前记录尝试的路径,便于调试
2. **文件存在性检查**:
```javascript
// 在原生平台检查文件是否存在
if (cc.sys.isNative && cc.sys.__globalAdapter?.isFileExist) {
if (!cc.sys.__globalAdapter.isFileExist(normalizedPath)) {
console.warn(`[FileCheck] File not found: ${normalizedPath}`);
continue;
}
}
```
- 在加载前检查文件是否存在,避免尝试加载不存在的文件
- 在场景加载前检查场景文件是否存在
3. **require 函数增强**:
```javascript
defineGlobal('require', function(module) {
// 尝试多个可能的路径
const searchPaths = [
module,
`${module}.js`,
`src/${module}`,
`assets/${module}`,
`scripts/${module}`
];
for (const path of searchPaths) {
// 尝试加载...
}
});
```
- 添加多个可能的模块路径
- 在原生平台使用文件系统API检查文件存在性
4. **错误处理增强**:
- 添加详细的日志记录,包括尝试的路径和加载结果
- 在文件不存在时跳过而不是抛出错误
- 在加载失败时继续尝试其他路径
5. **SDK 加载逻辑优化**:
- 在加载前打印所有尝试的路径
- 在原生平台优先使用 `require` 加载
- 添加路径规范化处理
### 测试建议
1. **路径验证测试**:
- 在不同平台(Web、原生)测试路径解析
- 验证所有可能的 SDK 路径在实际构建中的存在性
2. **文件存在性检查**:
```javascript
// 测试文件存在性检查
if (cc.sys.isNative && cc.sys.__globalAdapter?.isFileExist) {
const testPath = 'assets/_plugs/lib/gravityengine.mg.cocoscreator.min.js';
console.log(`File exists: ${testPath}`,
cc.sys.__globalAdapter.isFileExist(testPath));
}
```
3. **错误场景模拟**:
- 临时重命名 SDK 文件,验证错误处理逻辑
- 修改路径使其指向不存在的文件,观察控制台输出
4. **构建配置检查**:
- 确保所有需要的文件都包含在构建中
- 检查构建后的目录结构,确认资源路径正确