Closed misantronic closed 2 years ago
I have the same error but with the "path" package at the moment.
Okay, hear me out. :)
I think you can't use that module inside the routes
path. I just moved my helper function out of the routes folder and now the app is running for me.
Okay, hear me out. :)
I think you can't use that module inside the
routes
path. I just moved my helper function out of the routes folder and now the app is running for me.
I have it like this:
/app/root.tsx
import { configureAuth } from './aws/auth';
export default function App() {
useEffect(() => {
configureAuth();
}, []);
...
}
/app/aws/auth.ts
import Amplify from 'aws-amplify';
export function configureAuth() {
console.log(Amplify); // causes error
}
so that structure shouldn't cause any troubles... still it does :(
I have a similar problem trying to use the Authenticator
control from @aws-amplify/ui-react
.
Just by adding the import to index.jsx
:
import { Authenticator } from "@aws-amplify/ui-react";
I get the following error:
Uncaught TypeError: Failed to resolve module specifier "url". Relative references must start with either "/", "./", or "../".
TypeError: Cannot read properties of undefined (reading 'root')
at RemixRoute (http://localhost:3000/build/_shared/chunk-O3PPVUTT.js:3035:19)
at renderWithHooks (http://localhost:3000/build/_shared/chunk-MHFS6D7O.js:11065:26)
at mountIndeterminateComponent (http://localhost:3000/build/_shared/chunk-MHFS6D7O.js:13185:21)
at beginWork (http://localhost:3000/build/_shared/chunk-MHFS6D7O.js:13972:22)
at HTMLUnknownElement.callCallback2 (http://localhost:3000/build/_shared/chunk-MHFS6D7O.js:3675:22)
at Object.invokeGuardedCallbackDev (http://localhost:3000/build/_shared/chunk-MHFS6D7O.js:3700:24)
at invokeGuardedCallback (http://localhost:3000/build/_shared/chunk-MHFS6D7O.js:3734:39)
at beginWork$1 (http://localhost:3000/build/_shared/chunk-MHFS6D7O.js:17081:15)
at performUnitOfWork (http://localhost:3000/build/_shared/chunk-MHFS6D7O.js:16309:20)
at workLoopSync (http://localhost:3000/build/_shared/chunk-MHFS6D7O.js:16263:13)
Doing a quick debug, when the import is present then routeModules
is undefined on line 179 of components.js
.
Somebody who knows AWS Amplify will need to help out here. Remix is pretty simple to host. To deploy a Remix app the server needs to:
That lambda would have a Remix adapter that adapts the AWS Amplify request into a web fetch Request. I'm sure the adapter will be pretty much identical to the remix-architect and remix-netlify adapters. So you can look in there for hints.
When I've looked at AWS amplify it all seemed very browser-oriented and it wasn't obvious how to set up those two requirements. We welcome any amplify experts to help out here :)
@ryanflorence do you think the error:
Uncaught TypeError: Failed to resolve module specifier "url". Relative references must start with either "/", "./", or "../".
Is thrown by Remix?
Hey guys, I’m on mobile so can’t type out a proper writeup, but the reason for this is because the frontend amplify packages reference node modules like url
, path
etc.
These modules don’t actually exist in the browser, but are polyfilled when bundling with webpack 4. Note that throughout the amplify documentation, they always reference webpack 4 specifically.
In webpack 5, this polyfill functionality was removed, so it’s my understanding that the amplify packages will not work with webpack 5 without some config.
https://github.com/webpack/changelog-v5
Coming back to remix, I believe remix uses esbuild under the hood which won’t be polyfilling these node libraries, hence the errors.
There’s a giant thread over in the amplify repo with discussion on this.
aws-amplify/amplify-js#9639
Just thought I would provide some context, this is an amplify ui + esbuild issue, nothing to do with remix itself.
I personally think given the backend focus of remix, you probably don’t want to be using the amplify ui packages anyway. Do all your auth, queries etc using the AWS admin SDKs in your loaders and actions. Amplify UI is designed for single page apps, so you will be fighting the remix paradigm when it comes to auth etc.
Do all your auth, queries etc using the AWS admin SDKs in your loaders and actions.
thank your for this detailed explanation. do you happen to know where I would find the docs for those aws admin sdks?
@misantronic I think he means the aws-sdk which you can find the docs and detailed API here: https://aws.amazon.com/sdk-for-javascript/
@dangreaves Thanks for the explanation. Yes, it should mostly all work via the sdk in the Loader/Action function. One thing that would still be problematic would be Auth when using social/oauth providers as that needs to be done via the browser. I haven't found a way to do that without the library, although it should all be http calls/redirects so presumably there is a way.
Often you do the initial auth dance in the browser, and then submit the JWT to your remix app and put it in a cookie and then use the JWT on the Remix server.
@ryanflorence Right that is the problem, if we do the initial browser part with the library, the app crashes with the error above. Maybe we can do the redirect without the library, not sure yet, I will give it a shot at some point this week.
If you were able to add esbuild plugins to remix, you could add a plugin like this which adds a webpack 4-like polyfill feature.
https://github.com/remorses/esbuild-plugins#esbuild-pluginsnode-modules-polyfill
I can’t find a documented way of adding esbuild plugins to remix though so that may not be possible yet.
Also, it’s clear that the amplify team have only tested the package with webpack 4, so you might run into more esbuild related problems. as there’s a lot less “magic” in esbuild (which is a good thing!).
If it’s possible to do your initial auth with an alternate library, I would highly recommend it as the amplify ui package isn’t great for performance, has a lot of side effects and has some design problems (eg the use of node modules, requiring polyfilling at the bundler).
You might have some luck using this package which is specifically for cognito, rather than the full amplify ui package.
In case anyone needs it, here is an authentication method for Cognito without Amplify libraries:
https://gist.github.com/chanan/d1601c63df36ac476e84fbc2ca96b2e9
In case anyone needs it, here is an authentication method for Cognito without Amplify libraries:
https://gist.github.com/chanan/d1601c63df36ac476e84fbc2ca96b2e9
that is incredible helpful — thank you 🙏
something that pops in my mind is that Amplify AppSync (GraphQL API) requires client-side Auth to run queries and mutations that are Restricted to Cognito User Pool users, at least to work effortlessly, but for backend requests you would have to
so if you choose the IAM to keep the API restricted you would call a lambda to call de request from your backend, unless there's a way to sign the request from the remix backend with the AWS-SDK npm pkg.
Just as another vote, I don't have the time budget to re-implement the Amplify/Oauth stuff for the project I'm picking up remix to handle, it would be nice to have enough build system escape hatches for these kinds of things.
Hello @pckilgore and @misantronic !
I'm with the Amplify team, and with our latest release, I've been able to get Remix working with the Amplify library. We are still testing it, so if you find any issues let me know.
Here is our documentation.
@ErikCH Ended up writing the server-side stuff with the SDK. Good to know for the future.
@ErikCH i’m super excited to hear that you’ve been able to get Remix working with Amplify! i would love to start exploring that myself. i checked the docs you linked to and it only covers the amplify UI library, whereas the part i’m stuck on is how to integrate Remix with Amplify SSR hosting. i read the AWS docs on Amplify SSR hosting, as well as the Amplify docs on Next.js hosting, and there are some parts that seem pretty Next.js specific, so i’m not sure how to adapt them to work with a Remix app.
the SSR docs give an example amplify.yml
file:
version: 1
frontend:
phases:
preBuild:
commands:
- npm ci
build:
commands:
- npm run build
artifacts:
baseDirectory: .next
files:
- '**/*'
cache:
paths:
- node_modules/**/*
according to the docs, setting baseDirectory: .next
indicates that the build artifacts are for a Next.js app that supports SSG and SSR pages (for SSG-only, it would be baseDirectory: out
). what should that value be for a Remix app?
the docs also state that “Amplify inspects the app’s build script in the package.json
file to detect whether the app is SSR or SSG”. the "build": "next build",
indicates SSR, while ”build”: “next build && next export”,
indicates SSG. do you know what that value should be for integrating with a Remix app?
thanks so much for any guidance you can provide! also, if you want me to take this discussion anywhere else (a different GitHub repo, the discord, etc.), i’m happy to do so. once i get Amplify and Remix working together, i will put together a write-up with guidance and instructions on my blog.
👋 @acusti It's currently not possible to deploy Remix apps using the Amplify Hosting SSR implementation because it's designed to work with Next.js at the moment. We're working on several improvements that would remove that limitation. Now that I'm aware of this thread, I'll keep you all informed here when we have news worth sharing.
Hello @pckilgore and @misantronic !
I'm with the Amplify team, and with our latest release, I've been able to get Remix working with the Amplify library. We are still testing it, so if you find any issues let me know.
Here is our documentation.
Do you happen to know if that includes the Authentication components? That's a big blocker for me at the moment moving forward.
@CrshOverride ! Yup that's what we've been testing, the Authenticator, and it's been going well.
@ErikCH Do you have a gist or anything anywhere that you can toss up to show the flow? That would be amazing if it "just worked" but I need it to secure calls to the "backend" as well. :thinking:
This issue has been automatically closed because we haven't received a response from the original author 🙈. This automation helps keep the issue tracker clean from issues that are unactionable. Please reach out if you have more information for us! 🙂
@ErikCH Do you have a gist or anything anywhere that you can toss up to show the flow? That would be amazing if it "just worked" but I need it to secure calls to the "backend" as well. 🤔
@CrshOverride - were you able to get any additional information about this? Thanks
@aaronksaunders I wasn't. My naive attempts also didn't work at all. As soon as I added the Amplify UI components to my project, my bundle was too large to be deployed to Lambda.
Hmm, ok.
I have googled around and there doesn’t seem to be a solution other than a statement that it is being worked on and a link that doesn’t show the work.
I guess I will try the discord channel.
Thanks
On Fri, Apr 22, 2022 at 1:29 PM Justin Niessner @.***> wrote:
@aaronksaunders https://github.com/aaronksaunders I wasn't. My naive attempts also didn't work at all. As soon as I added the Amplify UI components to my project, my bundle was too large to be deployed to Lambda.
— Reply to this email directly, view it on GitHub https://github.com/remix-run/remix/issues/806#issuecomment-1106718362, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEAFGMJCBJN4CE5BVRJSYLVGLOXLANCNFSM5JB3L3DA . You are receiving this because you were mentioned.Message ID: @.***>
--
--
Aaron K. Saunders CEO Clearly Innovative Inc @.*** www.clearlyinnovative.com
This email message and any attachment(s) are for the sole use of the intended recipient(s) and may contain proprietary and/or confidential information which may be privileged or otherwise protected from disclosure. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient(s), please contact the sender by reply email and destroy the original message and any copies of the message as well as any attachment(s) to the original message.
Hi @aaronksaunders , @CrshOverride !
We don't have any official documentation on using Amplify with Remix yet. When I tested it, it was working. My testing was just limited to using the aws-amplify/ui-react
package Authenticator. I followed the steps in our official documentation to create a new app. However, I didn't test every scenario, or hosting it somewhere in production, so your may run into some unexpected problems.
When we feel confident that we've tested enough scenarios, we'll add it to our official documentation. If you do run into problems though, as @aaronksaunders suggested, post on our Discord #ui-help channel. Or post your issue on our Github too.
@CrshOverride We made a fix that reduced the bundle size significantly recently. So you may want to try that again if the Lambda was having problems with the size.
@ErikCH i’ve been experimenting with migrating an existing amplify web app to remix (using cloudflare-workers as the server target) and am unable to get it to build. once i add aws-amplify
as a dependency, i get this:
✘ [ERROR] Could not resolve "http2"
node_modules/@aws-sdk/node-http-handler/dist/es/node-http2-handler.js:4:35:
4 │ import { connect, constants } from "http2";
╵ ~~~~~~~
The package "http2" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
i then ran yarn why @aws-sdk/node-http-handler
to see why that dependency is getting included:
[1/4] 🤔 Why do we have the module "@aws-sdk/node-http-handler"...?
[2/4] 🚚 Initialising dependency graph...
[3/4] 🔍 Finding dependency...
[4/4] 🚡 Calculating file sizes...
=> Found "@aws-sdk/node-http-handler@3.6.1"
info Reasons this module exists
- "@aws-amplify#core#@aws-sdk#client-cloudwatch-logs" depends on it
- Hoisted from "@aws-amplify#core#@aws-sdk#client-cloudwatch-logs#@aws-sdk#node-http-handler"
- Hoisted from "@aws-amplify#core#@aws-sdk#client-cognito-identity#@aws-sdk#node-http-handler"
- Hoisted from "@aws-amplify#storage#@aws-sdk#client-s3#@aws-sdk#node-http-handler"
info Disk size without dependencies: "388KB"
info Disk size with unique dependencies: "1.41MB"
info Disk size with transitive dependencies: "1.54MB"
info Number of shared dependencies: 6
did you run into any issues from @aws-sdk/*
packages and esbuild in your tests? any ideas on how i can work around them? i’m still unclear why these node.js-only libraries are being depended on from the @aws-amplify/*
packages when they are intended to be used in a browser context, but i guess that’s a bigger question than this immediate issue.
a quick update: marking http2
as an external for esbuild results in that error going away and these fresh errors
✘ [ERROR] No matching export in "node-modules-polyfills:child_process" for import "exec"
node_modules/@aws-sdk/credential-provider-process/dist/es/index.js:4:9:
4 │ import { exec } from "child_process";
╵ ~~~~
✘ [ERROR] No matching export in "node-modules-polyfills:crypto" for import "createHash"
node_modules/@aws-sdk/hash-node/dist/es/index.js:3:9:
3 │ import { createHash, createHmac } from "crypto";
╵ ~~~~~~~~~~
✘ [ERROR] No matching export in "node-modules-polyfills:crypto" for import "createHmac"
node_modules/@aws-sdk/hash-node/dist/es/index.js:3:21:
3 │ import { createHash, createHmac } from "crypto";
╵ ~~~~~~~~~~
✘ [ERROR] No matching export in "node-modules-polyfills:fs" for import "createReadStream"
node_modules/@aws-sdk/hash-stream-node/dist/es/index.js:1:9:
1 │ import { createReadStream } from "fs";
╵ ~~~~~~~~~~~~~~~~
✘ [ERROR] No matching export in "node-modules-polyfills:fs" for import "readFile"
node_modules/@aws-sdk/shared-ini-file-loader/dist/es/index.js:2:9:
2 │ import { readFile } from "fs";
╵ ~~~~~~~~
✘ [ERROR] No matching export in "node-modules-polyfills:os" for import "homedir"
node_modules/@aws-sdk/shared-ini-file-loader/dist/es/index.js:3:9:
3 │ import { homedir } from "os";
╵ ~~~~~~~
✘ [ERROR] No matching export in "node-modules-polyfills:fs" for import "lstatSync"
node_modules/@aws-sdk/util-body-length-node/dist/es/index.js:1:9:
1 │ import { lstatSync } from "fs";
╵ ~~~~~~~~~
You can try using just @aws-amplify/auth
or @aws-amplify/ui-react
.
I ended up implementing auth on the remix side with the v2 SDK.
I ended up getting it working with a combination of server side code and client side code using the Amplify Authenticator component to simplify the user management on the client and then passing the session information to the server to track in a session cookie. I then can make api calls using AppSync and the token from the user that was in the session cookie.
I do need to go back an add an additional call to verify the token on the server side but the basic structure is in the code sample
source code - https://github.com/aaronksaunders/amplify-remix-todos-1
@aaronksaunders Which stack did you wind up using? I'm wondering if it'll address the issues I had my first attempt.
I wrote it from scratch. using the "Just the basics" option
On Mon, Jun 6, 2022 at 3:18 PM Justin Niessner @.***> wrote:
@aaronksaunders https://github.com/aaronksaunders Which stack did you wind up using? I'm wondering if it'll address the issues I had my first attempt.
— Reply to this email directly, view it on GitHub https://github.com/remix-run/remix/issues/806#issuecomment-1147808303, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEAFGIPAGK6C63OSQU6Y3DVNZFHJANCNFSM5JB3L3DA . You are receiving this because you were mentioned.Message ID: @.***>
--
--
Aaron K. Saunders CEO Clearly Innovative Inc @.*** www.clearlyinnovative.com
This email message and any attachment(s) are for the sole use of the intended recipient(s) and may contain proprietary and/or confidential information which may be privileged or otherwise protected from disclosure. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient(s), please contact the sender by reply email and destroy the original message and any copies of the message as well as any attachment(s) to the original message.
Hey so I currently have a standard create react app hosted via aws amplify that does need to use the authentication.
I'm considering converting it to remix as a learning experience as well as giving the client the performance benefit.
But reading this thread I'm wondering is it worth the pain? And shall I save remix for my other project which will be hosted on cloudflare?
Using amplify on the frontend kind of defeats the point of using remix :D - I will opt for the approach of implementing remix handlers for auth
Has there been any changes to the SSR side to allow other libraries to work beyond Next?
Using amplify on the frontend kind of defeats the point of using remix :D - I will opt for the approach of implementing remix handlers for auth
You can use @aws-amplify/auth
server side - although it is a little tricky.
Hi there,
I am currently trying to use the new amplify v6 apis in my remix app but I get stuck here:
const keyValueStorage = createKeyValueStorageFromCookieStorageAdapter({
get: async (name) => {
const cookieHeader = request.headers.get("cookie");
console.log("get", cookieHeader);
const cookie = createCookie(name)
.parse(cookieHeader)
.then((c) => console.log("cc", c));
console.log("cookie", cookie);
return { name: "", value: "" };
},
});
Problem is that the get
method is not allowed to be async and remix cookie api needs to be awaited. Anyone tried this and has ideas or made progress? Would also be nice to have a reference implementation for remix cookies like the one in the nextjs-adapter.
I experimented with the current Amplify 6 SSR solution, but as it stands currently you cannot officially sign in server side (and do not get things like IP address or user agent logged) so we have decided to write our own custom Cognito solution.
Someone from Amplify team claims that a proper server-side solution is in the works but there are no timescales for this:
If this is not a blocker from you, then to get this working what you need to do is move grabbing the session outside:
const createKeyValueStorage = async (request) => {
const values = await sessionStorage.getSession(request.headers.get('Cookie'))
if (!values) throw new Error('No session found');
return createKeyValueStorageFromCookieStorageAdapter({
get: (name) => {
const value = values.get(name)
if (!value) {
console.log({ name, values });
throw new Error('No value found');
}
return { name, value };
},
});
};
@MattyBalaam do you have a full example to save the cookies using your approach? I'm trying but I can't successfully login. If I remove the SSR, keeping everything client side, everything works fine.
I would strongly recommend not using it! Are you on 5 or 6? There was one tricky workaround we needed to do which was that when you do the original sign-in we needed to store the temporary session (not user session) and then re-apply. It was quite frankly a mess.
@MattyBalaam I'm on v6
I can‘t help, for v6 I just threw something up just to test if if would run server-side as we wanted and the code is long gone.
@MattyBalaam thank you for answer, I just run out of ideas on how to make it work, the API on V6 it's very NextJS flavour, and I don't want move to v5 so probably we will do everything client side.
Which Remix packages are impacted?
remix
(Remix core)What version of Remix are you using?
1.0.6
Steps to Reproduce
Install aws-amplify:
npm i aws-amplify
Use it in the project:
Expected Behavior
It should work, just like before.
Actual Behavior
I am pretty new to remix and ssr altogether. Also aws states that aws-amplify supports ssr, I cannot get it to work. Whenever I am executing the code above, I get an error:
I am also curious: Is that code I put into the
useEffect
actually executed on the server or in the browser? I just would like to run aws-amplify in the browser, to get my old app-logic going...