I wonder if we could take advantage of git to do this somehow. Generator triggers a check for any uncommitted code and then tags you at pre-generator so you could at least rollback. I know i do this manually anytime i run a generator i’m not familiar with.
Thank you @zpeters for your response. Your idea will certainly offer a minimalist solution - I did something similar for the same reason as you (we obviously are discussing a transactional application development). Here is the terminal log of the step: yarn redwood g scaffold post
(node:18259) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
✔ Generating scaffold files...
✔ Successfully wrote file `./web/src/components/Post/EditPost
Cell/EditPostCell.js`
✔ Successfully wrote file `./web/src/components/Post/Post/Pos
t.js`
✔ Successfully wrote file `./web/src/components/Post/PostCell
/PostCell.js`
✔ Successfully wrote file `./web/src/components/Post/PostForm
/PostForm.js`
✔ Successfully wrote file `./web/src/components/Post/Posts/Po
sts.js`
✔ Successfully wrote file `./web/src/components/Post/PostsCel
l/PostsCell.js`
✔ Successfully wrote file `./web/src/components/Post/NewPost/
NewPost.js`
✔ Successfully wrote file `./api/src/graphql/posts.sdl.js`
✔ Successfully wrote file `./api/src/services/posts/posts.js`
✔ Successfully wrote file `./api/src/services/posts/posts.sce
narios.js`
✔ Successfully wrote file `./api/src/services/posts/posts.tes
t.js`
✔ Successfully wrote file `./web/src/scaffold.css`
✔ Successfully wrote file `./web/src/layouts/PostsLayout/Post
sLayout.js`
✔ Successfully wrote file `./web/src/pages/Post/EditPostPage/
✔ Generating scaffold files...
✔ Successfully wrote file `./web/src/components/Post/EditPost
Cell/EditPostCell.js`
✔ Successfully wrote file `./web/src/components/Post/Post/Pos
t.js`
✔ Successfully wrote file `./web/src/components/Post/PostCell
/PostCell.js`
✔ Successfully wrote file `./web/src/components/Post/PostForm
/PostForm.js`
✔ Successfully wrote file `./web/src/components/Post/Posts/Po
sts.js`
✔ Successfully wrote file `./web/src/components/Post/PostsCel
l/PostsCell.js`
✔ Successfully wrote file `./web/src/components/Post/NewPost/
NewPost.js`
✔ Successfully wrote file `./api/src/graphql/posts.sdl.js`
✔ Successfully wrote file `./api/src/services/posts/posts.js`
✔ Successfully wrote file `./api/src/services/posts/posts.sce
narios.js`
✔ Successfully wrote file `./api/src/services/posts/posts.tes
t.js`
✔ Successfully wrote file `./web/src/scaffold.css`
✔ Successfully wrote file `./web/src/layouts/PostsLayout/Post
sLayout.js`
✔ Successfully wrote file `./web/src/pages/Post/EditPostPage/
✔ Generating scaffold files...
✔ Successfully wrote file `./web/src/components/Post/EditPost
Cell/EditPostCell.js`
✔ Successfully wrote file `./web/src/components/Post/Post/Pos
t.js`
✔ Successfully wrote file `./web/src/components/Post/PostCell
/PostCell.js`
✔ Successfully wrote file `./web/src/components/Post/PostForm
/PostForm.js`
✔ Successfully wrote file `./web/src/components/Post/Posts/Po
sts.js`
✔ Successfully wrote file `./web/src/components/Post/PostsCel
l/PostsCell.js`
✔ Successfully wrote file `./web/src/components/Post/NewPost/
NewPost.js`
✔ Successfully wrote file `./api/src/graphql/posts.sdl.js`
✔ Successfully wrote file `./api/src/services/posts/posts.js`
✔ Successfully wrote file `./api/src/services/posts/posts.sce
narios.js`
✔ Successfully wrote file `./api/src/services/posts/posts.tes
t.js`
✔ Successfully wrote file `./web/src/scaffold.css`
✔ Successfully wrote file `./web/src/layouts/PostsLayout/Post
sLayout.js`
✔ Successfully wrote file `./web/src/pages/Post/EditPostPage/
EditPostPage.js`
✔ Successfully wrote file `./web/src/pages/Post/PostPage/Post
Page.js`
✔ Successfully wrote file `./web/src/pages/Post/PostsPage/Pos
tsPage.js`
✔ Successfully wrote file `./web/src/pages/Post/NewPostPage/N
ewPostPage.js`
✔ Adding layout import...
✔ Adding set import...
✔ Adding scaffold routes...
✔ Adding scaffold asset imports...
✔ Generating types ...
nik$ yarn rw dev
(node:18427) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
gen | (node:18454) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time
gen | (Use `node --trace-warnings ...` to show where the warning was created)
gen | Generating TypeScript definitions and GraphQL schemas...
gen | 28 files generated
web | (node:18458) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time
web | (Use `node --trace-warnings ...` to show where the warning was created)
api | (node:18497) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time
api | (Use `node --trace-warnings ...` to show where the warning was created)
api | Building... Took 369 ms
api | Debugger listening on ws://127.0.0.1:18911/e2286fbd-9a52-4503-9545-7bd60a5462e6
api | For help, see: https://nodejs.org/en/docs/inspector
web | assets by path static/js/*.js 4.44 MiB
web | asset static/js/app.bundle.js 2.88 MiB [emitted] (name: app) 1 related asset
web | asset static/js/src_pages_Post_PostsPage_PostsPage_js.chunk.js 458 KiB [emitted] 1 related asset
web | asset static/js/src_pages_Post_PostPage_PostPage_js.chunk.js 456 KiB [emitted] 1 related asset
web | asset static/js/src_pages_Post_EditPostPage_EditPostPage_js.chunk.js 319 KiB [emitted] 1 related asset
web | asset static/js/src_pages_Post_NewPostPage_NewPostPage_js.chunk.js 318 KiB [emitted] 1 related asset
web | asset static/js/runtime-app.bundle.js 49.3 KiB [emitted] (name: runtime-app) 1 related asset
web | asset static/js/src_pages_NotFoundPage_NotFoundPage_js.chunk.js 3.37 KiB [emitted] 1 related asset
web | asset README.md 1.9 KiB [emitted] [from: public/README.md] [copied]
web | asset favicon.png 1.7 KiB [emitted] [from: public/favicon.png] [copied]
web | asset index.html 483 bytes [emitted]
web | asset robots.txt 24 bytes [emitted] [from: public/robots.txt] [copied]
web | Entrypoint app 2.93 MiB (2.89 MiB) = static/js/runtime-app.bundle.js 49.3 KiB static/js/app.bundle.js 2.88 MiB 2 auxiliary assets
web | orphan modules 408 KiB [orphan] 116 modules
web | runtime modules 33.1 KiB 17 modules
web | modules by path ../node_modules/ 2.76 MiB 830 modules
web | modules by path ./src/ 72.1 KiB
web | modules by path ./src/components/Post/ 33 KiB 7 modules
web | modules by path ./src/pages/ 10.4 KiB
web | modules by path ./src/pages/Post/ 4.89 KiB 4 modules
web | + 2 modules
web | modules by path ./src/*.css 22.2 KiB
web | ./src/scaffold.css 2.39 KiB [built] [code generated]
web | + 3 modules
web | modules by path ./src/*.js 4.49 KiB
web | ./src/App.js 1.63 KiB [built] [code generated]
web | ./src/Routes.js 2.86 KiB [built] [code generated]
web | ./src/layouts/PostsLayout/PostsLayout.js 1.98 KiB [built] [code generated]
web | webpack 5.71.0 compiled successfully in 4112 ms
web | <e> [webpack-dev-server] [HPM] Error occurred while proxying request localhost:8910/graphql to http://[::1]:8911/ [ECONNREFUSED] (https://nodejs.org/api/errors.html#errors_common_system_errors)
api | Starting API Server...
api | Loading server config from /Users/nik/dev/learning/storybook/my-redwood-project/api/server.config.js
api |
api | Importing Server Functions...
api | /graphql 118 ms
api | (node:18502) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time
api | (Use `node --trace-warnings ...` to show where the warning was created)
api | ...Done importing in 119 ms
api | Took 161 ms
api | API listening on http://localhost:8911/
api | GraphQL endpoint at /graphql
api | 18:16:04 🌲 Server listening at http://[::]:8911
api | 18:18:39 🌲 incoming request POST xxx /graphql
api | 18:18:39 🐛 Checking if GraphiQL Request
api | 18:18:39 🐛 Extracting GraphQL Parameters
api | 18:18:39 🐛 Processing Request
api | 18:18:39 🐛 execute-start
api | 18:18:39 🐛 mutation CreatePostMutation($input: CreatePostInput!) {
api | createPost(input: $input) {
api | id
api | __typename
api | }
api | }
api | 18:18:39 🐛 CreatePostMutation
api | 18:18:39 🐛 variables
api | 18:18:39 🐛 graphql-server GraphQL execution started: CreatePostMutation
api | (node:18502) ExperimentalWarning: buffer.Blob is an experimental feature. This feature could change at any time
api | 18:18:39 🌲 Starting a sqlite pool with 13 connections.
api | 18:18:39 🐛 execute-end
api | 18:18:39 🐛 -->
api | 📦 Result Data
api | {
api | "createPost": {
api | "id": 1,
api | "__typename": "Post"
api | }
api | }
api | 18:18:39 🐛 graphql-server GraphQL execution completed: CreatePostMutation
api | 18:18:39 🌲 request completed 100ms
api | 18:18:39 🌲 incoming request POST xxx /graphql
api | 18:18:39 🐛 Checking if GraphiQL Request
api | 18:18:39 🐛 Extracting GraphQL Parameters
api | 18:18:39 🐛 Processing Request
api | 18:18:39 🐛 execute-start
api | 18:18:39 🐛 query FindPosts {
api | posts {
api | id
api | title
api | body
api | createdAt
api | __typename
api | }
api | }
api | 18:18:39 🐛 FindPosts
api | 18:18:39 🐛 variables
api | 18:18:39 🐛 graphql-server GraphQL execution started: FindPosts
api | 18:18:39 🐛 execute-end
api | 18:18:39 🐛 -->
api | 📦 Result Data
api | {
api | "posts": [
api | {
api | "id": 1,
api | "title": "shrimps",
api | "body": "I really love them - in any dish",
api | "createdAt": "2022-04-14T22:18:39.898Z",
api | "__typename": "Post"
api | }
api | ]
api | }
api | 18:18:39 🐛 graphql-server GraphQL execution completed: FindPosts
api | 18:18:39 🌲 request completed 7ms
This is the step from the very first introduction to RW - Quick Start | RedwoodJS Docs. If I tell anyone that I would like to undo this step (``yarn redwood g scaffold post`) everyone would tell me to start this app creation from scratch - and they would be right. However RW intent is to be used to create serious applications - and in that case, let me cite one of my friends here:
But at the end of the day, it’s just a bunch of best practices wrapped up in code generators. I don’t know if you see my blog ever, but the opening four paragraphs of this one capture my concerns with “wizards” of this type. The tutorial is impeccable in its explanations, but side effects like this one give me hives:
“In the Success component, where did posts come from?
In the QUERY statement, the query we’re calling is posts. Whatever the name of this query is, that’s the name of the prop that will be available in Success with your data.”
This kind of naming thing (very common these days; RWJS is no worse than any other) is awful. People do not remember where they come from; new people in the codebase have to spend hours debugging to figure out the provenance of the data, what the fields on the magic object are, etc. etc. … there is something to like about “opinionated” frameworks, but I want those opinions wrapped up in documented APIs, not invisible side-effects.
Now, assuming that it is possible and feasible to implement transactional development process it will address all critical comments of my friend (a very well known and respected person in the industry).
I also like your list @dom and I would like to see a number of additional application templates. At the moment, having just one (redwood-app
), app created RW apps have the same ancestor, and then many of us look for answers on how to remove parts of it (example: app that uses only API side).
Ideally, it would be great to have template generator with the support for storing the templates created with it, so the command:
yarn create my-rw-template my-redwood-project
Any type of application that has multiple client instances, where any of the clients might mutate the DB and the other clients shall be dynamically updated. Other examples include dynamic data sources such as IoT devices, that mutate the DB with telemetry (i.e. GPS location) and all clients shall dynamically update the location on a map.
All of these ideas are so good !! (Electron support !!)
My wishlist: (apologies up front for not using the right terminology in all cases)
–typescript to be the default for application creation, we should specify --javascript if we don’t want typescript
opinionated mutators - whether they be created via generator, or added via the IDE plugin as code snippets of some sort, or however. I don’t want to think about how to get mutators to work, I want them as easy as cells.
generators for adding envelop plugins like the rate limiter - I expect there are others
generators for adding scale – the one that comes to mind would be adding caching to GQL as was shown here: RedwoodJS Meetup December 2021: The v1 Release Candidate Special Edition - YouTube
generators for adding css frameworks – I want me some mui.com
anything that might help me to copy components, containers, layouts, pages into my new project from other redwood projects
Redwood Rules !!
Important explanation: I did not imply that my wishlist should be considered in the next release - it (wishlist) states only that it should be considered for the future.
Also:
- the generator - generator is not a new idea, however it is not available in any current JamStack framework today.
- the transactional app development would certainly be a big win over all alternative development environment, however it also is not a new idea - just look at every banking software.
Yes yes and yes
Wow!
After digging deeper into RedwoodJS, I must say it is an awesome framework.
In order to make it really AAA you must prioritize:
- SSR/Edge rendering
- Live queries (or something akin to GraphQL subscriptions, if not GraphQL subscriptions)
- Better i18n
Welcome @fenos !
There’s a team at work on this already, so it’s only a matter of time. Stay tuned! And if you have specific requirements/opinions, we’d love to hear about them to make sure we’ve got you covered.
welcome @zpeters! thanks for your git
suggestion. There is already some prior art in this space that we might be able to leverage if we did want to go with this implementation route:
Ideally, it would be great to have template generator with the support for storing the templates created with it
@adriatic, @realStandal and I were just talking about making generators more composable so that instead of generating component, test, story all at once, you could choose just a subset of those. This idea lends itself really nicely to your template idea.
The reversible generators is something I have not given all that much thought into, but is a very cool idea imho.
I would really like to be able to step forwards and backwards through the process started by
yarn create redwood-app
Is this the primary use case you envision for it? I can see a definite value in terms of documenting steps to help someone’s learning.
Typically, when I have seen transactional databases that allow for rolling transactions back, it is to reconcile an error that got into the data. In theory, if the rw
code generators are doing their job, no errors should come from them; so I see less value in being able to reverse them outside of a learning context. Super interested in hearing your thoughts.
@bitshift let me make some comments on your sentence
Is this the primary use case you envision for it? I can see a definite value in terms of documenting steps to help someone’s learning.
Help with learning is not the primary reason in my opinion - developing apps is more important. When I decided to participate in the last Tutorial QA, I was not a RW newbie, but wanted to check every written word (looking even for typos) as well as every JavaScript statement I wrote following the tutorial, trying to ensure that my just written copy is the same as Redwoods own finished copy. So, my task was a lot less difficult than to create a new copy - I followed the tutorial, after all.
Do not be surprised when I admit that in my adventure in recreating the tutorial, I made too many errors to admit that as well. In each such situation I felt a dire need to be able to “walk back” to just before I made the error. Alas, this wasn’t possible, so avoiding to use GitHub as my help, realizing that the code implementing support for real walk back would have to be a lot smarter than Github (example: I forgot to invoke a generator that creates a lot of changes, completely invisible to me), I would resort to start from scratch.
I am very interested in the idea of reversible generators and templates editing/modifying so, I may just start with better definition of these terms.
gotcha. If this is the desired behavior, I might recommend leveraging git
/ atomic commit convention. It could be interesting to tie in generators to git
so that you can easily “walk back” a step.
SSR/Edge rendering and anything perf related for me. Thanks for the work team!
My 2 cents:
- be able to share code between api & web (i.e. validation): nx? turborepo?
- background & scheduled jobs: either managed by the framework (so should be atomic, with redis? bull?), or via cloud providers (google pubsub?, aws queues? etc.)
- official and supported ways to connect a third party frontend library/framework (next.js, remix, svelte etc.) jointly with the redwood API : would probably boost redwood adoption
- GraphQL Subscriptions
- an official way (and documented example) of how to use another query builder/postgres driver (like slonik, postgres.js etc.) to execute e2e typesafe raw queries to overcome prisma2 limitations or for optimal performance if it is needed for some queries
The git atomic commit convention
would certainly help a lot if the application being built is a sequence of JavaScript code. The generators (used to create initial skeleton: yarn create redwood-app ./myapp
) add a lot of Javascript code, (example yarn redwood generate page home /
) at nearly any stage of my-app
development, and our “code-watcher” would know nothing of it. In other words, any generator would have to reversible.
Consider the extreme case - a finished application that you would like to “disassemble” into its parts expecting that it finally takes a form of “script” which resembles a puppeteer
driven process that can “reassemble” these parts, after you edit this puppeteer script and remove a step that caused the problem you want to rectify.
The consequence of such programming method would be that instead of claiming that we use JavaScript, we would say that we use puppeteer script, a much higher level of abstraction. Once you realize that Redwood offers a higher level of abstraction by using code generators just to help the developer not to have to implement all of the pedestrian code.
Yes, this does sound like a science fiction, but using the (then brand new “C compiler”) to generate the skeleton of Z80 assembly code, process I used to write OS firmware, many dismissed as science fiction approach.
It seems that I am responding to “Post-v10 feedback” wanted.
Oh, I forgot !!
Deploy to Gatsby !
I forget who mentioned that…
And Node 18
For a buddy of mine
I thought that was literally only for Gatsby sites. Can you actually deploy other things too?
well it turns out that he’s not really using Gatsby – he’s using dist folders and nginx and calling it gatsby apps – a little confusion there.
he admitted that if my app wanted to use any of the Gatsby features that I was out of luck…
File-based routing, ala NextJS . Maybe I’m alone in this since I haven’t seen it mentioned. But I found it really intuitive to work with.