Warn user that `taskDirectory` cannot import typescript files.
Feature description
When using the taskDirectory option with .ts files inside the taskDirectory, the application should log a warning alerting the user that typescript files will not be imported as tasks.
Motivating example
I'm using ts-node-dev for local development. I spent some time tracing the graphile-worker source code to figure out why my jobs weren't running. Clearly I should have read the docs more thoroughly, as I now see it's mentioned there.
However, while I was digging through the source, I saw the check if (file.endsWith(".js")) here and thought it would be nice to add an else if (file.endsWith(".ts") and log a warning. There could potentially be another warning in a else statement for files that don't match either.
Breaking changes
I don't think this would break anything.
Supporting development
I [tick all that apply]:
- [x] am interested in building this feature myself
- [ ] am interested in collaborating on building this feature
- [ ] am willing to help testing this feature before it's released
- [ ] am willing to write a test-driven test suite for this feature (before it exists)
- [ ] am a Graphile sponsor ❤️
- [x] have an active support or consultancy contract with Graphile (I think so, I work at Postlight)
One issue with this approach is that I work with developers that compile the .js file next to the .ts file, so a simple implementation of this would cause issues for them. I think we could solve this by collecting the valid file names and then only alerting about the incompatible file names that don't share the relevant prefix?
Long term I'm planning to allow executing tasks in other languages (Python, Ruby, Perl, Go, Rust, etc) by calling the relevant file with either the relevant arguments or the relevant STDIN or maybe a task spec file written somewhere temporary, but I've not got as far as speccing this out yet. So we should definitely leave space for expansion. In general I think we should discourage anything except for the task files themselves (and maybe some .md files?) being in that folder.
For now a PR adding the warning but with some warning rejection if there's both a foo.ts and foo.js file would be welcome :+1:
Hello,
How are you doing?
Any news on this feature?
I don't know if this is the best place to put this, but I used this code to "emulate" the behavior of graphile-worker picking up the taskList from the taskDirectory, even if the tasks are written in Typescript.
const taskDirectory = resolve(__dirname, './tasks');
const taskFiles = readdirSync(taskDirectory);
const taskList = Object.fromEntries(
taskFiles.map((taskFile) => [
parse(taskFile).name,
/* eslint @typescript-eslint/no-require-imports: "off" */
require(join(taskDirectory, taskFile)) as Task,
]),
);
async function main() {
const runner = await run({
taskList,
});
await runner.promise;
}
main().catch((err) => {
logger.error(err);
process.exit(1);
});
I could then write my tasks like this:
import type { Task } from 'graphile-worker';
import { z } from 'zod';
const HelloTaskPayload = z.object({
name: z.string(),
});
const task: Task = async (payload, helpers) => {
const { name } = HelloTaskPayload.parse(payload);
helpers.logger.info(`Hello, ${name}`);
};
export = task;
The last line of the second example is important, because it makes Typescript transpile the line into module.exports = task.
@guzmonne
Thanks this helped me a lot ! I had trouble to dynamically import all my .ts task files
I was running into this error when running tasks TypeError: task is not a function. But export = [task_name] solved this issue
Since it's possible to define tasks in TypeScript (thank you @guzmonne), adding warnings doesn't seem necessary anymore.