Ошибка интеграции 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 и библиотек.