installing SST in a monorepo sometimes breaks all ...
# help
d
installing SST in a monorepo sometimes breaks all CDK apps in that monorepo Getting an error again
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined in /Users/derekkershner/repos/resonance-infrastructure-foundations/node_modules/@serverless-stack/resources/package.json
This time removing peerDependencies from the lib that builds on SST didnt work. Version
1.2.25
. Original time I got error: https://serverless-stack.slack.com/archives/C01JG3B20RY/p1653704371418879
Since I can use this package in other places, I believe this has something to do with: 1. Having a library that uses SST. 2. Linking that library to an App using turborepo (or any other linking method). It also must have something to do with ESM exporting, as the version timing seems to correlate.
t
can I see how you're importing?
we do specify an
exports
for
import
but not for require
we're not shipping a cjs version of sst/resources
d
I am definitely not using
require
anywhere.
t
yeah but depending on the version of sst it might be compiling your stacks code to cjs
it no longer does that
d
import * as sst from "@serverless-stack-slack/resources";
t
did you say you're doing this in a normal cdk app?
how is it being compiled?
d
if I am using SST, its in an SST app
you asking about
tsconfig
module
?
t
there was a time where
cat .build/lib/index.js
would give you a cjs module
is there more info with the error? like a stack trace
d
yes
Copy code
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined in /Users/derekkershner/repos/global-monorepo-devops/node_modules/@serverless-stack/resources/package.json
    at new NodeError (node:internal/errors:372:5)
    at throwExportsNotFound (node:internal/modules/esm/resolve:472:9)
    at packageExportsResolve (node:internal/modules/esm/resolve:693:7)
    at resolveExports (node:internal/modules/cjs/loader:482:36)
    at Function.Module._findPath (node:internal/modules/cjs/loader:522:31)
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:919:27)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (/Users/derekkershner/repos/global-monorepo-devops/packages/cdk-constructs/dist/cjs/NextjsStaticSite/index.js:32:26)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
NextJsStaticSite
is a construct that extends
StaticSite
t
Copy code
cdk-constructs/dist/cjs/
d
yeah, we export our libs in both CJS and ESM
t
yeah we only export ESM so importing sst from cjs won't work
d
well, it definitely does from an APP using commonjs, just not from a LIB that exports as commonjs
although, I feel like I have successfully gotten this to work in other libs that went all in on ESM
t
are you sure they weren't also shipping cjs versions?
d
and im actually pretty sure this even works if I PUBLISH the lib and then install it
t
yeah it would work because SST will take your stacks code and transpile + bundle all of it
so everything will get converted to esm before running
d
are you sure they weren’t also shipping cjs versions?
yes,
remark
rehype
as an example
what version did you guys stop publishing?
i had this up and running with
1.2.11
can verify that SOMETIMES this same lib works fine, and sometimes it doest…
its really inconsistent in how the error occurs, all consuming apps are nearly identical tsconfig-wise
and all module
commonjs
two apps installing in the same monorepo, one fails, other succeeds…
its the same `node_modules`…weirdly
actually, I may have it identified…I think you were correct on the
<http://cdk.App|cdk.App>
. We don’t use
SST
, but it is installed, and that alone is enough to break.
I believe I can split off the SST constructs into a separate lib to solve that issue, and the SST lib appears to work if installed NOT locally, its just linking locally that doesnt work.
maybe not…even in an app that doesnt install SST or reference it in any way, will error even if it is just in the same monorepo with something that does install SST
confirmed, installing SST in a monorepo now breaks all CDK apps in that monorepo
it doesnt seem to have anything to do with the lib, despite me thinking so
@Seth Geoghegan, I am guessing you guys do something similar, see a few messages above this one.
@thdxr, any ideas on how to solve this? I am reasonably certain the idea was not to break nearby CDK apps.
I am running out of ideas other than some fairly severe ones.
alright, I got everything into a working state, am now working on a reproduction for you guys
I cant reproduce the error given the very simple example stacks, so it must be something somewhat specific to the CDK app in question.
i also cant reproduce it in a different repo with CDK and SST apps…whatever causes the issue I am really struggling to pin down.
ok, im back to thinking it is the lib, perhaps it is as simple as that.
Alright, I think I finally have everything in an OK spot on this, though the process is only about 10% complete, I at least have a path. For others experiencing this, you just must make every library that references SST in any way export ESM only, and then any libraries that reference those libraries ESM only. I’d estimate this at about a 30 hour job for our stack. To the SST gang, please consider using a major version bump on breaking changes like this. It enables teams to set aside time and migrate everything rather than get surprised by what seems like an innocuous bump.
t
Sorry for the trouble here, we failed to consider people using the resources package as a library. For normal SST usage it all gets transpiled by esbuild so we didn't see it as a major change
We can ship a cjs version of sst resources if that helps you?
d
it wouldve yesterday! lol
im OK with any decisions you guys make, and want to support best I can, I just need to be out in front so that it doesn’t hamper my team’s ability to move forward.
and as we all know, dependencies are a crazy sore spot in every language, so I would encourage just being really careful in that area as the users of your lib are likely to experience required change at magnitudes more than the work required for the libs themselves.
t
oh you know what I can't even ship this as cjs anymore because of those weird dynamic imports I had to do to keep those dependencies (GraphQL etc) truly optional
d
i believe I actually had those working with CJS (since I was a proponent of that change). TS probably did something to backwards compatible it.
t
remember our case is that we can't use async inside the constructs because they're constructor based
so I had to do it at top level which requires ESM
d
btw, our use case for libs that consume SST is to create SST based constructs (more level 3s, on top of your guys’ constructs) and then use em all around the architecture.
t
you mentioned earlier you sometimes use them in CDK projects, how does that work? I thought our constructs needed to be initialized with an sst.App
d
its tough to say when exactly it broke, because it only breaks in certain circumstances, and the errors are all over the place.
we actually dont, but our shared libraries contained both SST and CDK constructs, and we just used them appropriately. We can no longer export this way, or at least, it is less work to not do so.
t
ah ok
d
we also had chains of libraries, because we also built on top of our own constructs…
you can see where this is going…
actually, I bet the GQL change didnt break us because we dont actually use the GQL construct… seems like CJS would break anyway, but who knows.
t
yeah it's tedious, I basically had to do something similar when converting all our stuff
d
yeah, I am not a fan of the tradeoffs for ESM packages for Node, especially after so many years of TS making it so seamless to convert ESM syntax to CJS.
BTW, the ORIGINAL problem I was solving yesterday was using webapps as Root as opposed to them having their own package.json/lock/modules. After having it done in a few places, I can fairly firmly say that, especially in monorepos, it is vastly preferred, and damn near critical in situations where you are using a Lib inside the same monorepo in the webapp.
(kinda like the recommended way to do APIs with SST or NodeJsLambda is to only have one package.json)
some of the reason for the firm recommendation is lesser dependencies in SST itself, which i know was a lift for you guys, but it has paid dividends here.