node package manager
Don’t reinvent the wheel. Reuse code within your team. Create a free org »

ftx

Conduit

This module allows you to perform source-code transform in real-time during file transfer. Code in a custom syntax and freely upload/download to and from your server that supports a different syntax.

Use Case

The use case it was developed for is React JSX syntax (which is similar to E4X or embedded XML in JS) and some custom CSS extensions (modules and variables).

At Facebook we use JSX in our JavaScript, which our servers can handle, but will cause most IDE's syntax parsing to freak out. Same goes for CSS modules and embedded variables.

Enter source transform. If you want to use JSX in your IDE and your IDE supports ES6 Template Strings, one work around is to wrap the JSX literals in multi-line string templates (using back-tick quotes).

One way to do this is to download your file, transform it using a command line, open and edit in your IDE, transform back and then upload.

That would be such a hassle it would negate any efficiencies you would gain from using a smart IDE in the first place!

Enter Conduit. Using this tool, you can perform the source transform during the upload/download process.

There are two ways to use it

  1. Command Line: use the ftx command from within a directory that has a .ftx.conf file (which describes your remote server) Example: ftx get path/to/remote-file.js This will get the file, create the directory path locally and save the transformed file. or: ftx put path/to/local-file.css

  2. FTP Proxy: since every IDE will support FTP upload/download (usually with a shortcut key) Conduit will run an FTP server on localhost and act as a proxy to your remote server. The transform(s) are performed transparently as you upload/download your source files. Example: ftx proxy 2121 to run the FTP server on port 2121

You can define custom transforms that are defined in transforms.js and indexed by file extension.

Currently the remote server must support SFTP for secure file transfer. Other transfer protocols could be supported by re-creating the logic in lib/ssh-fs.js.

For command-line use, the hostname, port, username and password (encoded in base64) must be present in .ftx.conf which is a JSON-formatted file.

For FTP proxy, the upstream host, port and username can all be embedded in the username field of your FTP client: me#10.0.0.1:22 so you don't have to put your password in your project directory.

Installation

npm install ftx

Then go to your project directory and run ftx proxy or create a .ftx.conf file (see example directory) and run ftx get file.

Transforms

Source transforms must be reversible! It would stand to reason that a source file that is transformed one way and then back again should be identical to the original.

Add your own transforms by editing ./transforms.js and put the dependent modules inside transforms directory (yes, the transforms should probably be in a separate project).

IDE + JSX

I use WebStorm/IntelliJ as a front-end dev, and these IDEs are very powerful for refactoring, hinting/linting as you type, suggesting optimizations, etc. But you lose all that power if the IDE cannot understand your syntax! This is the downside of extending syntax of a language and unfortunately there is no easy way to extend these IDE's language parsers.

However with some cool trickery we can now get most of our refactorings even within JSX embedded expressions:

var a = true;
return <a href={a ? b : c}>{content}</a>;

This will transform to:

var a = true;
return JSX(`<a href=${a ? b : c}>${content}</a>`);

(Assumeing you have the doc-block directive required by JSX)

The ${} allows us to tell our IDE that the expressions enclosed are still JS and should participate in any refactoring.

NOTE: This is not the same as the JSX conversion that will eventually happen beore this source is sent to the browser. This is a more literal, reversible transform that preserves most of the syntax by simply wrapping the JSX.

Nested JSX inside JS expressions is also supported:

var item = <a href={a ? b : c}>
  <strong>{content}</strong
</a>;

CSS

The CSS module syntax:

.c1/c2 {
  color: black;
}

will have it's slashed transformed to double-underscores:

.c1__c2 {
  color: black;
}

and variables will be simply enclosed in comments since there is no easy reversible way to represent variables in valid CSS syntax.

Issues

Please install and use this library and report any bugs you find!