865 words by Sean Levy written on 2024-02-27, last edit: 2024-02-27, tags: makemaker, npm, oo, perl, prototypes, toolchain, typescript | Next post: Do One Thing Well
Okay, yeah, even old beardos come to typescript eventually. It's kind of a bit like coming home for me, but I'm still living most of my time on the strange little island of Perl. I mean the rent is paid through the end of the century, so...
I was one of the original prototype-based OO people, being inspired by Smalltalk and especially Self. At CMU I and my colleague built an environment called the Basic Object System, a prototype-based environment written in C that could integrate seamlessly with C++ and other languages. It had a programming language called stitch, inspired by Self, in which our research group wrote systems in the area of corporate memory.
Early object-relational foundations and prototype-based OO was pretty much what I was about in the 90s. One of the key ideas in Self was applying type inference in a typeless language, by observing what types arguments to methods had at runtime and generating better and better machine code based on frequency of use and actual data types in play. The idea here was to compete head-on with hand-written C code in a high-level OO language. These ideas bore commercial fruit in the form of Java's JIT, which was built mostly by Self alumni from Stanford hired by Sun for precisely this reason.
So now flash forward 30 years and these same ideas are in play, but for another reason: giving the illusion of type-safety to a dynamic, untyped (for the most part) prototype-based language. Instead of performance, typescript is worried about correctness and above all else finding bugs.
It's taken me the better part of a day, but I think I've figured out how to use npm/typescript in a Mojo-based project, with Perl (ExtUtils::MakeMaker) in the driver's seat.
I keep my assets (which now include .ts
files) in my source tree
and manage them with e.g.
Mojo::Home. The
secret to integrating typescript
into my Perly world came down to the following few lines in
my tsconfig.json
{
"compilerOptions": {
"baseUrl": "./lib/myorg/myproj/public",
"outDir": "./blib",
"rootDir": "./",
"strict": true,
"moduleResolution": "node",
"experimentalDecorators": true,
// ... other stuff for sure
},
"include": ["lib/myorg/myproj/public/**/*.ts"],
"exclude": []
}
First, I follow the standard open-source naming convention of having
an overriding organization/project name and then a subcomponent
name underneath it (the myorg/myproj
), obviously the above is not
literally what I use.
Second, I'm still on a learning curve with npm; I used npm i typescript
in my source directory to get a typescript environment bootstrapped, and
perused the lit ts starter kit
for inspiration, but my project is not a node project, so like most
resources out there it has a lot of good stuff in it but also falls short.
It turns out with just a couple tweaks, the tsconfig that came with the lit starter kit was good.
The baseUrl
setting: until I did this all the imports in my modules were throwing
spectacular errors, because they were all supposed to be relative to
the docroot, and my public
directory is precisely that.
Next, outDir:
this caused the output of npx tsc
to start landing in the right
path under blib
, which is created and managed by
MakeMaker. This sort of gives them dual
custody.
This one was already set in the starter kit, but I think you get wildly
wrong results if you don't set it to ./
.
Everyone tells you to set this. Everyone. But was it set? Was it?
I don't really want a node-based dev server in the mix, I just use a simple out-of-band BSD makefile to manage a separate dev docroot where I can play around with stuff via the tender mercies of nginx and friends. Mojolicious also has plenty of dev-server magic available if I want that, but when I'm just debugging/developing the pretty face of one of my ugly little apps I don't really want much more than nginx and Firefox's dev tools.
I'm sure I'll eventually slide over to the dark side and start building stuff using node/npm more directly. There is now a JS version of the Mojo framework, which is strictly a server-side thing; it carries forward (I guess this is forward?) the ideas in Mojolicious to a brave new JS-oriented world.
I'm enjoying typescript, but I have to say there's nothing new here. It just feels like another turn of the wheel... we're sick of types and marvel at our wonderful, fluid, plastic typeless language, but then we end up needing types and add them back... lather, rinse, repeat, rhyme with the past while marching into the future.
I do recommend that Perl devs with significant JS code strongly consider switching to typescript. You have nothing to lose but the past.
Copyright © 2024 by Sean Levy<snl@cluefactory.com>. All Rights Reserved.