nbb

Pradeep B 2023-05-29T10:15:53.039439Z

Anyone used or tried nbb with a nest.js project? I have tried doing it same way as express.js/cljs integration however didn’t work. Tried following things: • created a simple nest.js service ( nest new project-name ) • ran with npm run start and it worked fine • created hello.cljs file and tried using this in app.service.ts file, it failed to load • tried converting to type: module and ran it failed with another error. Anyone ever tried this combination nest.js + nbb clojure module? Idea to plug some new clojure code into some running nest.js repo/service.

Pradeep B 2023-05-29T10:17:42.961349Z

context of generated dist/app.service.js file

borkdude 2023-05-29T10:18:30.117249Z

what output did you see?

borkdude 2023-05-29T10:19:06.498949Z

"it didn't work" is not very informative without elaborate error output or a repro that I could run locally

borkdude 2023-05-29T10:19:26.103559Z

oh I see, the error is on the right, I'm sorry

borkdude 2023-05-29T10:20:13.679439Z

yes, nbb is an ES6 project, your project should also be compiled as an ES6 project, but it's compiled as CJS project

Pradeep B 2023-05-29T10:22:29.217849Z

right, i am trying to build with “cjs” type for nest.js however no success. will try few more things and add more details.

borkdude 2023-05-29T10:23:28.419329Z

you can import nbb with a dynamic import though

borkdude 2023-05-29T10:23:32.615279Z

from cjs

borkdude 2023-05-29T10:31:33.026579Z

async function loadNbbFile(file) {
  const nbb = await import('nbb');
  await nbb.loadFile(file);
}

(async () => await loadNbbFile('hello.cljs'))();

Pradeep B 2023-05-29T10:49:01.352039Z

that will be one way, i am trying now. https://dev.to/wolfejw86/the-commonjs-vs-es-modules-war-is-taxing-for-us-regular-folks-out-here-one-way-to-interop-55e tried this one and for some weird reason getting argument mismatch error even when it correct ( trying this further).

borkdude 2023-05-29T10:51:07.129689Z

I don't think the const DynamicImport has any benefits over using dynamic import directly?

borkdude 2023-05-29T10:51:55.573319Z

I mean, you can just write:

async myImport(module) {
  return import(module);
}

1
borkdude 2023-05-29T10:52:12.221709Z

or even just import which is already a function

👀 1
borkdude 2023-05-29T10:52:43.865639Z

(await import('nbb')).default

borkdude 2023-05-29T10:54:24.448289Z

(async () => console.log( (await import('nbb')) ))()

Pradeep B 2023-05-29T10:54:29.567149Z

yes simple await will work, i was overlooking and missed the change in app.service.ts (that’s where argument count mismatch).

borkdude 2023-05-29T10:54:44.193889Z

there is no default export in nbb, you need to use .loadString or whatever directly.

borkdude 2023-05-29T10:55:02.651439Z

or just pass the whole nbb itself

borkdude 2023-05-29T10:55:26.570069Z

either way, don't do .default , there is none on the nbb module

Pradeep B 2023-05-29T10:55:46.388559Z

ok sure.

Pradeep B 2023-05-29T13:51:18.548909Z

that also didn’t work... however it moved 1 step ahead and now control reached nestjs framework level and that threw same exception. Will try out few more things, if this works it will be great fun and easy migration to clojure stack :)

borkdude 2023-05-29T13:53:07.375739Z

You still have import from 'nbb' on the right, this is causing the error

borkdude 2023-05-29T13:53:41.227299Z

the top level import

borkdude 2023-05-29T13:58:12.995539Z

^ @pradeep.bishnoi

Pradeep B 2023-05-29T14:01:35.961239Z

tried removing it earlier (later only got that to pull the type) - retrying without that fully (it will require some change in app.service.ts constructor (i.e., line number 7)

borkdude 2023-05-29T14:02:59.078139Z

loadFile is a function of string -> Promise<Any> if that helps

Pradeep B 2023-05-29T14:06:00.243829Z

not sure, trying few combinations. Wouldn’t it be helpful if we add a default export to nbb package it self?

borkdude 2023-05-29T14:07:34.328529Z

default exports aren't mandatory and I would say even an anti-pattern. there is no single thing that is "default" about the nbb API

🆗 1
Pradeep B 2023-05-29T14:08:43.795849Z

never liked js eco-system (long live Java eco-system) and now this is adding more reasons to it.

borkdude 2023-05-29T14:09:25.298229Z

perhaps typescript is trying to be clever and rewrites (await import('nbb').loadFile) to a top level import which then gets compiled as require. To work around this can you write:

async function myLoadFile(file) {
  const nbb = await import('nbb');
  return nbb.loadFile(file);
}
and then pass myLoadFile?

borkdude 2023-05-29T14:09:43.902219Z

If that doesn't work, perhaps then I get why they used Function in the earlier example

Pradeep B 2023-05-29T14:10:42.623679Z

let me try. and thanks for all the proactive help so far.

👍 1
borkdude 2023-05-29T14:11:06.759939Z

The const dynamicImport one I mean, perhaps TS is too clever and tries to optimize it when you don't write it using that

Pradeep B 2023-05-29T14:13:31.817099Z

this time server started, one more step forward. however failing to load cljs while accessing the endpoint (locahost:3000).

borkdude 2023-05-29T14:14:19.768159Z

ah yes, that's it:

For what it's worth, if we were in regular Javascript land this would work by itself, but wouldn't you know it, TypeScript has it's own problems with this one - it's actually rewriting that dynamic import as a require statement 😢. It's even sadder to realize that there's no way around this without hiding your dynamic import from the TypeScript compiler with a hackier method.

borkdude 2023-05-29T14:15:09.712709Z

yes, please use the const dynamicImport you head earlier, TS is rewriting dynamic import

borkdude 2023-05-29T14:15:27.569629Z

or just use a freaking .js file - screw ts ;)

😮‍💨 1
Pradeep B 2023-05-29T14:23:21.093369Z

this is 1 more step forward. now no error in module loading however data from cljs file is not returned in the api response. can’t use .js as want to migrate some existing service with nestjs(typescript) to clj.

borkdude 2023-05-29T14:25:33.667859Z

What is in your .cljs file?

Pradeep B 2023-05-29T14:29:32.484359Z

(ns hello)

;; variation 1 tried
;; (defn someData []
;;   "Hi, please show up in api response")

;; variation 2 tried
(defn someData []
 {:a "Hi, please show up in api response"})

#js {:someData someData}
got this from the nbb docs.

borkdude 2023-05-29T14:30:27.067769Z

> however data from cljs file is not returned in the api response where are you calling the someData function then?

Pradeep B 2023-05-29T14:31:55.934089Z

in the app.controller.ts the getHello function is getting called which is injected in the app.service.ts

Pradeep B 2023-05-29T14:32:23.513319Z

i guess it might be because of promise type, will try without that.

Pradeep B 2023-05-29T14:33:58.451269Z

changing (removed the promise, and made it only string) the return type of the getHello also didn’t help.

borkdude 2023-05-29T14:35:35.127799Z

isn't what you're seeing here a JS object being printed?

borkdude 2023-05-29T14:35:58.238349Z

you are returning a JS object from the loadFile call (async, so you might want to add an await in there)

borkdude 2023-05-29T14:36:08.163709Z

just console.log it and it will hopefully become clear to you

🆗 1
borkdude 2023-05-29T14:40:49.762049Z

What I mean is:

getHello(): Promise<string> {
  const loadFileResult = await this.loadFile("...");
  const { someData } = loadFileResult;
  const result = someData();
  console.log(result);
  return result;
}

borkdude 2023-05-29T14:41:53.664839Z

The result of someData is not a string, but a CLJS map in your code, but hopefully you get the idea

Pradeep B 2023-05-29T14:50:18.395609Z

yes, this piece of code worked for me. Thanks so much, you are awesome @borkdude gratitude-danke. Just relooking at organising it now for better usage.

borkdude 2023-05-29T14:50:52.460509Z

cool :)

🙌 1