March 2nd, 2020
A few days ago, I saw from multiple sources (including ycombinator and Reddit) that a team from Facebook was working on a experimental Javascript toolchain called Rome.
It seems to include a compiler, a linter, a formatter a bundler and a testing framework despite not being based on any of the "usual" tools that are standard in the industry (Babel, Webpack, etc.).
The project was started by Sebastian McKenzie, the author of Babel and Yarn.
This article is from the perspective of a developer discovering a new tool. I'm not from the dev team! I wrote this Rome tutorial while learning the tool!
At the moment, Rome isn't a package yet:
The only way to use it is to build from source.
So let's get started with it:
git clone https://github.com/facebookexperimental/rome.git
cd rome
Let's see what options are available on the CLI tool for the moment (assuming you have NodeJS already installed):
node scripts/vendor/rome.cjs --help
There are a bunch of Options that I won't talk about here. The other categories are Code Quality Commands (ci
, lint
and test
), Internal Commands (I don't know what they are yet), Process Management Commands to control the daemon, Project Management Commands (some of them like publish
and run
are not implemented yet) and Source Code Commands (like bundle
, compile
, etc.)
I'll just create an alias as rome
for this command to play with it anywhere else. I don't know if this is the right method as there is no installation documentation yet.
alias rome='node <path_to_your_folder>/rome/scripts/vendor/rome.cjs'
Rome is written mostly in Typescript which is surprising, considering that Facebook is putting a lot of effort into ReasonML.
Looking at packages.json
:
{
"name": "rome-root",
"license": "MIT",
"version": "0.0.2",
"//": "Look! No deps!",
"dependencies": {},
"///": "Only used for static type checking",
//...
}
The project clearly wants to be dependency-free.
Let's initialize a project:
mkdir hello-world
cd hello-world
rome init
It asks me if I want the recommended settings, let's agree.
Note: You can also use the shortcut rome init --defaults
It created a file called rome.json
that will probably act like config files from other tools like .prettierrc
, .babelrc
, etc.
{
"version": "^0.0.52",
"lint": {
"enabled": true
}
}
Let's add a simple index.js
file containing some javascript using modern features:
const who = () => "Rome"
console.log(`Hello ${who()}!`)
Note: it also works with typescript out of the box!
And enter the command:
rome parse index.js
Output:
Program {
comments: Array []
diagnostics: Array []
directives: Array []
filename: 'project-hello-world/index.js'
hasHoistedVars: false
mtime: 1_583_158_150_325.729
sourceType: 'script'
syntax: Array [
'jsx'
'flow'
]
body: Array [
VariableDeclarationStatement {
declaration: VariableDeclaration {
kind: 'const'
declarations: Array [
VariableDeclarator {
id: BindingIdentifier {name: 'who'}
init: ArrowFunctionExpression {
body: StringLiteral {value: 'Rome'}
head: FunctionHead {
async: false
hasHoistedVars: false
params: Array []
}
}
}
]
}
}
ExpressionStatement {
expression: CallExpression {
callee: MemberExpression {
object: ReferenceIdentifier {name: 'console'}
property: StaticMemberProperty {value: Identifier {name: 'log'}}
}
arguments: Array [
TemplateLiteral {
expressions: Array [
CallExpression {
arguments: Array []
callee: ReferenceIdentifier {name: 'who'}
}
]
quasis: Array [
TemplateElement {
cooked: 'Hello '
raw: 'Hello '
tail: false
}
TemplateElement {
cooked: '!'
raw: '!'
tail: true
}
]
}
]
}
}
]
}
Cool! Let's try to create a bundle the bundle
command:
rome bundle index.js bundle
It creates a bundle/
folder containing index.js
, index.js.map
and a bundlebuddy.json
that probably contains some kind of bundling info:
[
{
"source": "project-hello-world/index.js"
}
]
Now let's execute the freshly created bundle/index.js
:
node bundle/index.js
Returns:
Hello Rome!
Kind of what we expected, right?
I hope this article helped you do your first steps with Rome. Rome is still experimental and in development and it aims to replace a lot of existing tools! Maybe it wants to solve too many problems at the same time and it's not a good idea to break the single responsibility principle? We will see in the future how it succeeds in the Javascript ecosystem and how it finds its place.