Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

23 February 2024

Switching from ts-node to tsx

 Running server side typescript with ts-node

JavaScript is a fast changing ecosystem. With so many new and old kids on the block there  are so many options that having them play nicely together is a challenge.

We're working with node.js 18 at the server side and have moved to using TypeScript (instead of JavaScript) and ES modules (instead of CommonJS modules).

We're using ts-node to feed node TypeScript, and added extra options to our tsconfig.json for this:

{
"extends": "@tsconfig/node-lts/tsconfig.json",
"compilerOptions": {
"module": "ESNext",
},
"ts-node": {
"esm": true,
"experimentalSpecifierResolution": "node"
}
}

We're using nodemon to restart node upon changes.  

This was giving us some problems when launching in debug mode, so we had to explictly pass the ES module loaders of node to nodemon. These are our commands in package.json

"scripts": {
"start": "nodemon index.ts",
"ts": "ts-node ",
"debug": "nodemon -x \"node --inspect --loader ts-node/esm \" "
}

For both npm run ts and npm run debug we're appending the ts file to be run.

We're testing with Jest and  again we needed some extra configuration to play nicely with Typescript and ES modules.

ts-node does not play nicely with Node.js 20

And then we moved to the Node.js 20 LTS release and things broke. It cannot even grok @tsconfig/node-lts/tsconfig.json (es2023 not supported).  You can get things going by also passing the esm loader when running the code normally, just as you do when you're debugging.

But really, not running with the LTS seemed a bit lame to me for a tool like ts-node. The 10.9 release dates from juli 2022, with only two bug fix releases since, and no sign of updates for new releases of underlying packages.

 Running server side typescript with tsx

So, we took a stab at tsx as an alternative for ts-node. If you look at the comparison between the two (by tsx, but still informational), you see that tsx has less downloads (6M/month vs 94M/month), has a larger footprint (10 MB vs 2MB), has less github stars (7k vs 12k).

Trying out tsx we could reduce tsconfig.json to sensible defaults

{
"extends": "@tsconfig/node-lts/tsconfig.json",
"compilerOptions": {
"outDir": "dist"
}
}

With this setup we are importing files with a .js extension, even if we are developing with .ts extensions. We need to avoid picking up previously generated .js files is compiling with tsc, so we are directing compiled files to a dist directory.

Annoying downside of tsx is that its name overlaps with the .tsx file extension (React typescript file), which gives you false positives when googling.

Monitoring changes

Also, we did not need nodemon anymore, as tsx comes with a watcher. Our scripts commands in package.json have simplified to

"scripts": {
"start": "tsx watch index.ts",
"ts": "tsx ",
"debug": "tsx --inspect-brk "
},

I have not tried out (Jest) testing yet, but as for now, tsx looks like the way to go!

2 May 2018

Node.js 10 released

Node.js 10 is releaed and will become the long term support version (replacing Node 8) in october 2018.
Highlights:

  • ES6 module support: 
    • given the ubiquity of node.js native modules (CommonJS) this was a hard nut to crack
    • Both systems provide and use module elements differently
      • Node.js modules work with module.exports and require 
      • EJS modules work with export and import
    • a difference between both module systems is that node modules load synchronously and ES6 modules load asynchronously. Tools bridging both worlds like webpack load ES6 modules syncronously into Node.js. These tools have allowed isomorphic javascript, running both in the browser and in Node. The node team has not gone this way and stuck to the standard: they load ES6 modules synchronously.
    • Node 10 allows usage of ES6 modules only in files with the new .mjs extension (module javascript). So .js files keep on using module.exports and require. 
    • How do you access a module from the other module universe?
      • You can import from a Node .js file into a ES6 .mjs file, but you can only use a default import. That is logical, as Node's module.exports only exports one thing. This one thing can be an object or a function, that can encapsulate more stuff.
      • You can import from a .mjs file into a Node .js file, but only by explicitly making the import asynchronous using await import(). Again this seems a logical choice.
      • This image from a Medium article  sums it up nicely
      • If you import a file without an extension Node will first look for a .mjs file. If it does not find it, it will look for a .js file. This leaves the door open to using your ES6 .js files, without renaming them.
    • This seems to be a workable system, but I'm not sure I like the degradation of ES6 modules to second class .mjs citizens.  Well, this is a work in progress, and I think for now the Node team is awating the reaction from the developer community
  • API changes
    • fs.promises: fs functions returning promises without having to use util.promisify()!
    • standard numeric codes for error messages
    • console.table
  • npm 6
    • better security and new npm audit command to check a package for vulnerabilities
    • warnings if you download a package with security issues
    • speed bump

20 February 2013

Firefox 19 javascript PDF viewer

Firefox doesn't use an adobe plugin anymore to show PDF. It handles them entirely in javascript, using the same pdf.js library as Chrome.
Bleeding fast and responsive.
Still young though, you might get incompatibility messages. So I'm just waiting a little before dumping the adobe plugin (with its pesky McAffee bundle) entirely.