Skip to content

Commit

Permalink
fix(worker): Fix import error when using pkg with node v20
Browse files Browse the repository at this point in the history
  • Loading branch information
nagyszabi committed Mar 27, 2024
1 parent 8f7930d commit 9f7f86b
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 3 deletions.
4 changes: 3 additions & 1 deletion lib/worker.js
Expand Up @@ -44,8 +44,10 @@ async function start () {
if ((error.code === 'ENOTDIR' || error.code === 'ERR_MODULE_NOT_FOUND') &&
filename.startsWith('file://')) {
worker = realRequire(decodeURIComponent(filename.replace('file://', '')))
} else if (error.code === undefined) {
} else if (error.code === undefined || error.code === 'ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING') {
// When bundled with pkg, an undefined error is thrown when called with realImport
// When bundled with pkg and using node v20, an ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING error is thrown when called with realImport
// More info at: https://github.com/pinojs/thread-stream/issues/143
worker = realRequire(decodeURIComponent(filename.replace(process.platform === 'win32' ? 'file:///' : 'file://', '')))
} else {
throw error
Expand Down
5 changes: 3 additions & 2 deletions package.json
Expand Up @@ -10,6 +10,7 @@
"devDependencies": {
"@types/node": "^20.1.0",
"@types/tap": "^15.0.0",
"@yao-pkg/pkg": "^5.11.5",
"desm": "^1.3.0",
"fastbench": "^1.0.1",
"husky": "^9.0.6",
Expand All @@ -22,9 +23,9 @@
"why-is-node-running": "^2.2.2"
},
"scripts": {
"test": "standard && npm run transpile && tap test/*.test.*js && tap --ts test/*.test.*ts",
"test": "standard && npm run transpile && tap \"test/**/*.test.*js\" && tap --ts test/*.test.*ts",
"test:ci": "standard && npm run transpile && npm run test:ci:js && npm run test:ci:ts",
"test:ci:js": "tap --no-check-coverage --coverage-report=lcovonly \"test/**/*.test.*js\"",
"test:ci:js": "tap --no-check-coverage --timeout=120 --coverage-report=lcovonly \"test/**/*.test.*js\"",
"test:ci:ts": "tap --ts --no-check-coverage --coverage-report=lcovonly \"test/**/*.test.*ts\"",
"test:yarn": "npm run transpile && tap \"test/**/*.test.js\" --no-check-coverage",
"transpile": "sh ./test/ts/transpile.sh",
Expand Down
37 changes: 37 additions & 0 deletions test/pkg/index.js
@@ -0,0 +1,37 @@
'use strict'

/**
* This file is packaged using pkg in order to test if worker.js works in that context
*/

const { test } = require('tap')
const { join } = require('path')
const { file } = require('../helper')
const ThreadStream = require('../..')

test('bundlers support with .js file', function (t) {
t.plan(1)

globalThis.__bundlerPathsOverrides = {
'thread-stream-worker': join(__dirname, '..', 'custom-worker.js')
}

const dest = file()

process.on('uncaughtException', (error) => {
console.log(error)
})

const stream = new ThreadStream({
filename: join(__dirname, '..', 'to-file.js'),
workerData: { dest },
sync: true
})

stream.worker.removeAllListeners('message')
stream.worker.once('message', (message) => {
t.equal(message.code, 'CUSTOM-WORKER-CALLED')
})

stream.end()
})
15 changes: 15 additions & 0 deletions test/pkg/pkg.config.json
@@ -0,0 +1,15 @@
{
"pkg": {
"assets": [
"../custom-worker.js",
"../to-file.js"
],
"targets": [
"node14",
"node16",
"node18",
"node20"
],
"outputPath": "test/pkg"
}
}
44 changes: 44 additions & 0 deletions test/pkg/pkg.test.js
@@ -0,0 +1,44 @@
'use strict'

const { test } = require('tap')
const config = require('./pkg.config.json')
const { promisify } = require('util')
const { unlink } = require('fs/promises')
const { join } = require('path')
const { platform } = require('process')
const exec = promisify(require('child_process').exec)

test('worker test when packaged into executable using pkg', async (t) => {
const packageName = 'index'

// package the app into several node versions, check config for more info
const filePath = `${join(__dirname, packageName)}.js`
const configPath = join(__dirname, 'pkg.config.json')
const { stderr } = await exec(`npx pkg ${filePath} --config ${configPath}`)

// there should be no error when packaging
t.equal(stderr, '')

// pkg outputs files in the following format by default: {filename}-{node version}
for (const target of config.pkg.targets) {
// execute the packaged test
let executablePath = `${join(config.pkg.outputPath, packageName)}-${target}`

// when on windows, we need the .exe extension
if (platform === 'win32') {
executablePath = `${executablePath}.exe`
} else {
executablePath = `./${executablePath}`
}

const { stderr } = await exec(executablePath)

// check if there were no errors
t.equal(stderr, '')

// clean up afterwards
await unlink(executablePath)
}

t.end()
})

0 comments on commit 9f7f86b

Please sign in to comment.