-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Detecting server imports on the client #2442
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Mihovil Ilakovac <[email protected]>
Signed-off-by: Mihovil Ilakovac <[email protected]>
moduleName: string; | ||
} | ||
|
||
const importStatementRegex = /\s*import\s+(?:(?:[\w*\s{},]*)\s+from\s+)?(['"`])([^'"`]+)\1\s*/g; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't dive deep, just wanted to check, since this is regex, is there a chance of false positives? If so, in which situations, and are we ok with that? If not, can we do it better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, could we maybe parse the import and do something with its AST (I'm not sure how powerful these plugins are, just throwing out ideas)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Vite doesn't expose AST information to the plugins. One the popular plugins unplugin-ast uses the Babel parser under the hood to parse files into AST.
I didn't want to go down this route due to potential performance issues, but I have to admit that I haven't timed anything. I just assumed that regexes will be good enough.
I went with a good enough approach because we are not catch all server imports anyways. We are only focusing on wasp/server/*
modules (for which we know they shouldn't be imported on the client). But... we don't catch stuff like some-node-dep
.
I will explore the AST approach and see how it works and report back. I'll also explore the JS imports syntax and see if our regex matches all the cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love the change, but have some reserverations about the implementation.
return { | ||
name: 'wasp-detect-server-imports', | ||
transform(code, filePath) { | ||
const isInDotWaspFolder = filePath.includes("/.wasp/"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a more appropriate way to do this? For example, by saying "check only src
"?
importStatement: match[0].trim(), | ||
moduleName: match[2], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to destructure the array and name each segment instead of using indexes.
} | ||
|
||
function getServerImportErrorMessage(imp: Import, filePath: string): string { | ||
return `Client module "${getRelativeFilePath(filePath)}" imports server code: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a double space, don't forget to run a formatter :)
-- Vite plugins | ||
genFileCopy [relfile|vite/detectServerImports.ts|] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of writing a comment, we should scope the file under an appropriately named function/variable. For example:
genVitePlugins :: ...
genVitePlugins = ...
Or
genViteFiles :: ...
genViteFiles ...
where config = ...
plugins = ...
// user running the tests, which is different on different machines. | ||
function getWaspProjectDirAbsPathFromCwd(): string { | ||
const webAppDirAbsPath = process.cwd(); | ||
const waspProjectDirAbsPath = path.join(webAppDirAbsPath, "../../../"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already defined this relative path somewhere, probably in multiple places.
I know it's defined in one of our JS files. I think even Haskell code defines a constant under Project.Common
(but perhaps this wasn't merged)
In any case, this knowledge should definitely come from Haskell. If you're up for it, you could change it in those other places too.
Also, I don't understand the reason we couldn't pass waspProjectDir
. Could we add some more details in the comment? Perhaps an example (what it is vs. what we need)?
@@ -6,5 +6,5 @@ | |||
"moduleResolution": "bundler", | |||
"allowSyntheticDefaultImports": true | |||
}, | |||
"include": ["vite.config.ts", "./src/ext-src/vite.config.ts"] | |||
"include": ["vite.config.ts", "./src/ext-src/vite.config.ts", "./vite/detectServerImports.ts"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, this is starting to feel like something we should pass in through the template.
function getRelativeFilePath(filePath: string): string { | ||
return filePath.replace(waspProjectDirAbsPath, ""); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we improve this function's name?
moduleName: string; | ||
} | ||
|
||
const importStatementRegex = /\s*import\s+(?:(?:[\w*\s{},]*)\s+from\s+)?(['"`])([^'"`]+)\1\s*/g; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, could we maybe parse the import and do something with its AST (I'm not sure how powerful these plugins are, just throwing out ideas)?
Signed-off-by: Mihovil Ilakovac <[email protected]>
We want to detect imports from
wasp/server/*
in users' client code because we know it's incorrect. It's better to give users a nice error message than users receiving some (often hard to understand) runtime error message.This is a draft initial implementation, I'll iterate on this a bit more.
Closes #2067