|
| 1 | +--- |
| 2 | +title: Release - v0.32.0 |
| 3 | +abstract: TODO |
| 4 | +published: 2025-4-12 |
| 5 | +coverImage: /assets/blog/acorn.webp |
| 6 | +layout: blog |
| 7 | +--- |
| 8 | + |
| 9 | +# Greenwood v0.32.0 |
| 10 | + |
| 11 | +**Published: April 12th, 2025** |
| 12 | + |
| 13 | +<img src="https://raw.githubusercontent.com/ProjectEvergreen/www.greenwoodjs.dev/03867761c4c28cad202097a2ea39670393bb80a9/src/assets/aws.svg" style="display:block; width: 25%; margin: 0 auto;" alt="AWS logo"/> |
| 14 | + |
| 15 | +## What's New |
| 16 | + |
| 17 | +Along with a round of bug fixes and miscellaneous enhancements, this new Greenwood release brings with it two big new features we are excited to share. We now have an official AWS Adapter for deploying dynamic pages and routes to Lambda functions, as well as now making our TypeScript plugin officially built-in; no more plugin needed anymore! There was also a small minimum version bump for NodeJS. |
| 18 | + |
| 19 | +This release was also the by-product of some great feedback, support, and contributions from our community. In particular the built-in TypeScript support was very much a collaborative communication process that really helped to strengthen Greenwood as a project that can be a pragmatic and productive experience to develop with. We very much enjoyed the conversations we had around this topic and the end result we produced. Thank you so much to everyone who got involved with us for this release, it means a lot to use and it's great to see what you're building with Greenwood! 💚 |
| 20 | + |
| 21 | +> Please refer to the [release notes](https://github.com/ProjectEvergreen/greenwood/releases/tag/v0.32.0) for the complete changelog and overview of breaking changes. |
| 22 | +
|
| 23 | +## AWS Adapter |
| 24 | + |
| 25 | +While static hosting of your Greenwood project was always possible with AWS, serverless support on Lambda for SSR pages and API routes didn't have a formal solution... until now! With this release, there is now an official adapter plugin for generating Lambda compatible function code for your dynamic pages and routes. ☁️ |
| 26 | + |
| 27 | +```js |
| 28 | +import { greenwoodPluginAdapterAws } from "@greenwood/plugin-adapter-aws"; |
| 29 | + |
| 30 | +export default { |
| 31 | + plugins: [greenwoodPluginAdapterAws()], |
| 32 | +}; |
| 33 | +``` |
| 34 | + |
| 35 | +Taking into consideration that there are many methods and options for deploying to AWS, this adapter plugin is primarily focused on generating consistent and predictable build output that can be complimented by some form of [**IaC (Infrastructure as Code)**](https://en.wikipedia.org/wiki/Infrastructure_as_code) or deployment tooling of your choice. The build output will look similar to Greenwood's own [standard build output](/docs/reference/appendix/#build-output) and will be available in the _.aws-output/_ folder at the root of your project. |
| 36 | + |
| 37 | +```shell |
| 38 | +.aws-output/ |
| 39 | + api/ |
| 40 | + event/ |
| 41 | + event.js |
| 42 | + index.js |
| 43 | + package.json |
| 44 | + search/ |
| 45 | + ... |
| 46 | + routes/ |
| 47 | + admin/ |
| 48 | + ... |
| 49 | + products/ |
| 50 | + index.js |
| 51 | + package.json |
| 52 | + products.route.chunk.jgsTuvlz.js |
| 53 | + products.route.js |
| 54 | +``` |
| 55 | + |
| 56 | +For each of the folders in the _api/_ or _routes/_ directories, it would just be a matter of creating a zip file for each folder / route, or ideally pointing your IaC tooling to those output folders. For example, here is a simplified example from our [**SST**](https://sst.dev/) example repo: |
| 57 | + |
| 58 | +```ts |
| 59 | +// 1) Configure SSR pages and API routes in API Gateway |
| 60 | +const api = new sst.aws.ApiGatewayV2("MyApi"); |
| 61 | + |
| 62 | +// products page |
| 63 | +api.route(`GET /routes/products`, { |
| 64 | + bundle: `.aws-output/routes/products`, |
| 65 | + handler: "index.handler", |
| 66 | +}); |
| 67 | + |
| 68 | +// search API |
| 69 | +api.route(`GET /api/search`, { |
| 70 | + bundle: `.aws-output/api/search`, |
| 71 | + handler: "index.handler", |
| 72 | +}) |
| 73 | + |
| 74 | +// 2) Setup hosting for static content |
| 75 | +const frontend = new sst.aws.StaticSite("MyStaticSite", { |
| 76 | + path: "./", |
| 77 | + build: { |
| 78 | + output: "public" |
| 79 | + }, |
| 80 | +}) |
| 81 | + |
| 82 | +// 3) Configure CloudFront router with SSR pages, API routes, and static content |
| 83 | +const router = new sst.aws.Router("MyRouter", { |
| 84 | + routes: { |
| 85 | + "/api/*": api.url, |
| 86 | + { |
| 87 | + url: api.url, |
| 88 | + rewrite: { |
| 89 | + regex: `^/products/$`, |
| 90 | + to: `/routes/products` |
| 91 | + } |
| 92 | + }, |
| 93 | + "/*": frontend.url |
| 94 | + }, |
| 95 | + invalidation: true, |
| 96 | +}); |
| 97 | + |
| 98 | +// 4) Configure SST app |
| 99 | +export default $config({ |
| 100 | + app(input) { |
| 101 | + return { |
| 102 | + name: "my-app", |
| 103 | + removal: input?.stage === "production" ? "retain" : "remove", |
| 104 | + protect: ["production"].includes(input?.stage), |
| 105 | + home: "aws", |
| 106 | + }; |
| 107 | + }, |
| 108 | + async run() { |
| 109 | + router |
| 110 | + }, |
| 111 | +}); |
| 112 | +``` |
| 113 | + |
| 114 | +> Naturally you wouldn't want to hardcode these, so please check out our full [AWS hosting documentation](/guides/hosting/aws/#serverless) for more details, including example repositories using **SST** and **Architect**. |
| 115 | +
|
| 116 | +## Built-in TypeScript Support |
| 117 | + |
| 118 | +With this release, Greenwood now provides built-in support for TypeScript, with the ability to fallback to using `tsc` if certain TypeScript features you're using (like Decorators, [enums, namespaces, etc](https://devblogs.microsoft.com/typescript/announcing-typescript-5-8/#the---erasablesyntaxonly-option)) are not supported through just type stripping alone. This was motivated due to [NodeJS version `>= 22.6.0`](https://nodejs.org/en/learn/typescript/run-natively) now making type stripping available by using the `--experimental-strip-types` flag. This also means you can remove Greenwood's [TypeScript plugin](https://greenwoodjs.dev/docs/plugins/typescript/) as it is has been deprecated with this release. |
| 119 | + |
| 120 | +```json |
| 121 | +{ |
| 122 | + "scripts": { |
| 123 | + "build": "NODE_OPTIONS='--experimental-strip-types' greenwood build" |
| 124 | + } |
| 125 | +} |
| 126 | +``` |
| 127 | + |
| 128 | +This also means that you can author your Greenwood configuration files and plugins with TypeScript! |
| 129 | + |
| 130 | +```ts |
| 131 | +// greenwood.config.ts |
| 132 | +import type { Config } from "@greenwood/cli"; |
| 133 | + |
| 134 | +const config: Config = { |
| 135 | + // ... |
| 136 | +}; |
| 137 | + |
| 138 | +export default config; |
| 139 | +``` |
| 140 | + |
| 141 | +For actual _type-checking_, you can of course install **typescript** in your project and use Greenwood's minimum recommended _tsconfig.json_ settings so that you can run `tsc` during CI. |
| 142 | + |
| 143 | +```json |
| 144 | +{ |
| 145 | + "compilerOptions": { |
| 146 | + "module": "preserve", |
| 147 | + "moduleResolution": "bundler", |
| 148 | + "allowImportingTsExtensions": true, |
| 149 | + "verbatimModuleSyntax": false, |
| 150 | + "noEmit": true, |
| 151 | + "erasableSyntaxOnly": true |
| 152 | + } |
| 153 | +} |
| 154 | +``` |
| 155 | + |
| 156 | +> Check out our [TypeScript docs](/docs/resources/typescript/) to learn more about getting setup with TypeScript and Greenwood. |
| 157 | +
|
| 158 | +--- |
| 159 | + |
| 160 | +As always, we're excited to see where the community can take Greenwood and are always available to chat on [GitHub](https://github.com/ProjectEvergreen/greenwood) or [Discord](/discord/). See you for the next release! ✌️ |
0 commit comments