kubeless
kubeless copied to clipboard
Support webpacked NodeJS functions
Opening this PR to track updates to this as I find them and also to get some feedback on where this can/should be enabled.
Is this a BUG REPORT or FEATURE REQUEST?:
Feature Request
What happened:
Running the deployed function results in the following output log output from the function invocation:
unction failed to execute: /kubeless/handlers.js:1
(function(e, a) { for(var i in a) e[i] = a[i]; }(exports, /******/ (function(modules) { // webpackBootstrap
^
ReferenceError: exports is not defined
at /kubeless/handlers.js:1:50
at ContextifyScript.Script.runInContext (vm.js:59:29)
at ContextifyScript.Script.runInNewContext (vm.js:65:15)
at app.all (/kubeless.js:146:20)
at Layer.handle [as handle_request] (/node_modules/express/lib/router/layer.js:95:5)
at next (/node_modules/express/lib/router/route.js:137:13)
at next (/node_modules/express/lib/router/route.js:131:14)
at next (/node_modules/express/lib/router/route.js:131:14)
at next (/node_modules/express/lib/router/route.js:131:14)
at next (/node_modules/express/lib/router/route.js:131:14)
::ffff:172.17.0.7 - - [25/May/2018:07:45:00 +0000] "GET / HTTP/1.1" 500 21 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"
What you expected to happen:
The function to run and return a result.
How to reproduce it (as minimally and precisely as possible):
Create a serverless-kubeless nodejs8 project with serverless-webpack also installed, deploy a function, call the function and then view the logs from the container.
This would probably be the same no matter what mechanism you were using to babel/webpack your nodejs code, even if you were using the kubeless
cli directly to deploy.
Anything else we need to know?:
ReferenceError: exports is not defined
happens using the serverless-webpack
plugin with serverless-kubeless
because kubeless is running the deployed in a new Script(...)
then script.runInNewContext
(see: https://github.com/kubeless/kubeless/blob/master/docker/runtime/nodejs/kubeless.js)
The issue is that the way webpack is packing the functions, it is meant to be require()
-d and if you actually do open the .serverless/[yourservice].zip
build artifact and then run node in your terminal and require the handlers.js
... it will work and you get all the functions you wrote back. But if it's not required and you instead try to run it the same way kubeless does, you get the same error because the exports
"global" variable is only available to require()
-d code.
I'm not sure what the right way to handle this is, but obviously being able to use webpack/babel in conjunction with kubeless/serverless is desirable.
The options I can think of are:
- somehow change the output of webpack so it doesn't use
exports
but instead usesmodule.exports
; - change the
serverless-kubeless
plugin to detect when the webpack plugin is being used (which can be done) and have the plugin make the necessary changes to the generated code before it base64s and sends it over to kubeless; - Have kubeless run the function so that it is
require()
-d instead of running it directly as it does now viascript.runInNewContext
via adding some extra bootstrapping code in a similar way to how therequire('kubeless')(module.exports)
line inkubeless.js
does now.
Environment:
- Kubernetes version (use
kubectl version
):
Client Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.7", GitCommit:"dd5e1a2978fd0b97d9b78e1564398aeea7e7fe92", GitTreeState:"clean", BuildDate:"2018-04-19T00:05:56Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.0", GitCommit:"fc32d2f3698e36b93322a3465f63a14e9f0eaead", GitTreeState:"clean",BuildDate:"2018-03-26T16:44:10Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}
- Kubeless version (use
kubeless version
):
Kubeless version: v1.0.0-alpha.3
- Cloud provider or physical cluster: minikube for now
Thanks for opening the issue @ianserlin. The first thing I would try would be to make it work through the option 3. I am not very familiar with webpack but if it is possible to run it just changing the way it is required it should be a possible approach (and choosing the require method with an env var).
@ianserlin i was able to figure it out - here's how - https://github.com/kubeless/kubeless/issues/1111#issuecomment-583674820