capacitor-community / sqlite

Community plugin for native & electron SQLite databases
MIT License
426 stars 104 forks source link

ionic7-angular-sqlite-app tutorial fails on v5.7.1 #533

Closed ChrisHSandN closed 1 month ago

ChrisHSandN commented 1 month ago

Describe the bug Updating the demo ionic7-angular-sqlite-app to v5.7.1 breaks with webpack errors and jeep-sqlite element is not present error.

To Reproduce

git clone https://github.com/jepiqueau/blog-tutorials-apps.git
cd blog-tutorials-apps/Part-1/ionic7-angular-sqlite-app
npm install 
npm install --save @capacitor-community/sqlite@5.7.1
ionic serve
[ng] ./node_modules/jeep-sqlite/dist/esm/jeep-sqlite.entry.js:2926:20-37 - Warning: Module not found: Error: Can't resol
ve 'crypto' in 'ionic7-angular-sqlite-app\SQLite\Part-1\ionic7-angular-sqlite-app\node_modules\jeep-sqlite\dist\esm'
[ng]
[ng] BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
[ng] This is no longer the case. Verify if you need this module and configure a polyfill for it.
[ng]
[ng] If you want to include a polyfill, you need to:
[ng]    - add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
[ng]    - install 'crypto-browserify'
[ng] If you don't want to include a polyfill, you can use an empty module like this:
[ng]    resolve.fallback: { "crypto": false }

The app runs but fails with

initializeAppError: Error: The jeep-sqlite element is not present in the DOM! Please check the @capacitor-community/sqlite documentation for instructions regarding the web platform.

Desktop (please complete the following information):

Additional context With a bit of Googling I ended up with the following changes:

package.json

    "crypto-browserify": "^3.12.0",
    "stream-browserify": "^3.0.0",
    "vm-browserify": "^1.1.2",

tsconfig.json

{
  "compilerOptions": {
    "paths":{
      "crypto":["node_modules/crypto-browserify"],
      "stream":["node_modules/stream-browserify"],
      "vm":["node_modules/vm-browserify"]
    }
  }
}

angular.json

{
  "architect": {
    "build": {
      "options": {
        "allowedCommonJsDependencies": ["crypto"],
      }
    }
  }
}

The above fixes the webpack < 5 breaking change error in compilation but still fails with

initializeAppError: Error: The jeep-sqlite element is not present in the DOM!

So I am a bit stuck.

jepiqueau commented 1 month ago

@ChrisHSandN Thanks for reporting. jeep-sqlite does not use 'crypto' module in fact the latest release of sql.js did, so the build of jeep-sqlite esm/jeep-sqlite-entry.js referred to crypto. To avoid the error message in angular create a webpack.config.js file including

module.exports = {
  resolve: {
    fallback: {
      crypto: false
      // Add more fallbacks if needed
    }
  }
};
jepiqueau commented 1 month ago

@ChrisHSandN Sorry this does not work with Angular13.3.2 so i look at it

ChrisHSandN commented 1 month ago

@jepiqueau thanks for your reply,

I am using Angular 16.2.12 (as per the tutorial package.json setup).

ChrisHSandN commented 1 month ago

Digging into this further, I suspect the issue may be with this function: https://github.com/capacitor-community/sqlite/blob/48e0c217a5ea8cfdafccc068460adc4a324e2e9a/src/web.ts#L47

Although it is async it has an internal then() so will resolve immediately (before anything has actually been set up).

I would propose something like:

async initWebStore(): Promise<void> {
  await customElements.whenDefined('jeep-sqlite');

  this.jeepSqliteElement = document.querySelector('jeep-sqlite');
    // ... etc.

Otherwise await initWebStore() doesn't actually wait for it to be ready and then checkConnectionsConsistency gets called before the element is set up.

jepiqueau commented 1 month ago

@ChrisHSandN You right. Will be fixed in the next release

jepiqueau commented 1 month ago

@ChrisHSandN The tutorial has also been updated. thanks for your contribution