Open aheissenberger opened 1 month ago
@lazarv
examples/hello-world-aws
:
node test.mjs
It looks like the wrong current working directory. Can you give me a hint how to solve this?~ The problem was the accept: "*/*"
request header. After adding text/html
it worked.packages/react-server-adapter-aws/libs
folder:
create-aws-lambda-handler.mjs
everything else is generic und could be part of @lazarv/react-server
hattip
adapters@lazarv the adapter is ready but I need help with these small problems:
define: { 'process.env.NODE_ENV': JSON.stringify(mode), },
from the deploy adapter to vite to ensure no development code is called as this fails after a build as the optimitzation has removed the required code.~NODE_ENV=production
in AWS Lambda to avoid that the react version of the client (production) differs from backend (development)..react-server
directory in relation to cwd
with environment variable OUT_DIR
.Example Error from sst dev
| Build Error ApiGatewayRouteBbovcaHandler
| ↳ Could not resolve "../lib/dev/create-logger.mjs" .aws-lambda/output/functions/index.func/node_modules/@lazarv/react-server/server/logger.mjs:6:20
create-logger.mjs
does not exist in the optimizes output/functions/index.func/node_modules
folder.
when create-logger.mjs
is included it fails with:
| Build Error ApiGatewayRouteBbovcaHandler
| ↳ No loader is configured for ".node" files: .aws-lambda/output/functions/inde
x.func/node_modules/fsevents/fsevents.node .aws-lambda/output/functions/index.fun
c/node_modules/fsevents/fsevents.js:13:23
| ↳ Could not resolve "lightningcss" .aws-lambda/output/functions/index.func/nod
e_modules/vite/dist/node/chunks/dep-DXWVQosX.js:62529:59
| Build Error ApiGatewayRouteBbovcaHandler
| ↳ No loader is configured for ".node" files: .aws-lambda/output/functions/inde
x.func/node_modules/fsevents/fsevents.node .aws-lambda/output/functions/index.fun
c/node_modules/fsevents/fsevents.js:13:23
| ↳ Could not resolve "lightningcss" .aws-lambda/output/functions/index.func/nod
e_modules/vite/dist/node/chunks/dep-DXWVQosX.js:62529:59
| Build Error ApiGatewayRouteBbovcaHandler
| ↳ No loader is configured for ".node" files: .aws-lambda/output/functions/inde
x.func/node_modules/fsevents/fsevents.node .aws-lambda/output/functions/index.fun
c/node_modules/fsevents/fsevents.js:13:23
| ↳ Could not resolve "lightningcss" .aws-lambda/output/functions/index.func/nod
e_modules/vite/dist/node/chunks/dep-DXWVQosX.js:62529:59
The problem is not related to NODE_ENV, it's the additional bundling by ˋsstˋ which fails with imports not represented in the node_module folder. I will try to find an option to switch off bundling
Hi @aheissenberger!
I will implement / refactor what you have right now in the AWS adapter to be able to just provide a function which creates a Hattip handler / middleware, so it's easier to create handlers for different platforms, like Node.js, AWS, etc. But I can't promise when I'll have time to do it.
I tried to deploy to AWS lambda using Serverless Framework v3 and v4, but neither worked. Your test run works, but there were issues with the deployments.
Using v3 it creates a handler which calls the specified function handler, but it's implemented using CommonJS which can't call ESM. With v4 I had other module resolution issues. Could you please provide a working serverless.yaml
? I think it would be nice if the output would be usable straight after a build, like the Vercel adapter to deploy the app right ahead.
@lazarv I am finished and suggest to move any kind of optimization regarding configuration of deployment frameworks to its own PRs Please have a look at the included example project which provides deployment configuration for three different deployment frameworks.
Currently your methods in core do not copy any source map files which is fine for me as I upload them directly to sentry but I suggest to add an option which allows to define if the source maps should be included in the output for the adapter.
regarding sst v3
- a stack should be created but I do not know the internals of react-server
well enough to connect to the dev server as done in the stack for e.g. remix or other existing stacks directly provided by sst:
https://github.com/sst/ion/blob/b9c9760259ebcd4419dc15679ebdbc61babc517f/platform/src/components/aws/remix.ts
slow startup time: Have you ever looked at the startup time of your server? The current startup time for a lambda is Init Duration: 756.41 ms
which is quit high. Further request for the example app are Duration: 37.10 ms
which is ok.
@aheissenberger this is great! As soon as you think this is ready to go, just mark it ready for review and it's good to go!
Please have a look at the included example project which provides deployment configuration for three different deployment frameworks.
I went through all of them, everything works! My only concern is about the SST deployment as it doesn't use CloudFront to serve all the static files from an S3 bucket, but every request is handled by the lambda, which is very suboptimal.
Currently your methods in core do not copy any source map files which is fine for me as I upload them directly to sentry but I suggest to add an option which allows to define if the source maps should be included in the output for the adapter.
The build can get the information from the configuration that it's needed to copy source maps or not, an enhancement for later for sure.
regarding sst v3 - a stack should be created but I do not know the internals of react-server well enough to connect to the dev server as done in the stack for e.g. remix or other existing stacks directly provided by sst
I think this is a future task and should be implemented at SST like in the case of Remix or Next.js with support from react-server's side.
Have you ever looked at the startup time of your server?
This is a performance issue around loading the configuration files. If loadConfig
just return early with an empty configuration object it shaves off ~150ms. I will investigate this further.
function bundling needs to be deactivated
I think that bundling is almost impossible right now because how client components and server actions are resolved and imported on-demand. It could result in shrinking the size a bit regarding the dependencies in node_modules
, but not much on the app code side which is already minified during build.
I have added a first version of a sst stack for react-server which supports s3 for static assets.
Last step will be to add optional lambda streaming.
@lazarv any idea why the @esbuild
is included in the examples/hello-world-aws/.aws-lambda/output/functions/index.func/node_modules
?
Here is a list sorted by size: 10M @esbuild 1,4M react-dom 720K parse5 516K react-server-dom-webpack 304K node-fetch-native 180K react 176K entities 172K @lazarv 132K esbuild 112K fast-glob 112K @nodelib 104K @hattip 72K picomatch 52K mime 40K braces 32K react-property 20K style-to-object 20K micromatch 12K to-regex-range 12K style-to-js 12K module-alias 12K inline-style-parser 12K fill-range 12K fastq 12K cookie 8,0K run-parallel 8,0K reusify 8,0K queue-microtask 8,0K picocolors 8,0K merge2 8,0K is-number 8,0K is-glob 8,0K is-extglob 8,0K glob-parent
any idea why the esbuild is included
Again, because of configuration. That module needs special attention from my side and I'll fix the performance and dependency issues around it this weekend.
Regarding patching SST with a symlink, can you move that into the adapter package and add Pulumi as an optional peer dependency? Also that "master" file needs some cleanup, like removing unused import comment and fixing TanStack Start link. I'll check out what's needed to make dev mode work.
If you could move the instructions from the readme into the docs that would be awesome!
The symlink is only a hack to allow me to test the stack - I am not experienced with sst framework at all and the documentation on how to develop a stack outside the repository does not exist. Currently all frameworks exist directly in the sst repository which is cool in the long run but currently as things still move a little bit problematic. I have asked on discord on how to handle this case.
I will upgrade the docs to include the content of the readme.
I was able to significantly reduce the startup time with changes regarding configuration and static file handling. On the main branch before the changes the docs started locally in ~265ms for me in production mode. After the changes this is down to ~72-75ms.
This configuration handling change also removes the esbuild
dependency when using a deployment adapter.
You will need to change the import at https://github.com/aheissenberger/react-server/blob/feat/adapter/aws-lambda/packages/react-server-adapter-aws/libs/create-handler.mjs#L1 to use https://github.com/lazarv/react-server/blob/main/packages/react-server/config/prebuilt.mjs. This way it's loading a prebuilt version of the configuration much faster than using glob in development mode.
Status update:
docs/src/pages/en/(pages)/deploy/aws.mdx
Issues:
@lazarv I asked sst team on how to extend the existing ssr base stack from outside the repository to avoid the hack I currently use by coping the stack into the .sst
directory and I was told that there is currently no solution but they are working on a solution.
extend the existing ssr base stack from outside the repository
I think being an open source repo, it's also an option for the future to contribute into sst/ion a react-server specific stack. Absolutely not a priority for now, especially as they already working on a long-term solution. Your current implementation is ok for now.
I will look into the streaming problem this weekend - maybe I find and fix it or remove the option and finish this PR without streaming support
Hi @aheissenberger! While working on upgrading to the latest Vite 6 beta version (for quite a while now...), I had an idea on your streaming issue. The server opens a Worker where the SSR rendering happens. Not closing this worker after rendering completes in the Lambda could keep the lambda running. If this is right, then I think it would be best to handle this using some input options and context to terminate the worker after response completes. Can you confirm this behavior?
Adapter to deploy to AWS Lambda. Wraps the hattip middleware with a AWS Lambda specific handler. fix #30
Status with different Deployment Frameworks:
/create-logger.mjs
and cannot handle the native libs forfsevents
andlightningcss