Having issues with StaticSite in regards to the en...
# help
d
Having issues with StaticSite in regards to the env vars. • WORKS -
yarn workspace frontend run build
(gatsby build) • NO WORK -
yarn deploy
(SST)
Copy code
The site's gatsby-config.js failed validation:

"siteMetadata.siteUrl" must be a valid uri
Likely because we have a number of gatsby plugins that need the
GATSBY_SITE_URL
in order to work. Ex.
gatsby-plugin-robots-txt
, and
siteMetadata
all inside
gatsby-config.js
I tried to just create the manual
.env
file in the frontend root and thats what allows the build to work locally with
yarn workspace frontend run build
but running
yarn deploy
from the root causes sst to fail. So not only is the envs that we’re passing into StaticSite don’t work, but neither does that
.env
file in the
frontend
folder.
I think the issue is that not only do those ENVs need to be provided/replaced IN the built JS… but they also need to be provided to the execSync build step. @thdxr Could we not pass them in here as well? Oh…. weird…. it looks like you already are passing them in?
is it because you are passing in the *tokenized *vars into the execSync and not the originals?
going to grab lunch and then try passing the untokenized to the execSync and see what happens
Yup… thats the issue I bet. When I console.log
siteMetadata
in
gatsby-config.esm.js
I get ….
Copy code
{
  siteMetadata: {
    siteUrl: '{{ GATSBY_SITE_URL }}',
    stackname: '{{ GATSBY_STACKNAME }}',
    gitVersion: '{{ GATSBY_GIT_SHORT }}'
  }
}
f
Hey @Dan Van Brunt, are you passing in a static string value for
siteUrl
?
d
@Frank no, it usually comes from the stack outputs (in the SLS days)
t
The issue is at build time we don't have access to those values since it requires us to actually deploy the resources
d
usually SLS would completely deploy the stack and return the url. This url “used” to be dynamic as part of the stack… but I supposed we could hard code it now.
t
@Frank I've been thinking the word
environment
is a bit confusing because people expect those values would be passed in as process.env
f
@Dan Van Brunt is
siteUrl
coming from another stack in the same SST app?
d
I’m still trying to noodle how exactly its working now. I guess you are building the frontend files BEFORE the CDK template deploy. and then swapping out the values in the built code via a custom resource IN the deployed stack?
f
@thdxr yeah I can the confusion at build time.. thought they are often used as
process.env
in React/Next.js site
@Dan Van Brunt yeah exactly that. Imagine you haven’t deployed ur app, when you are building,
siteUrl
is unknown. So SST uses a placeholder
{{ xxxxx }}
, and creates a Custom Resource that will go in and replaces
{{ xxxx }}}
with the actual url after it is deployed.
d
makes sense. I still think there needs to be two types of envs …. one for values known at build-time and ones only known after build-time. We still need to be able to pass in values into the frontend during build time
example…. STACKNAME GIT_SHORT
both of those are available at build time
even the siteurl itself we can hardcode into the stack but it needs to be passed into the
execSync
as untokenized
f
Okay.. I’m going to put it in the next release.. if value is a constant, we skip the placeholder step.
I can put that in by later today/tmr.
d
what would that look like?
how do you know its a constant?
f
cdk has this
isResolvable()
function, where it can tell u if something is resolvable (ie. untokenized) or not.
d
like say for the stackname… that would come from
Copy code
const { name: SERVICE, stage: STAGE } = scope
    const STACKNAME = `${SERVICE}-${STAGE}`
for us
oh? neat! so you could just test all the variables in the loop and tokenize as-needed?
f
yup yup
the check will be:
Copy code
cdk.Token.isUnresolved(value)
d
only other thing to consider…. is that in the case of
siteUrl
we need that var in both the gatsby cli build as well as a process.env post build. … So I guess this would still work… all the untokenized (Resolvables) would just get baked in at build time by gatsby cli as usual. Since they already equal the actual string. Vs any tokenized ones that are not Resolvable…. which would get baked in by Gatsby as tokens and replaced by the custom resource later
f
I think if u pass the value to gatsby cli build, it will replace
process.env
at build time right?
d
ya… so just checking that this works both ways…. and I think it does?
cool!
@Frank you want me to give a PR a go?
f
I’m not too familiar with Gatsby, but React and Next.js work this way, so i’m guessing it will work 🙂
d
ya in that way they are the same
I’ve used all 3
f
You are more than welcome to give a go at it man! Here’s the issue - https://github.com/serverless-stack/serverless-stack/issues/893
d
thanks! will take a peak.
t
oo
cdk.Token.isUnresolved
cool
f
@Dan Van Brunt Just updated the issue with a detailed spec - https://github.com/serverless-stack/serverless-stack/issues/893
t
That's clever, then we can keep it just as one environment field
f
Feel free to skip the last 2 tests if you are pressed for time, I can go in and fix up the tests.
d
kk
f
@thdxr Yeah let’s try that.. and see if ppl are confused by it
d
I like it…. just need to noodle how it all works if your implementation is complex
Quick question regarding usual PR workflow • checkout upstream master to my fork • create branch
dvb-envs
• commit changes with tests and proper commit msg with
Fixes #893
in the body • Submit PR from
dvb-envs
->
upstream master
Anything else? does things get CI tested right then? I noticed running tests locally doesnt work.
f
d
hmm kk… will try again
f
Does this work:
Copy code
cd packages/resources
yarn test StaticSite
d
oh… I tried testing the whole thing…. oh and it was when I was editing the core or CLI I think
t
I do experience some flaky stuff sometimes when running all the tests, haven't tracked it down
d
…well as expected… it works. 🙂 Will take a quick peak at tests and then PR
oh.. just realizing that
environment
StaticSite prop nets out to
environment
AND
replaceValues
. Where
replaceValues
prop is ONLY
replaceValues
is that right? If so… should not this test also test replaceValues?
f
Yup that’s totally right!
Should’ve tested for replaceValues 🤒
d
nw… still learning myself… just want to be sure I wasn’t missing something
@Frank I don’t understand what this is testing… There is an
index.html
file that already has
{{ REACT_APP_API_URL }}
in it. Then we read that file into the test… and test if that exact value is in it. ??? Why would it not be?
I guess I’m now wondering what the different use cases are for
environment
vs
replaceValues
f
hmm the test is out dated.
t
it's a very stable test
d
lol… ok so I’m not crazy. It’s not really testing anything 😛
f
The tests was originally meant to test the environment varialbe in a React site was removed upon build
There’s no point testing it here, let me fix it after u push the PR.
d
so what SHOULD the resulting HTML value be? would it not just keep the same value?
also…. since this isn’t using react build as part of the test…. its not completely accurate, no?
f
yeah, it was moved around and not update-to-date
d
I think I have a hang of what we are trying to test though….I think we want to test to see what is being put into the
Custom::SSTBucketDeployment > ReplaceValues
when the value is inresolvable or not
f
Yup
d
kk lemme see if I can rewrite for that for now.
can be extended to include react or something later
f
To answer the environment vs replacevalues question above, so
environment
does a couple of things: 1. set the env vars in the
npm build
command 2. sets the
replaceValues
3. generates a metadata file consumed by
sst-env
to make the env vars available when you run
npm start
in for React app
d
cool
Am I doing something wrong… I run
yarn watch
in the root and then I edit and save
packages/resources/test/StaticSite.test.ts
and nothing seems to compile ?
tests compile on the fly?
t
you don't need the watcher if you're just doing work on resources
d
k
t
for tests, jest compiles the tests itself using
ts-jest
. Been meaning to switch it to
esr
which is a lot faster
d
kk
f
@thdxr u meant we don’t need the watcher if we are working on tests right? Need it for resources?
d
I think that is what I was thinking was meant
t
You don't need it for resources either if you're working just on the resources package. Only need watcher if you're using a different project to test and linking to it
d
right… which I think I would do if I were working on resources
f
I often rely on the watcher to show me errors in resources as i’m working on them 🤔
t
I need to get you on neovim 😄
A lot of projects like vite, snowpack don't even run typechecking as part of their process because they assume people just rely on whatever their editor does
f
😢 Fine
d
Is this what we want the output to look like in the case of something that is UNresolved?
Copy code
{
  "Fn::GetAtt": [
    "ApiCD79AAA0",
    "ApiEndpoint"
  ]
}
I think so… so my next question would be… how should I TEST for that output since I assume that key is unique hash. Should I just test that its a
Fn::GetAtt
?
which looking at the
haveResource
stuff… doesn’t seem super straighforward
f
Yeah, or just test
replace
exists is fine. Whereas for the constant value case,
ReplaceValues
should be empty.
d
hmm… or is it… Resolvable (constant) === No ReplaceValues Unresolvable === ReplaceValues
f
yup
d
is there no way to do something like this…
Copy code
expectCdk(stack).to(
    haveResource("Custom::SSTBucketDeployment", {
      ReplaceValues: not(arrayWith(objectLike({
        search: "{{ REACT_APP_CONSTANT }}"
      }))),
    })
  );
meaning I want to be sure there is NO object in the array like this
nm… got it.
Copy code
expectCdk(stack).to(
    haveResource("Custom::SSTBucketDeployment", {
      ReplaceValues: notMatching(arrayWith(objectLike({
        search: "{{ REACT_APP_CONSTANT }}",
      }))),
    })
  );
@Frank got StaticSite.test.ts working. however, ReactStaticSite.test.ts is erroring out and doing something odd…. this test is REPLACING the index.html value with
undefined
https://github.com/serverless-stack/serverless-stack/blob/master/packages/resources/test/ReactStaticSite.test.ts#L69
Not really sure where in the code this replacing is happening
got it… but would love to chat later about this.
@thdxr looks like missing label is failing the build. Any idea how I would do that as part of the PR?
t
I have to add it, will do
f
@Dan Van Brunt Released this in v0.46.0!
Thanks for taking a crack at this!