Closed jscottsf closed 3 weeks ago
Additional info
The build step is:
# 7. Bundle telefunc function to a single file.
echo "INFO: Bundling SSR render functions"
cd .vercel/output/functions/_telefunc.func
npx ncc build --minify --out . index.js
if [ $? -ne 0 ]
then
echo "ERRO: Bundling failed, exiting"
exit 1
fi
The runtime config is:
{
"handler": "index.js",
"launcherType": "Nodejs",
"runtime": "nodejs20.x",
"shouldAddHelpers": true
}
Seems to be happening at this line inside loadTelefuncFiles
:
if (!(0, o.isWebpack)() || (0, o.isVikeApp)()) {
Looks like ncc
is Webpack-based, and the assertion is failing on the Webpack test.
It seems to be a relatively simple issue: the failing assertion inside isWebpack()
means that the test for checking whether the environment is webpack isn't working as expected. Ideas for improving the isWebpack()
function? I guess there is a newer/better way to check?
Here is the ncc packed output for the current function, if this helps.
;(s, t, a) => {
Object.defineProperty(t, '__esModule', { value: true })
t.isWebpack = void 0
const o = a(80241)
function isWebpack() {
const s = typeof require === 'function'
const t = typeof a === 'function'
;(0, o.assert)(s === t)
return s || t
}
t.isWebpack = isWebpack
}
Also looks like they replace __webpack_require__
with some form of __nccwpck_require<n>_
https://github.com/vercel/ncc/blob/b2a325dec1dc54f2168f838dee0b9e48ee701d18/src/index.js#L552
Maybe this could be a config setting or ENV var to guide/override the loading process in challenging installs?
Good to know, thank you!
Fix released as 0.1.79
.
Well, now Vercel is throwing this. Hmmm.
Calling: {
method: 'POST',
url: '/_telefunc',
rawBody: '{"file":"/src/telefuncs/Cart.telefunc.js","name":"fnLoadCart","args":[true,null,null]}'
}
Error: [telefunc@0.1.79][Wrong Usage] You don't seem to be using Telefunc with a supported stack. Reach out on GitHub.
at loadTelefuncFiles (file:///var/task/index.js:65:17127)
at runTelefunc_ (file:///var/task/index.js:65:7443)
at runTelefunc (file:///var/task/index.js:65:6584)
at telefunc (file:///var/task/index.js:65:32015)
at handler (file:///var/task/index.js:71:1612340)
at async Server.<anonymous> (/opt/rust/nodejs.js:1:10566)
at async Server.<anonymous> (/opt/rust/nodejs.js:8:4242)
Hm. What does isWebpack()
return? Ideas to make the the isWebpack()
check work?
A bit confused actually. What code path are we trying to go down? The web app is Vike, but the serverless function is built with ncc (webpack). The serverless load is failing on invocation.
Would it help to specify the Telefunc file to load? I only have one with all server side behaviors for a cart system.
Since we reached the assertUsage
at the end:
isWebpack()
must be true
now (the inner assert was removed and one of the tests passed).
isVikeApp()
must be false
since we didn't enter the block.
!isWebpack() || isVikeApp()
false || false
Is the intent to have this block run?
if (!isWebpack() || isVikeApp()) {
const { telefuncFilesLoaded, viteProvider, telefuncFilesAll } = await loadTelefuncFilesWithVite(runContext)
assertUsage(Object.keys(telefuncFilesAll).length > 0, getNothingFoundErr(`Vite [\`${viteProvider}\`]`))
return { telefuncFilesLoaded, telefuncFilesAll }
}
You're right.
isVikeApp()
must befalse
since we didn't enter the block.
That seems to be the culprit. Why is it false
even though you're using Vike? What Vike version are you using? Vike sets globalThis._isVikeApp
at node_modules/vike/dist/esm/node/runtime/index-common.js
(or dist/cjs
if you aren't using ESM).
(Btw. reproduction welcome if you prefer.)
├── telefunc@0.1.79
├── vike@0.4.195
I have two serverless function builds. One for a Vike SSR, and another just for Telefunc. I wanted separate functions. Since Vike is not imported in the Telefunc one, is the global not getting set?
# 6. Bundle render function to a single file.
echo "INFO: Bundling SSR render functions"
cd .vercel/output/functions/ssr_.func
npx ncc build --minify --out . index.js
if [ $? -ne 0 ]
then
echo "ERRO: Bundling failed, exiting"
exit 1
fi
cd ../../../..
# 7. Bundle telefunc function to a single file.
echo "INFO: Bundling SSR render functions"
cd .vercel/output/functions/_telefunc.func
npx ncc build --minify --out . index.js
if [ $? -ne 0 ]
then
echo "ERRO: Bundling failed, exiting"
exit 1
fi
cd ../../../..
That makes sense. I've an idea to make it work. Let me finish what I'm currently working on then I'll implement it.
Solved it.
If you are using a Vike file structure, but not importing it in a serverless function implementation, then just do:
globalThis._isVikeApp = true
import { telefunc } from 'telefunc'
import { text } from 'micro'
export default async function handler(req, res) {
const { method, url } = req
if (url === '/_telefunc') {
const context = {}
const rawBody = await text(req)
console.log('Calling:', { method, url, rawBody })
globalThis._isVikeApp = true // DO THIS
const httpResponse = await telefunc({
url,
method,
body: rawBody,
context
})
const { body, statusCode, contentType } = httpResponse
res.statusCode = statusCode
res.setHeader('content-type', contentType)
res.end(body)
}
}
Also, the Webpack fix you made allows this to work with ncc
since it's a bit more relaxed.
Thank you!!!
Indeed, that workaround should work. I'll be implementing a proper fix next week.
Fix released in 0.1.81
.
Followed the examples and deployed a Vercel serverless handler. Upon calling a function, a "bug" is logged. Everything builds correctly and it runs locally with a dev server. Using Build Output API v3.
Vercel serverless log:
The handler:
Config.json
NOTE: I have a Vike serverless renderer as another function and it works perfectly.
Any ideas on what to try?