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

Seems like Next.js is not working #151

Closed
aboodman opened this issue Oct 22, 2020 · 13 comments · Fixed by #164
Closed

Seems like Next.js is not working #151

aboodman opened this issue Oct 22, 2020 · 13 comments · Fixed by #164

Comments

@aboodman
Copy link
Contributor

@elsigh tried to use Replicache in a nextjs app and just imported it through npm the naive way. It correctly resolved to the cjs bundle, but the cjs bundle contains code with export which doesn't seem correct.

This blocks @elsigh from trying Replicache. We should maybe make a sample nextjs app to ensure this works.

@aboodman
Copy link
Contributor Author

aboodman commented Oct 23, 2020

Confirmed. I can replicate like this:

npx create-next-app foo

Then in package.json, add:

  "resolutions": {
    "webpack": "^5.0.0-beta.30"
  }

... to enable wp5 support per https://nextjs.org/blog/next-9-5#webpack-5-support-beta.

Then npm install replicache and instantiate it in index.js. I get:

error - ./node_modules/replicache/out/wasm/release/replicache_client.js 302:22
Module parse failed: Unexpected token (302:22)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| async function init(input) {
|     if (typeof input === 'undefined') {
>         input = import.meta.url.replace(/\.js$/, '_bg.wasm');
|     }
|     const imports = {};
/Users/aa/work/roci/replicache-next/node_modules/replicache/out.cjs/wasm/release/replicache_client.js:223
export function uuid() {
^^^^^^

SyntaxError: Unexpected token 'export'

I think since this blocks anyone creating a cjs app it's a p1. @arv I see the flag in webpack-build, but not sure how you want to setup the output.

@aboodman aboodman added the p1 label Oct 23, 2020
@arv
Copy link
Contributor

arv commented Oct 23, 2020

Did some exploring. If we generate --target nodejs for wasm-pack compilation we get closer but there are some more issues.

  • The shape of the module it generates is different (no default export for init)
    • We can probably do import * as mod and "feature detect" the default init function.
  • Next.js complains that there is no:
    • localStorage
      • I commented that one out to get things further
    • Performance
      • This one comes from Rust wasm_bindgen because we are doing dyn_into::<Performance>

Next.js is running in a Node.js environment without a lot of DOM. I think we will also run into trouble with IDBFactory if we get that far.

@aboodman
Copy link
Contributor Author

I’m so lost - why are we running in a node environment?

@arv
Copy link
Contributor

arv commented Oct 24, 2020

Next.js tries to run the js on the server, it is what is so special about next.js. I will try to switch to dynamic import and see how that plays out.

@arv
Copy link
Contributor

arv commented Oct 24, 2020

We can check process.browser or use dynamic import which are only run on the client.

@arv
Copy link
Contributor

arv commented Oct 26, 2020

Manually Removing out.cjs and things seems to work well with next.js

Screen Shot 2020-10-26 at 11 20 41 AM

@aboodman
Copy link
Contributor Author

This needs to be re-opened, right?

@arv arv reopened this Oct 30, 2020
@arv
Copy link
Contributor

arv commented Nov 4, 2020

Getting closer...

Turns out I have to use yarn for "resolutions" to work.

Now it replaces the import.meta.url with a file:// URL (which is clearly wrong), however, one of the webpack bugs suggests using the following pattern to get webpack to realize that it is an asset (webpack/webpack#6719 (comment))

new URL('./path/file.wasm', import.meta.url);

That look much better and becomes http://localhost:3000/_next/c770d646807cab937689.wasm but that file is 404

Then I tried using file-loader.

// next.config.js
module.exports = {
  webpack: (config, options) => {
    config.module.rules.push({
      test: /\.wasm/,
      use: ["file-loader"],
    });

    return config;
  },
};

Could not resolve file-loader...

yarn add file-loader

Still getting 404.

Maybe @elsigh has any idea what I am missing?

@aboodman
Copy link
Contributor Author

aboodman commented Nov 5, 2020

I was able to hack this to work horribly with the following steps:

  1. npx create-next-app foo
  2. resolutions -> use wp5
  3. add a symlink public/wasm -> node_modules/out/wasm
  4. pass wasmModule field to Replicache constructor with value wasm/release/replicache_client_bg.wasm

Basically, I tell Replicache the URL to find the wasm file at specifically rather than trying to derive it from import.meta.url, then I hack app dir to serve it.

This is not ideal, but works for now.

@aboodman
Copy link
Contributor Author

aboodman commented Nov 5, 2020

new URL('./path/file.wasm', import.meta.url);

Where did you put this? I can't replicate your steps here.

That look much better and becomes http://localhost:3000/_next/c770d646807cab937689.wasm but that file is 404

I wonder if webassemblyModuleFilename is the missing piece here?

https://github.com/vercel/next.js/blob/canary/examples/with-webassembly/next.config.js

@arv
Copy link
Contributor

arv commented Nov 5, 2020

I modified the generated code in replicache_client.js but we can do the same thing one layer higher up.

I tried using webassemblyModuleFilename too. Not sure if it was working, in other words changing the name didn't seem to change the URL or where the file was assured on disk.

More later...

@arv
Copy link
Contributor

arv commented Nov 5, 2020

And yes, manually putting things in public works for me too

arv added a commit to arv/replicache that referenced this issue Nov 6, 2020
There are a bunch of Webpack/Next.js issues to work around:

- `import.meta.url` generates `file:` URL. Using the `new URL` pattern
  tells Webpack to do runtime URLs.
- `experimental.asyncWebAssembly` causes Webpack to parse the wasm file
  and validate imports which it doesn't do correctly. Instead you need
  to use `type: "asset/resource"`.
  - But this puts the wasm file in `_next` which cause 404. We need to
    tell webpack to put the file in `static/` too

Towards rocicorp#151
arv added a commit that referenced this issue Nov 6, 2020
There are a bunch of Webpack/Next.js issues to work around:

- `import.meta.url` generates `file:` URL. Using the `new URL` pattern
  tells Webpack to do runtime URLs.
- `experimental.asyncWebAssembly` causes Webpack to parse the wasm file
  and validate imports which it doesn't do correctly. Instead you need
  to use `type: "asset/resource"`.
  - But this puts the wasm file in `_next` which cause 404. We need to
    tell webpack to put the file in `static/` too

Towards #151
arv added a commit to arv/replicache that referenced this issue Nov 7, 2020
arv added a commit to arv/replicache that referenced this issue Nov 7, 2020
arv added a commit that referenced this issue Nov 7, 2020
@arv arv changed the title It seems like the cjs bundle isn't working Seems like Next.js is not working Nov 7, 2020
@arv
Copy link
Contributor

arv commented Nov 7, 2020

Calling this done for now.

We will see if we need to resurface a cjs build in the future.

@arv arv closed this as completed Nov 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants