其他分享
首页 > 其他分享> > Rome:Facebook最新JS工具上手

Rome:Facebook最新JS工具上手

作者:互联网

北京时间2020年2月27日,Facebook宣布其实验性JavaScript工具链Rome开源。Rome是Babel和Yarn作者、React Native团队成员Sebastian McKenzie的新作品。开源之前,Rome基本上Sebastian McKenzie的个人项目,只不过Facebook愿意付薪水让他潜心开发。

Rome项目地址:https://github.com/facebookexperimental/rome。

图片

Rome(罗马)这个名字是这个项目的第三个名字。2016年,Sebastian McKenzie给这个项目起的第一个名字是Sonic(声速/音速),“因为追求速度”,后来又改为Hydra(九头蛇),因为“有多个头”。2019年3月改为Rome,因为“罗马有很多非常恰当的隐喻,如「罗马不是一天建成的」「条条大路通罗马」”(https://twitter.com/sebmck/status/1108408813864906752)。

这是Sebastian McKenzie为Rome选的Logo:

图片

有人说:“这不是斯巴达头盔吗?”

Sebastian McKenzie回答说:“没错,就是斯巴达头盔,希腊的。不是罗马的。无所谓,我不在乎。”

Rome是什么?

根据项目介绍:

Rome完全使用TypeScript编写,所有代码在一个仓库中,以内部包形式区分功能组件。Rome也是自托管的(self-hosted),可以自己编译自己。Rome支持JSX,也支持Flow和TypeScript注解代码。当前,Rome的工作重心是Linting:https://github.com/facebookexperimental/rome/issues/20。

关于如何使用Rome,官方提到只支持从源码构建。本文最后介绍如何让Rome跑起来。

Rome长什么样

正如项目页面所说,Rome现在还在开发中,不能在实际项目中使用。不过,通过其CLI帮助信息可以大致了解目前Rome提供的特性。

源代码命令

代码质量命令

流程管理命令

项目管理命令

内部命令

打包

Rome的打包流程比较独特,所有编译都以模块为单位,每个模块都通过一个工作线程池来处理。这个流程用于转译单个模块没问题,但打包时就可能存在问题,比如重复解析已经由其他工作线程解析完成的模块。为此,需要给模块预先添加命名空间,让模块全部共享一个作用域。

Rome会给模块作用域中的每个变量加上前缀,即根据模块名称生成的一个标识符。比如,test.js中的变量foo会变成test_js_foo。

同样,对每个模块的导入和导出标识符也会如此处理。这样,任何模块的导出都可以通过模块的名字及其导出的名字来确定。

1. 输出

比如,moduleA.mjs(Rome打包模块时要求使用.mjs扩展名)中包含以下导出变量:

export const myVar = 'hello'

另一个模块文件module.mjs导入这个模块:

import { myVar } from './moduleA.mjs'

运行:

rome bundle mudule.mjs dist

会在dist目录生成如下index.js文件:

(function(global) {

  'use strict';

  // rome-root/moduleA.mjs

const ___R$rome$root$moduleA_mjs$myVar = 'hello';


  // rome-root/module.mjs

const ___R$rome$root$module_mjs = {};

  console.log(___R$rome$root$moduleA_mjs$myVar);


  return ___R$rome$root$module_mjs;

})(typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : this);

由此可见,Rome打包后的文件类似Rullup,即所有模块都被打进一个共享的闭包作用域,而不是像Webpack那样每个模块都有一个闭包,然后通过运行时加载器把这些闭包串起来。

2. 复杂的例子

下面再尝试一个贴近项目的例子。

entry.tsx:

import React from './react';

import title from './other';


async function App(props: any) {

  return <div id="app">{await title()}</div>

}


App({}).then(console.log);

other.tsx:

import React from './react';export default () => <h1>Hello World</h1>;

react.tsx:

type VNode = {  type: string;  props: any;  children: Array<VNode|string>};function createElement(  type: string,  props: any,  ...children: Array<VNode|string>): VNode {  return { type, props, children };}export default { createElement };

运行rome bundle entry.tsx bundle:

➜ rome git:(master) ✗ rome bundle entry.tsx bundle⚠ Disk caching has been disabled due to the ROME_CACHE=0 environment variable ⚠ℹ Bundling packages/@romejs/cli/bin/rome.ts✔ Saved the following files to /tmp/rome-dev  - index.js 2.41MB entry  - index.js.map 95B sourcemap  - bundlebuddy.json 473kB stats⚠ Disk caching has been disabled due to the ROME_CACHE=0 environment variable ⚠ℹ Bundling entry.tsx✔ Saved the following files to bundle  - index.js 907B entry  - index.js.map 95B sourcemap  - bundlebuddy.json 293B stats

会在bundle目录生成如下index.js文件:

(function(global) {

  'use strict';

  // rome-root/react.tsx

  function ___R$$priv$rome$root$react_tsx$createElement(type, props, ...children) {

    return {type: type, props: props, children: children};

  }

  const ___R$rome$root$react_tsx$default = {

    createElement: ___R$$priv$rome$root$react_tsx$createElement

  };


  // rome-root/other.tsx

        const ___R$rome$root$other_tsx$default = () =>

      ___R$rome$root$react_tsx$default.createElement('h1', null, 'Hello World');


  // rome-root/entry.tsx

  const ___R$rome$root$entry_tsx = {};

  async function ___R$$priv$rome$root$entry_tsx$App(props) {

    return ___R$rome$root$react_tsx$default.createElement('div', {

      id: 'app'}, (await ___R$rome$root$other_tsx$default()));

  }


  ___R$$priv$rome$root$entry_tsx$App({}).then(console.log);


  return ___R$rome$root$entry_tsx;

})(typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : this);

乍看起来似乎有点乱,但删减掉特定于模块的代码再看,就容易理解了:

(function(global) {

  'use strict';

  // rome-root/react.tsx

  const ___R$rome$root$react_tsx$default = /* 省略 */


  // rome-root/other.tsx

  const ___R$rome$root$other_tsx$default = /* 省略 */


  // rome-root/entry.tsx

  const ___R$rome$root$entry_tsx = {}; /* 省略 */

   ___R$$priv$rome$root$entry_tsx$App({}).then(console.log);


  return ___R$rome$root$entry_tsx;

})(window);

实际上,跟前面那个简单的例子一样:三个模块都被打进了一个闭包。

帮助信息

运行rome --help可以看到Rome目前“完整”的帮助信息:

➜ ~ rome --help

⚠ Disk caching has been disabled due to the ROME_CACHE=0 environment variable ⚠

ℹ Bundling Projects/_projects/rome/packages/@romejs/cli/bin/rome.ts

✔ Saved the following files to /tmp/rome-dev

  - index.js 2.41MB entry

  - index.js.map 95B sourcemap

  - bundlebuddy.json 473kB stats


  Usage: rome [command] [flags]


  Options


    --benchmark no description found

    --benchmark-iterations <num> no description found

    --collect-markers no description found

    --cwd <input> no description found

    --fieri no description found

    --focus <input> no description found

    --grep <input> no description found

    --help show this help screen

    --inverse-grep no description found

    --log-path <input> no description found

    --logs no description found

    --log-workers no description found

    --markers-path <input> no description found

    --max-diagnostics <num> no description found

    --no-profile-workers no description found

    --no-show-all-diagnostics no description found

    --profile no description found

    --profile-path <input> no description found

    --profile-sampling <num> no description found

    --profile-timeout <num> no description found

    --rage no description found

    --rage-path <input> no description found

    --resolver-mocks no description found

    --resolver-scale <num> no description found

    --silent no description found

    --temporary-daemon no description found

    --verbose no description found

    --verbose-diagnostics no description found

    --watch no description found


  Code Quality Commands


    ci install dependencies, run lint and tests

    lint run lint against a set of files

    test run tests

      --no-coverage no description found

      --show-all-coverage no description found

      --update-snapshots no description found


  Internal Commands


    evict evict a file from the memory cache

    logs

    rage


  Process Management Commands


    restart restart daemon

    start start daemon (if none running)

    status get the current daemon status

    stop stop a running daemon if one exists

    web


  Project Management Commands


    config

    publish TODO

    run TODO


  Source Code Commands


    analyzeDependencies analyze and dump the dependencies of a file

      --compact no description found

      --focus-source <input> no description found

    bundle build a standalone js bundle for a package

    compile compile a single file

      --bundle no description found

    develop start a web server

      --port <num> no description found

    parse parse a single file and dump its ast

      --no-compact no description found

      --show-despite-diagnostics no description found

    resolve resolve a file

让Rome跑起来

如前所述,Rome还没有发布npm包,因此只能通过代码来使用。首先,克隆其Github仓库:

git clone git@github.com:facebookexperimental/rome.git

然后:

cd rome

最后运行:

scripts/dev-rome --help


标签:description,no,--,rome,Rome,Facebook,found,JS,root
来源: https://blog.51cto.com/u_15127660/2784400