Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recommendation to transpile and bundle typescript for running in quickjs #191

Closed
RichardGaleSonos opened this issue Aug 24, 2023 · 16 comments

Comments

@RichardGaleSonos
Copy link

I have a typescript node app with dependencies. I can build with webpack and run via node or execute directly with ts-node, now I would like to run via quickjs. Are there any examples of transpiling to the appropriate versioned javascript, including dependencies, and creating a bundle?

I'm happy to use esbuild, rollup, weback, etc.

@paulocoghi
Copy link

paulocoghi commented Aug 24, 2023

You can easily bundle all your code to a single JS file using Rollup or any other standard bundler. Even bun.sh is a valid (and really fast) option for this task.

But the real issue here is compatibility, since QuickJS is not equivalent nor compatible to NodeJS, due to the large differences on their standard libraries [1].

If all the javascript code, including the dependencies, do not use any specific feature from Node stdlib (very unlikely), then its fully compatible with QuickJS.

[1] To the surprise of many, yes, QuickJS does provide a standard library (link)

@RichardGaleSonos
Copy link
Author

But the real issue here is compatibility, since QuickJS is not equivalent nor compatible to NodeJS, due to the large differences on their standard libraries [1].

Agree on the libraries. Firstly I need QuickJS to accept and parse my JS. Which means transpiling from typescript to some ECMA version including the dependencies in node_modules.

@paulocoghi
Copy link

paulocoghi commented Aug 24, 2023

Agree on the libraries. Firstly I need QuickJS to accept and parse my JS. Which means transpiling from typescript to some ECMA version including the dependencies in node_modules.

Any JS bundler is enough. I particularly like Rollup. But bun.sh bundler is also becoming interesting


Depending on how much control you have over your javascript code (including dependencies), and on how much you really want to run it on QuickJS, you can translate the code related to standard librarie usage, and use QuickJS's one, eventually using additional helping libraries (like an HTTP server library for quickjs, just as an example), but you really need to know your goal and evaluate if QuickJS is a good choice for your scenario.

@paulocoghi
Copy link

paulocoghi commented Aug 24, 2023

Here is an example (not tested) of a rollup.config.js to transpile and "three-shake" (remove the unused parts of) your typescript code to a single optimized final bundle in ECMA

import esbuild from 'rollup-plugin-esbuild'

export default [
{
	input: `src/your-main-file.js`,
	plugins: [esbuild()],
	output: [
	{
		file: `dist/bundle.js`,
		format: 'cjs',
		exports: 'default'
	}]
}]

@RichardGaleSonos
Copy link
Author

100% control of my javascript. 100% my choice of dependencies. 100% committed to running embedded QuickJS.

@paulocoghi
Copy link

When possible, give a feedback about the example approach above (with Rollup)

@guest271314
Copy link

What issues are you having running the JavaScript that TypeScropt compiles to JavaScript in QuickJS environment?

@RichardGaleSonos
Copy link
Author

I had some require("") statements in packages under node_modules that hadn't been converted.

@paulocoghi
Copy link

@RichardGaleSonos Were you able to create a single bundled javascript with the example I gave you above?

@RichardGaleSonos
Copy link
Author

esbuild() does not appear to be handling my TS files. Using your rollup.config.js I get "RollupError: The keyword 'enum' is reserved"

@paulocoghi
Copy link

@RichardGaleSonos, when possible, please install Bun (bun.sh) and use its bundler (bun build), as the following example:

  • By creating a bundler.js and running bun bundler.js
// bundler.js
await Bun.build({
  entrypoints: ['./src/index.ts'],
  outdir: './dist',
});
  • Or, directly through cli:
bun build ./src/index.ts --outdir ./dist

@guest271314
Copy link

Another option is the deprecated deno bundle test.ts test.js or deno_emit

import { bundle } from "https://deno.land/x/emit/mod.ts";
const result = await bundle(
  'test.ts',
);

const { code } = result;
console.log(code);

@RichardGaleSonos
Copy link
Author

Thank you.

bun worked for me, generating a single .js file that quickjs could parse, I'm running it as a dependency of txiki.js

Now I need to resolve, "ReferenceError: could not load 'node:fs'" this was expected.

@paulocoghi
Copy link

paulocoghi commented Sep 5, 2023

I'm glad to hear it worked out.

IMHO, unless there is some particular feature provided by txiki.js, I would recommend pure QuickJS over it, considering txiki.js also uses libuv (used by NodeJS) which, in the end, negates many (if not most of) possible benefits of going to an alternative and smaller runtime.

@RichardGaleSonos
Copy link
Author

RichardGaleSonos commented Sep 5, 2023

I need node:fs, node:dgram, etc. My goal is to run a node app in a smaller footprint than running node itself.

@paulocoghi
Copy link

paulocoghi commented Sep 5, 2023

For node:fs, quickjs stdlib would be enough (through FILE prototype).

But node:dgram (UDP datagram sockets) is another thing. If txiki.js provides it, go for it :)

Edit:

I confirm that txiki.js supports datagram sockets (at least partially), available on its tjs namespace

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants