Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for react-native-web #249

Closed
jasonlewicki opened this issue Jul 26, 2024 · 16 comments
Closed

Support for react-native-web #249

jasonlewicki opened this issue Jul 26, 2024 · 16 comments
Labels
enhancement New feature or request

Comments

@jasonlewicki
Copy link

jasonlewicki commented Jul 26, 2024

I'm having trouble getting powersync installed and working with an expo universal app (react-native and react-native-web)

Error running powersync/react-native on web:
Screenshot 2024-07-26 at 2 23 27 PM

text version of the link:
https://github.com/expo/fyi/blob/main/fb-batched-bridge-config-web.md

@jasonlewicki
Copy link
Author

jasonlewicki commented Jul 26, 2024

If i use @powersync/web, i get the error:
Uncaught SyntaxError: Cannot use 'import.meta' outside a module (at index.bundle?platform=web&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.routerRoot=src%2Fapp:258371:114)

which comes from here:

class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementation.WebStreamingSyncImplementation {
    constructor(options) {
      super(options);
      /**
       * Configure or connect to the shared sync worker.
       * This worker will manage all syncing operations remotely.
       */
      const syncWorker = new SharedWorker(new URL('../../worker/sync/SharedSyncImplementation.worker.js', import.meta.url), {
        /* @vite-ignore */
        name: `shared-sync-${this.webOptions.identifier}`,
        type: 'module'
      });

@jasonlewicki
Copy link
Author

jasonlewicki commented Jul 26, 2024

Additional info, issue raised on expo:
expo/expo#21099
expo/expo#30323

@jasonlewicki
Copy link
Author

jasonlewicki commented Jul 27, 2024

here's a git repo reproducing the error:

https://github.com/fig-wealth/powersync-react-native-web

npx expo install
npx expo start
w to launch web

@jasonlewicki
Copy link
Author

jasonlewicki commented Jul 27, 2024

Metro does not support esm, probably wont until at least next year:
facebook/metro#916
facebook/metro#886

any chance of making a commonjs transpile of powersync or changing the import.meta.url instances?

@stevensJourney
Copy link
Collaborator

Thanks for the detailed issue and example repository! We'll use your example to investigate the requirements - I'll keep you posted when we have an update.

@jasonlewicki
Copy link
Author

I was missing a commit, i've since added it to the repo. apologies

@kobiebotha kobiebotha added the enhancement New feature or request label Jul 29, 2024
@jasonlewicki
Copy link
Author

jasonlewicki commented Jul 29, 2024

To give you all an update, and potentially reduce the problem set, I've created another branch that conditionally incorporates @powersync/react-native

https://github.com/fig-wealth/powersync-react-native-web/tree/with-react-native

As far as I can tell, it works on iOS (at least saying the auth is wrong... [I have the self hosted demo running])
Screenshot 2024-07-29 at 2 01 35 PM

@stevensJourney
Copy link
Collaborator

We've done an initial investigation where we identified some hurdles and potential solutions for providing React Native web support. We have managed to get an example POC running using a UMD bundled version of the Web SDK. Support may be available in the near future.

@jasonlewicki
Copy link
Author

That's great news. I can't wait 👍

@jasonlewicki
Copy link
Author

The dev build has been working great so far. Thanks for all the hard work!

@jasonlewicki
Copy link
Author

jasonlewicki commented Aug 30, 2024

Hey team. We're trying to build for MVP over here:
npx expo export -p w --clear

This is the error we are getting on load:
Failed to fetch a worker script. Pretty sure it's powersync.

Here's a screen grab of the dist directory:
Screenshot 2024-08-30 at 10 57 41 AM

I'll try to get more information shortly.

@jasonlewicki
Copy link
Author

jasonlewicki commented Aug 31, 2024

Ok we're in business.

i have a git action:

# Copy public powersync files to dist directory
- name: Copy public files to dist directory
  run: |
    # Define the source and destination directories
    SOURCE_DIR="apps/client/dist"
    DEST_DIR="apps/client/dist/_expo/static/js/web"

    # Create the destination directory if it doesn't exist
    mkdir -p $DEST_DIR

    # Copy all files from the source to the destination
    cp -r $SOURCE_DIR/* $DEST_DIR

Moving the files into the _expo/web/js directory fixed it! This is probably just an artifact of the dev build.

@ducpt-bili
Copy link

hi @jasonlewicki ,
so does the powersync work on expo web now? Do we need to add more config like git action you paste above? Thanks

@jasonlewicki
Copy link
Author

hi @jasonlewicki , so does the powersync work on expo web now? Do we need to add more config like git action you paste above? Thanks

@ducpt-bili Hey, yeah, until the team merges into main, there's a list of things you need to do to get it working:

install these:

"@powersync/attachments": "0.0.0-dev-20240812065227",
"@powersync/common": "0.0.0-dev-20240812065227",
"@powersync/kysely-driver": "0.0.0-dev-20240812065227",
"@powersync/react": "0.0.0-dev-20240812065227",
"@powersync/react-native": "0.0.0-dev-20240812065227",
"@powersync/web": "0.0.0-dev-20240812065227",

Then, add this script:

// This file is required for the dev build of powersync to work properly.
// It copies the necessary files from the node_modules/@powersync/web/dist directory to the public directory.
// Gets around the package being built with esm modules and not being able to be resolved by metro.
// This is a temporary solution until the package is updated.

const fs = require('fs');
const path = require('path');
// Source directory
const sourceDir = path.join(
  __dirname,
  'node_modules',
  '@powersync',
  'web',
  'dist',
);
const destDir = path.join(__dirname, 'public');
function copyRecursiveSync(src, dest) {
  if (fs.existsSync(src) && fs.statSync(src).isDirectory()) {
    // Create the destination directory if it doesn't exist
    if (!fs.existsSync(dest)) {
      fs.mkdirSync(dest, { recursive: true });
    }
    const files = fs.readdirSync(src);
    // Copy each file/directory
    files.forEach((file) => {
      const srcFile = path.join(src, file);
      const destFile = path.join(dest, file);
      if (fs.statSync(srcFile).isDirectory()) {
        copyRecursiveSync(srcFile, destFile);
      } else {
        fs.copyFileSync(srcFile, destFile);
      }
    });
  } else {
    // eslint-disable-next-line no-console
    console.error(
      `Source directory ${src} does not exist or is not a directory.`,
    );
  }
}
// Execute the copy
copyRecursiveSync(sourceDir, destDir);
// eslint-disable-next-line no-console
console.log(`Files copied from ${sourceDir} to ${destDir} successfully.`);

and run it.

then modify your metro config to add this:

const customResolveRequest = (context, moduleName, platform) => {
  if (platform === 'web') {
    if (
      ['react-native-prompt-android', '@powersync/react-native'].includes(
        moduleName,
      )
    ) {
      return {
        type: 'empty',
      };
    }
    const mapping = {
      'react-native': 'react-native-web',
      '@powersync/web': '@powersync/web/dist/index.umd.js',
      kysely: 'kysely/dist/cjs/index.js',
    };
    if (mapping[moduleName]) {
      // eslint-disable-next-line no-console
      console.log('remapping', moduleName);
      return context.resolveRequest(context, mapping[moduleName], platform);
    }
  } else if (['@powersync/web'].includes(moduleName)) {
    return {
      type: 'empty',
    };
  }

  // Ensure you call the default resolver.
  return context.resolveRequest(context, moduleName, platform);
};

the git action above is for production runs, where you copy/move the dev files into the proper dist directory

@ducpt-bili
Copy link

hi @jasonlewicki , thank you for your hard work.

@cahofmeyr
Copy link
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants