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

Adds support for root component #1009

Merged
merged 10 commits into from
Feb 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions waspc/ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# Changelog

## v0.8.2

### Bug fixes
- Fixes a file lock error that kills CLI when changing entities with `wasp start` running on newer Macs.

### Support for defining the web app's root component
You can now define a root component for your client app. This is useful if you want to wrap your app in a provider or have a common layout. You can define it in `app.client.rootComponent` in your `.wasp` file.

### `wasp deploy` CLI command added
We have made it much easier to deploy your Wasp apps via a new CLI command, `wasp deploy`. 🚀 This release adds support for Fly.io, but we hope to add more hosting providers soon!

Expand Down
25 changes: 17 additions & 8 deletions waspc/data/Generator/templates/react-app/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,25 @@ import ReactDOM from 'react-dom'
import { QueryClientProvider } from '@tanstack/react-query'

import router from './router'
import {
import {
initializeQueryClient,
queryClientInitialized,
} from './queryClient'
import * as serviceWorker from './serviceWorker'

{=# doesClientSetupFnExist =}
{=& clientSetupJsFnImportStatement =}
{=/ doesClientSetupFnExist =}
{=# setupFn.isDefined =}
{=& setupFn.importStatement =}
{=/ setupFn.isDefined =}
{=# rootComponent.isDefined =}
{=& rootComponent.importStatement =}
{=/ rootComponent.isDefined =}

startApp()

async function startApp() {
{=# doesClientSetupFnExist =}
await {= clientSetupJsFnIdentifier =}()
{=/ doesClientSetupFnExist =}
{=# setupFn.isDefined =}
await {= setupFn.importIdentifier =}()
{=/ setupFn.isDefined =}
initializeQueryClient()

await render()
Expand All @@ -34,7 +37,13 @@ async function render() {
const queryClient = await queryClientInitialized
ReactDOM.render(
<QueryClientProvider client={queryClient}>
{ router }
{=# rootComponent.isDefined =}
<{= rootComponent.importIdentifier =}>
{=/ rootComponent.isDefined =}
{router}
{=# rootComponent.isDefined =}
</{= rootComponent.importIdentifier =}>
{=/ rootComponent.isDefined =}
</QueryClientProvider>,
document.getElementById('root')
)
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions waspc/examples/todoApp/src/client/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export function App({ children }) {
return (
<div className="p-6">
<header className="mb-6">
<h1 className="text-3xl font-bold">ToDo App</h1>
</header>
{children}
</div>
);
}
1 change: 1 addition & 0 deletions waspc/examples/todoApp/todoApp.wasp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ app todoApp {
setupFn: import setup from "@server/serverSetup.js"
},
client: {
rootComponent: import { App } from "@client/App.jsx",
setupFn: import setup from "@client/clientSetup"
},
db: {
Expand Down
3 changes: 2 additions & 1 deletion waspc/src/Wasp/AppSpec/App/Client.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Data.Data (Data)
import Wasp.AppSpec.ExtImport (ExtImport)

data Client = Client
{ setupFn :: Maybe ExtImport
{ setupFn :: Maybe ExtImport,
rootComponent :: Maybe ExtImport
}
deriving (Show, Eq, Data)
23 changes: 19 additions & 4 deletions waspc/src/Wasp/Generator/JsImport.hs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
module Wasp.Generator.JsImport
( extImportToJsImport,
ImportLocation,
jsImportToImportJson,
)
where

import Data.Aeson (KeyValue ((.=)), object)
import qualified Data.Aeson as Aeson
import StrongPath (Dir, File', Path, Posix, Rel, (</>))
import qualified StrongPath as SP
import qualified Wasp.AppSpec.ExtImport as EI
Expand All @@ -12,15 +14,14 @@ import Wasp.Generator.ExternalCodeGenerator.Common (GeneratedExternalCodeDir)
import Wasp.JsImport
( JsImport,
JsImportName (JsImportField, JsImportModule),
getJsImportStmtAndIdentifier,
makeJsImport,
)

type ImportLocation = ()

extImportToJsImport ::
GeneratedSrcDir d =>
Path Posix (Rel d) (Dir GeneratedExternalCodeDir) ->
Path Posix (Rel ImportLocation) (Dir d) ->
Path Posix (Rel importLocation) (Dir d) ->
EI.ExtImport ->
JsImport
extImportToJsImport pathFromSrcDirToExtCodeDir pathFromImportLocationToSrcDir extImport = makeJsImport importPath importName
Expand All @@ -32,3 +33,17 @@ extImportToJsImport pathFromSrcDirToExtCodeDir pathFromImportLocationToSrcDir ex
extImportNameToJsImportName :: EI.ExtImportName -> JsImportName
extImportNameToJsImportName (EI.ExtImportModule name) = JsImportModule name
extImportNameToJsImportName (EI.ExtImportField name) = JsImportField name

jsImportToImportJson :: Maybe JsImport -> Aeson.Value
jsImportToImportJson maybeJsImport = maybe notDefinedValue mkTmplData maybeJsImport
where
notDefinedValue = object ["isDefined" .= False]

mkTmplData :: JsImport -> Aeson.Value
mkTmplData jsImport =
let (jsImportStmt, jsImportIdentifier) = getJsImportStmtAndIdentifier jsImport
in object
[ "isDefined" .= True,
"importStatement" .= jsImportStmt,
"importIdentifier" .= jsImportIdentifier
]
2 changes: 1 addition & 1 deletion waspc/src/Wasp/Generator/ServerGenerator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ genServerJs spec =
(maybeSetupJsFnImportStmt, maybeSetupJsFnImportIdentifier) =
(fst <$> maybeSetupJsFnImportDetails, snd <$> maybeSetupJsFnImportDetails)

relPathToServerSrcDir :: Path Posix (Rel ()) (Dir C.ServerSrcDir)
relPathToServerSrcDir :: Path Posix (Rel importLocation) (Dir C.ServerSrcDir)
relPathToServerSrcDir = [reldirP|./|]

genRoutesDir :: AppSpec -> Generator [FileDraft]
Expand Down
2 changes: 1 addition & 1 deletion waspc/src/Wasp/Generator/ServerGenerator/ExternalAuthG.hs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ getTmplDataForAuthMethodConfig auth authMethod =
maybeOnSignInFnImportDetails = getJsImportStmtAndIdentifier' <$> maybeGetUserFieldsFn
(maybeOnSignInFnImportStmt, maybeOnSignInFnImportIdentifier) = (fst <$> maybeOnSignInFnImportDetails, snd <$> maybeOnSignInFnImportDetails)

relPathFromAuthConfigToServerSrcDir :: Path Posix (Rel ()) (Dir C.ServerSrcDir)
relPathFromAuthConfigToServerSrcDir :: Path Posix (Rel importLocation) (Dir C.ServerSrcDir)
relPathFromAuthConfigToServerSrcDir = [reldirP|../../../../|]

depsRequiredByPassport :: AppSpec -> [App.Dependency.Dependency]
Expand Down
2 changes: 1 addition & 1 deletion waspc/src/Wasp/Generator/ServerGenerator/JobGenerator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ genJob (jobName, job) =
]
maybeJobSchedule = jobScheduleTmplData <$> J.schedule job

relPathFromJobsDirToServerSrcDir :: Path Posix (Rel ()) (Dir C.ServerSrcDir)
relPathFromJobsDirToServerSrcDir :: Path Posix (Rel importLocation) (Dir C.ServerSrcDir)
relPathFromJobsDirToServerSrcDir = [reldirP|../|]

-- Creates a file that is imported on the server to ensure all job JS modules are loaded
Expand Down
5 changes: 2 additions & 3 deletions waspc/src/Wasp/Generator/ServerGenerator/JsImport.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import Data.Maybe (fromJust)
import StrongPath (Dir, Path, Posix, Rel)
import qualified StrongPath as SP
import qualified Wasp.AppSpec.ExtImport as EI
import Wasp.Generator.JsImport (ImportLocation)
import qualified Wasp.Generator.JsImport as GJI
import Wasp.Generator.ServerGenerator.Common (ServerSrcDir)
import Wasp.Generator.ServerGenerator.ExternalCodeGenerator (extServerCodeDirInServerSrcDir)
Expand All @@ -16,13 +15,13 @@ import Wasp.JsImport
import qualified Wasp.JsImport as JI

getJsImportStmtAndIdentifier ::
Path Posix (Rel ImportLocation) (Dir ServerSrcDir) ->
Path Posix (Rel importLocation) (Dir ServerSrcDir) ->
EI.ExtImport ->
(JsImportStatement, JsImportIdentifier)
getJsImportStmtAndIdentifier pathFromImportLocationToExtCodeDir = JI.getJsImportStmtAndIdentifier . extImportToJsImport pathFromImportLocationToExtCodeDir

extImportToJsImport ::
Path Posix (Rel ImportLocation) (Dir ServerSrcDir) ->
Path Posix (Rel importLocation) (Dir ServerSrcDir) ->
EI.ExtImport ->
JsImport
extImportToJsImport = GJI.extImportToJsImport serverExtDir
Expand Down
2 changes: 1 addition & 1 deletion waspc/src/Wasp/Generator/ServerGenerator/OperationsG.hs
Original file line number Diff line number Diff line change
Expand Up @@ -134,5 +134,5 @@ operationTmplData operation =
where
(importStmt, importIdentifier) = getJsImportStmtAndIdentifier relPathFromOperationsDirToServerSrcDir (AS.Operation.getFn operation)

relPathFromOperationsDirToServerSrcDir :: Path Posix (Rel ()) (Dir C.ServerSrcDir)
relPathFromOperationsDirToServerSrcDir :: Path Posix (Rel importLocation) (Dir C.ServerSrcDir)
relPathFromOperationsDirToServerSrcDir = [reldirP|../|]
14 changes: 5 additions & 9 deletions waspc/src/Wasp/Generator/WebAppGenerator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ where

import Data.Aeson (object, (.=))
import Data.List (intercalate)
import Data.Maybe (fromMaybe, isJust)
import StrongPath
( Dir,
File',
Expand Down Expand Up @@ -46,7 +45,7 @@ import Wasp.Generator.WebAppGenerator.ExternalCodeGenerator
( extClientCodeGeneratorStrategy,
extSharedCodeGeneratorStrategy,
)
import Wasp.Generator.WebAppGenerator.JsImport (getJsImportStmtAndIdentifier)
import Wasp.Generator.WebAppGenerator.JsImport (extImportToImportJson)
import Wasp.Generator.WebAppGenerator.OperationsGenerator (genOperations)
import Wasp.Generator.WebAppGenerator.RouterGenerator (genRouter)
import Wasp.Util ((<++>))
Expand Down Expand Up @@ -246,16 +245,13 @@ genIndexJs spec =
(C.asWebAppFile [relfile|src/index.js|])
( Just $
object
[ "doesClientSetupFnExist" .= isJust maybeSetupJsFunction,
"clientSetupJsFnImportStatement" .= fromMaybe "" maybeSetupJsFnImportStmt,
"clientSetupJsFnIdentifier" .= fromMaybe "" maybeSetupJsFnImportIdentifier
[ "setupFn" .= extImportToImportJson relPathToWebAppSrcDir maybeSetupJsFunction,
"rootComponent" .= extImportToImportJson relPathToWebAppSrcDir maybeRootComponent
]
)
where
maybeSetupJsFunction = AS.App.Client.setupFn =<< AS.App.client (snd $ getApp spec)
maybeSetupJsFnImportDetails = getJsImportStmtAndIdentifier relPathToWebAppSrcDir <$> maybeSetupJsFunction
(maybeSetupJsFnImportStmt, maybeSetupJsFnImportIdentifier) =
(fst <$> maybeSetupJsFnImportDetails, snd <$> maybeSetupJsFnImportDetails)
maybeRootComponent = AS.App.Client.rootComponent =<< AS.App.client (snd $ getApp spec)

relPathToWebAppSrcDir :: Path Posix (Rel ()) (Dir C.WebAppSrcDir)
relPathToWebAppSrcDir :: Path Posix (Rel importLocation) (Dir C.WebAppSrcDir)
relPathToWebAppSrcDir = [reldirP|./|]
18 changes: 15 additions & 3 deletions waspc/src/Wasp/Generator/WebAppGenerator/JsImport.hs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
module Wasp.Generator.WebAppGenerator.JsImport where

import qualified Data.Aeson as Aeson
import Data.Maybe (fromJust)
import StrongPath (Dir, Path, Posix, Rel)
import qualified StrongPath as SP
import Wasp.AppSpec.ExtImport (ExtImport)
import qualified Wasp.AppSpec.ExtImport as EI
import Wasp.Generator.JsImport (ImportLocation)
import Wasp.Generator.JsImport
( jsImportToImportJson,
)
import qualified Wasp.Generator.JsImport as GJI
import Wasp.Generator.WebAppGenerator.Common (WebAppSrcDir)
import Wasp.Generator.WebAppGenerator.ExternalCodeGenerator (extClientCodeDirInWebAppSrcDir)
Expand All @@ -15,14 +19,22 @@ import Wasp.JsImport
)
import qualified Wasp.JsImport as JI

extImportToImportJson ::
Path Posix (Rel importLocation) (Dir WebAppSrcDir) ->
Maybe ExtImport ->
Aeson.Value
extImportToImportJson pathFromImportLocationToSrcDir maybeExtImport = jsImportToImportJson jsImport
where
jsImport = extImportToJsImport pathFromImportLocationToSrcDir <$> maybeExtImport

getJsImportStmtAndIdentifier ::
Path Posix (Rel ImportLocation) (Dir WebAppSrcDir) ->
Path Posix (Rel importLocation) (Dir WebAppSrcDir) ->
EI.ExtImport ->
(JsImportStatement, JsImportIdentifier)
getJsImportStmtAndIdentifier pathFromImportLocationToSrcDir = JI.getJsImportStmtAndIdentifier . extImportToJsImport pathFromImportLocationToSrcDir

extImportToJsImport ::
Path Posix (Rel ImportLocation) (Dir WebAppSrcDir) ->
Path Posix (Rel importLocation) (Dir WebAppSrcDir) ->
EI.ExtImport ->
JsImport
extImportToJsImport = GJI.extImportToJsImport webAppExtDir
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ createPageTemplateData page =
importStmt :: String
(importStmt, _) = getJsImportStmtAndIdentifier $ applyJsImportAlias (Just importAlias) $ extImportToJsImport relPathToWebAppSrcDir pageComponent

relPathToWebAppSrcDir :: Path Posix (Rel ()) (Dir C.WebAppSrcDir)
relPathToWebAppSrcDir :: Path Posix (Rel importLocation) (Dir C.WebAppSrcDir)
relPathToWebAppSrcDir = [reldirP|./|]

pageComponent :: AS.ExtImport.ExtImport
Expand Down
Loading