How to provide and consume require.js modules in scala.js (and extending classes) - node.js

I'm doing this Ensime package for Atom.io https://github.com/ensime/ensime-atom and I've been thinking about the possibility to use scala.js instead of writing Coffeescript.
Atom is a web based editor which is scripted with js and is node.js based. A plugin/package defines it's main entry point by pointing out a javascript object with a few specific.
I figured I should start out simple and try using scala.js replacing the simplest coffeescript file I have:
{View} = require 'atom-space-pen-views'
# View for the little status messages down there where messages from Ensime server can be shown
module.exports =
class StatusbarView extends View
#content: ->
#div class: 'ensime-status inline-block'
initialize: ->
serialize: ->
init: ->
#attach()
attach: =>
statusbar = document.querySelector('status-bar')
statusbar?.addLeftTile {item: this}
setText: (text) =>
#text("Ensime: #{text}").show()
destroy: ->
#detach()
As you can see this exports a require.js module and is a class extending a class fetched with require as well.
Sooo.
I'm thinking I'd just use Dynamic for the require dep as I've seen on SO How to invoke nodejs modules from scala.js?:
import js.Dynamic.{global => g}
import js.DynamicImplicits._
private[views] object SpacePen {
private val spacePenViews = require("atom-space-pen-views")
val view = spacePenViews.view
}
But if I wanted to type the super-class, could I just make a facade-trait and do asInstanceOf?
Secondly, I wonder how I can export my class as a node module. I found this:
https://github.com/rockymadden/scala-node/blob/master/main/src/main/coffeescript/example.coffee
Is this the right way? Do I need to do the sandboxing? Couldn't I just get moduleimported from global and write module.exports = _some_scala_object_?
I'm also wondering how I could extend existing js classes. The same problem as asked here, but I don't really understand the answer:
https://groups.google.com/forum/#!topic/scala-js/l0gSOSiqubs
My code so far:
private[views] object SpacePen {
private val spacePenViews = js.Dynamic.global.require("atom-space-pen-views")
type View = spacePenViews.view
}
class StatusBarView extends SpacePen.View {
override def content =
super.div()
}
gives me compile errors that I can't extend sealed trait Dynamic. Of course.
Any pointers highly appreciated!

I'm not particularly expert in Node per se, but to answer your first question, yes -- if you have a pointer to a JS object, and you know the details of its type, you can pretty much always define a facade trait and asInstanceOf to use it. That ought to work.
As for the last bit, you basically can't extend JS classes in Scala.js -- it just doesn't work. The way most of us get around that is by defining implicit classes, or using implicit def's, to get the appearance of extending without actually doing so.
For example, given JS class Foo, I can write
implicit class RichFoo(foo:Foo) {
def method1() = { ... }
}
This is actually a wrapper around Foo, but calling code can simply call foo.method1() without worrying about that detail.
You can see this approach in action very heavily in jquery-facade, particularly in the relationship between JQuery (the pure facade), JQueryTyped (some tweaked methods over JQuery to make them work better in Scala), and JQueryExtensions (some higher-level functions built around JQuery). These are held together using implicit def's in package.scala. As far as calling code is concerned, all of these simply look like methods on JQuery.

Related

Switching multiple inheritance via mixins to composition but keep the same API

Firstly, thank you for taking the time to read and input. It is greatly appreciated.
Question: What kind of approach can we take to keep the same public API of a class currently using multiple mixins but refactor it internally to be composed of objects that do the same work as the mixin. Autocomplete is a must (so runtime dynamics are kind of out such as hacking things on via __getattr__ or similar - I know this depends on the runtime environment i.e ipython vs pycharm etc, for the sake of this question, assume pycharm which cannot leverage __dir__ I think fully.
Accompanying Information:
I am writing a little assertion library in python and I have a core class which is instantiated with a value and subsequently inherits various assertion capabilities against that value via a growing number of mixin classes:
class Asserto(StringMixin, RegexMixin):
def __init__(self, value: typing.Any, type_of: str = AssertTypes.HARD, description: typing.Optional[str] = None):
self.value = value
self.type_of = type_of
self.description = description
These mixin classes offer various assertion methods for particular types, here is a quick example of one:
from __future__ import annotations
class StringMixin:
def ends_with(self, suffix: str) -> StringMixin:
if not self.value.endswith(suffix):
self.error(f"{self.value} did not end with {suffix}")
def starts_with(self, prefix: str) -> StringMixin:
if not self.value.startswith(prefix):
self.error(f"{self.value} did not end with {prefix}")
I would like to refactor the Asserto class to compose itself of various implementations of some sort of Assertable interface rather than clobber together a god class here with Mixins, I'm likely to have 10+ Mixins by the time I am finished.
Is there a way to achieve the same public facing API as this mixins setup so that client code has access to everything through the Asserto(value).check_something(...) but using composition internally?
I could define every single method in the Asserto class that just delegate to the appropriate concrete obj internally but then I am just making a massive god class anyway and the composition feels like a pointless endeavour in that instance?
for example in client code, I'd like all the current mixins methods to be available on an Asserto instance with autocomplete.
def test_something():
Asserto("foo").ends_with("oo")
Thank you for your time. Perhaps using the mixin approach is the correct way here, but it feels kind of clunky.

Create Map of classes in TypeScript

I've got a rendering engine, much like React where I need to store classes rather than instances in an object for compiling.
So for example, I have a Button component that I would like to be able to dynamically instantiate. Doing this would be as easy as
new components["Button"]
For this, I need a list of all possible classes. So I've got a Dictionary interface declared like so:
interface Dictionary<T> {
[Key: string]: T;
}
This works well, I'm easily able to add objects to this dictionary. Except if I have an object:
const components: Dictionary<Component> = {
Button: Button
}
Then I get an error because Button is a class, rather than an instance. Here, the issue is, I don't want to define the dictionary as Dictionary<Function> because that would mean I allow any function into the dictionary. Specifically, I only want to allow classes into the dictionary that extend the Component class.
How would I achieve this?
You also need to define the signature of the constructor (which makes sense if you think about it), but you do the following:
interface ComponentClass {
new (a: number): Component;
}
(The signature of the constructor is probably not "number", but put in whatever it is.)

What is the best way to organize the code of a nodejs-express project, using TypeScript?

While trying to organize the code of my first NodeJS-express project, I ran into some doubts about the use of namespaces, modules and classes. When to choose one? When another?
For example, my project is structured (simplifying) in.
routers -> controllers -> services -> repositories.
The possibilities I thought of to manage these "entities" are the following:
Classes
Classes with static methods
Singletons
Simple module export
Namespaces
Classes
I thought of avoiding them right away, since the above-mentioned entities do not need to memorize any state. Furthermore, they would complicate the code due to the need to be instantiated.
Classes with static methods
They are correct? Or rather a simple namespace or simple export of the modules?
Class + Singletons
A way of organizing the code in a "nicer" way than the simple class, but which does not convince me, since reading on the net that the singleton in TypeScript is replaceable with the namespace.
Simple module export
The way I thought to implement immediately, for example in this way (file user.repository.ts):
const add = async (user: User): Promise<void> => {
if(await canBeAdded(user)) {
//save user;
} else {
// throw error
}
}
export const UserRepository = {
add
}
It's corrects? Or am I not properly using what TypeScript offers? Being the first time I use this language, I would like to be sure I chose the right path.
Namespaces
Are they a better choice to develop the code published above? Are you advised against?
Thank you in advance for the answers! Any advice is welcome!
P.S. I know that, once the TypeScript is compiled, in Javascript the classes are practically syntactic sugar. What I'm interested in knowing are the best practices for writing good code in TypeScript.

Classes vs modules in Node.js

My question is, if it is better the use classes in Node.js or the function, or prototypes and modules, I know that most use the modules and function prototypes, but which is better?
And we most consider that classes have always been in all programming languages the best option to work.
classes vs. modules is the wrong question
The question you are looking for is classes vs. prototypes.
Both classes and prototypes are used by modules.
Modules (ES2015 Modules) are what JavaScript uses to be able to export and import code. Before JavaScript officially implemented modules there were hacks to do this and create code encapsulation which fixed issues such as pollution of the global scope; Immediately Invoked Function Expressions is an example. Node.js with CommonJS and Angular with AMD and several others tried to figure out how to do this in a better way and implemented their own 'module' system. I would like to think ES2015 Modules were influenced by other languages and CommonJS/Amd etc. and as a result, we now have a module system in JavaScript.
As for classes, they themselves create code encapsulation, but they cannot export themselves, that's what modules do. The same applies for the prototype based code, it creates code encapsulation but cannot export it self just like classes.
Now to put this together.
Example of a module, this example has nothing to do with classes or prototypes, only-a-module.js:
const privateHello = 'hello' // <- module code (private)
export const publicHello = 'hello'; // <- module code (public)
Example of a module that uses a class, module-that-exports-a-class.js:
export class Classes { // <- module AND class code (public)
private privateHello = 'hello'; // <- class code (private)
public publicHello = 'hello'; // <- class code (public)
} // <- class code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
Example of a module that uses prototypes, module-that-exports-a-prototype.js:
export function Prototypes() { // <- module AND prototype code (public)
const privateHello = 'hello'; // <- prototype code (private)
this.publicHello = 'hello'; // <- prototype code (public)
} // <- prototype code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
What makes this confusing to beginners coming from OOP languages is that for example in Java a class file (file.class) is automatically exported as a class, this is by default as this is how Java works. This is not the case in JavaScript. You must state what you are exporting.
Classes are an attempt to implement so called classical inheritance while prototype is, you guessed it, prototypal inheritance. These are two ways to deal with code-reuse and objects that keep their own state.
If we want to make things even more complicated, a good followup question is OOP vs. functional programming. But you can read that up in other places.
My question is if it is better the use classes in nodejs or the function or prototypes and modules, i know that most use the modules and function prototypes, but which is better?
Your question seems a bit misguided. In node.js, one does not choose between classes, prototypes and modules.
First off classes in Javascript uses the prototype. The class syntax is just syntactical sugar for defining a constructor and methods on the prototype. When you use the class syntax, you are creating a constructor with a prototype and causing methods to be added to the prototype (under the covers). So, there is no tradeoff between using classes and using the prototype.
The only tradeoff there is there is between using the new class syntax to define your prototype vs. doing it the older, manual way.
Then, classes are pretty much orthogonal to modules. You use modules when you want to encapsulate a body of code in a module interface so you can reap all the benefits of using modules (easier sharing, reuse, documenting, testing, etc...). That module interface can be whatever you think is most appropriate for your circumstance. You can export a series of plain functions. You can export one or more object constructors. You can export factory functions that create objects for you that you can then use methods on. The module scheme is massively flexible so you can export pretty much any type of interface you want (and classes can be a part of that if you choose).
There is no "best" way to export things from modules because it depends upon your needs, your chosen architectural and coding style, etc...

NodeJS: Keeping library files DRY

I've recently started working on a non-trivial project in CoffeeScript and I'm struggling with how best to deal with registering exports etc. I'm writing it in a very 'pythonesque' manner, with individual files effectively being 'modules' of related classes and functions. What I'm looking for is the best way to define classes and functions locally AND in exports/window with as little repetition as possible.
At the moment, I'm using the following in every file, to save writing exports.X = X for everything in the file:
class module
# All classes/functions to be included in exports should be defined with `#`
# E.g.
class #DatClass
exports[name] = item for own name, item of module
I've also looked at the possibility of using a function (say, publish) that puts the passed class in exports/window depending on its name:
publish = (f) ->
throw new Error 'publish only works with named functions' unless f.name?
((exports ? window).namespace ?= {})[f.name] = f
publish class A
# A is now available in the local scope and in `exports.namespace`
# or `window.namespace`
This, however, does not work with functions as, as far as I know, they cannot be 'named' in CoffeeScript (e.g. f.name is always '') and so publish cannot determine the correct name.
Is there any method that works like publish but works with functions? Or any alternative ways of handling this?
It's an ugly hack but you can use the following :
class module.exports
class #foo
#bar = 3
And then :
require(...).foo.bar // 3
The old
(function (exports) {
// my code
exports.someLib = ...
})(typeof exports === "undefined" ? window : exports);
Is a neat trick that should do what you want.
If writing that wrapper boilerplate is a pain then automate it with a build script.
What I'm looking for is the best way to define classes and functions locally AND in exports/window with as little repetition as possible.
It's impossible to do something like
exports.x = var x = ...;
without writing x twice in JavaScript (without resorting to black magicks, i.e. eval), and the same goes for CoffeeScript. Bummer, I know, but that's how it is.
My advice would be to not get too hung up on it; that kind of repetition is common. But do ask yourself: "Do I really need to export this function or variable and make it locally available?" Cleanly decoupled code doesn't usually work that way.
There's an exception to the "no named functions" rule: classes. This works: http://jsfiddle.net/PxBgn/
exported = (clas) ->
console.log clas.name
window[clas.name] = clas
...
exported class Snake extends Animal
move: ->
alert "Slithering..."
super 5

Resources