Ошибка интеграции SQLite в проекте Expo SDK
При попытке полностью интегрировать приложение с SQLite в проекте на Expo SDK, следуя официальной инструкции, вы столкнулись с ошибкой компиляции при тестировании в браузере:
Critical dependency: the request of a dependency is an expression
Фрагмент проблемного кода
Вот код, на который компилятор выдаёт ошибку:
await FileSystem.downloadAsync(
Asset.fromModule(require(pathToDatabaseFile)).uri,
FileSystem.documentDirectory + pathToDatabaseFile
)
return SQLite.openDatabase(pathToDatabaseFile)
Что означает эта ошибка?
Ошибка Critical dependency: the request of a dependency is an expression указывает на то, что в require() используется переменная (pathToDatabaseFile), а не статическая строка. Веб-сборщик (например, webpack) не может статически проанализировать такой динамический импорт, что приводит к ошибке в среде браузера. В Expo это часто возникает при попытке загрузить файлы базы данных через Asset.fromModule с динамическим путём.
Как это исправить?
Для решения проблемы замените динамический require() на статический импорт с использованием Asset.fromModule с явным указанием пути. Вот два основных подхода:
- Использовать статический импорт с
Asset.fromModule: Убедитесь, что файл базы данных находится в папкеassets(например,./assets/database.db). Затем используйте:
import { Asset } from 'expo-asset';
import * as FileSystem from 'expo-file-system';
import * as SQLite from 'expo-sqlite';
const databaseFile = require('./assets/database.db');
const asset = Asset.fromModule(databaseFile);
await asset.downloadAsync();
const dbUri = asset.localUri || asset.uri;
const dbPath = `${FileSystem.documentDirectory}database.db`;
await FileSystem.copyAsync({
from: dbUri,
to: dbPath
});
return SQLite.openDatabase(dbPath);
- Использовать
Asset.fromModuleс явным указанием ресурса: Если база данных уже встроена, можно сразу получить её URI безrequire():
const asset = Asset.fromModule(require('./assets/database.db'));
// Далее - как в первом варианте
Основное правило: избегайте переменных в require() - всегда указывайте статическую строку пути. Если путь динамический, предварительно загрузите ресурс через Asset.fromModule и используйте его localUri или uri.
Примечание: Если вы по-прежнему сталкиваетесь с трудностями, убедитесь, что все модули Expo (expo-file-system, expo-sqlite, expo-asset) установлены и настроены корректно. Проверьте также версии SDK и библиотек.