piscinajs / piscina

A fast, efficient Node.js Worker Thread Pool implementation

Home Page:https://piscinajs.github.io/piscina/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

No handler function exported after building via webpack

sollidy opened this issue · comments

Hello! I try to use piscina vs js after webpack, and always get error No handler function exported from ...

worker.js without webpack - working well

i don't pass name to run() function

function convertStruct(arrayBuffer) {
  return Promise.resolve(['test']);
}
module.exports = convertStruct;

worker.js after webpack doesn't work

i pass name, or without name

/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it uses a non-standard name for the exports (exports).
(() => {
var exports = __webpack_exports__;

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.convertStruct = void 0;
function convertStruct(arrayBuffer) {
    return Promise.resolve(['test']);
}
exports.convertStruct = convertStruct;

})();

/******/ })()
;

Hey!
I’m not really well versed in webpack but the JS code as outcome after using Webpack is sadly wrong as it exposes the entry point as a named export instead of being the only export for the worker. To work, the outcome should look slightly like this:

/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it uses a non-standard name for the exports (exports).
(() => {
var exports = __webpack_exports__;

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.convertStruct = void 0;
function convertStruct(arrayBuffer) {
    return Promise.resolve(['test']);
}
exports = convertStruct;

})();

/******/ })()
;

I’m not sure why is your reason to use webpack for Node code, but unless you are able to sort out this issue, most likely it would be better to not use webpack at all

Sorry, but I take back what I said; I totally forgot this is doable in Piscina.
You can do something like:

    piscina.run({ a: 4, b: 6 }, { name: 'convertStruct' }),
    piscina.run({ a: 4, b: 6 }, { name: 'anotherTask' })

Did you try it already @sollidy?

@metcoder95 Yes, of course, I've tried it. After webpack, also when i pass name to piscina.run(), it doesn't handle it. The same error.

Hmm, ok that's bad 🙁
Then, I'm pretty sure the issue is on the trick webpack does when patching the exports. Haven't checked that but maybe we can come with something to also support weback

I find solution!
I add this options to webpack.config.js, and now i have module.export when i export functions

output: {
  library: {
    type: 'commonjs2',
  },
}
export function convertStruct() {
  return Promise.resolve(['test']);
}
/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it uses a non-standard name for the exports (exports).
(() => {
var exports = __webpack_exports__;

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.convertStruct = void 0;
function convertStruct() {
    return Promise.resolve(['test']);
}
exports.convertStruct = convertStruct;

})();

module.exports = __webpack_exports__;
/******/ })()
;

Thanks! That was amazing, I'll close the issue for now and hopefully people with the same problem can reference this issue 👍