Coder Social home page Coder Social logo

lastmjs / zwitterion Goto Github PK

View Code? Open in Web Editor NEW
570.0 11.0 14.0 960 KB

A web dev server that lets you import anything*

License: MIT License

JavaScript 10.09% TypeScript 89.91%
typescript javascript spa c cpp webassembly wasm rust es6 es7 es2016 assemblyscript esnext

zwitterion's Introduction

build status npm version dependency Status devDependency Status

Zwitterion

A web dev server that lets you import anything*

* If by anything you mean: JavaScript ES2015+, TypeScript, JSON, JSX, TSX, AssemblyScript, Rust, C, C++, WebAssembly, and in the future anything that compiles to JavaScript or WebAssembly.

Zwitterion is designed to be an instant replacement for your current web development static file server.

Production deployments are also possible through the static build.

For example, you can write stuff like the following and it just works:

./index.html:

  <!DOCTYPE html>

  <html>
    <head>
      <script type="module" src="app.ts"></script>
    </head>

    <body>
      This is the simplest developer experience I've ever had!
    </body>
  </html>

./app.ts:

import { getHelloWorld } from './hello-world.ts';

const helloWorld: string = getHelloWorld();

console.log(helloWorld);

./hello-world.ts:

export function getHelloWorld(): string {
  return 'Why hello there world!';
}

Really, it just works.

Zwitterion lets you get back to the good old days of web development.

Just write your source code in any supported language and run it in the browser.

Also...Zwitterion is NOT a bundler. It eschews bundling for a simpler experience.

Current Features

  • ES2015+
  • TypeScript
  • JSON
  • JSX
  • TSX
  • AssemblyScript
  • Rust (basic support)
  • C (basic support)
  • C++ (basic support)
  • WebAssembly Text Format (Wat)
  • WebAssembly (Wasm)
  • Bare imports (import * as stuff from 'library'; instead of import * as stuff from '../node_modules/library/index.js';)
  • Single Page Application routing (by default the server returns index.html on unhandled routes)
  • Static build for production deployment

Upcoming Features

  • More robust Rust integration (i.e. automatic local Rust installation during npm installation)
  • More robust C integration
  • More robust C++ integration
  • Import maps
  • HTTP2 optimizations

Documentation

Installation and Basic Use

Local Installation and Use

Install Zwitterion in the directory that you would like to serve files from:

npm install zwitterion

Run Zwitterion by accessing its executable directly from the terminal:

node_modules/.bin/zwitterion

or from an npm script:

{
  ...
  "scripts": {
    "start": "zwitterion"
  }
  ...
}

Global Installation and Use

Install Zwitterion globally to use across projects:

npm install -g zwitterion

Run Zwitterion from the terminal:

zwitterion

or from an npm script:

{
  ...
  "scripts": {
    "start": "zwitterion"
  }
  ...
}

Production Use

It is recommended to use Zwitterion in production by creating a static build of your project. A static build essentially runs all relevant files through Zwitterion, and copies those and all other files in your project to a dist directory. You can take this directory and upload it to a Content Delivery Network (CDN), or another static file hosting service.

You may also use a running Zwitterion server in production, but for performance and potential security reasons it is not recommended.

To create a static build, run Zwitterion with the --build-static option. You will probably need to add the application/javascript MIME type to your hosting provider for your TypeScript, AssemblyScript, Rust, Wasm, and Wat files.

From the terminal:

zwitterion --build-static

From an npm script:

{
  ...
  "scripts": {
    "build-static": "zwitterion --build-static"
  }
  ...
}

The static build will be located in a directory called dist, in the same directory that you ran the --build-static command from.

Languages

JavaScript

JavaScript is the language of the web. You can learn more here.

Importing JavaScript ES2015+ is straightforward and works as expected. Simply use import and export statements without any modifications. It is recommended to use explicit file extensions:

./app.js:

import { helloWorld } from './hello-world.js';

console.log(helloWorld());

./hello-world.js:

export function helloWorld() {
  return 'Hello world!';
}

JavaScript transpilation is done by the TypeScript compiler. By default, the TypeScript compiler's compilerOptions are set to the following:

  {
    "module": "ES2015",
    "target": "ES2015"
  }

You can override these options by creating a .json file with your own compilerOptions and telling Zwitterion where to locate it with the --tsc-options-file command line option. The available options can be found here. Options are specified as a JSON object. For example:

tsc-options.json:

{
  "target": "ES5"
}

Tell Zwitterion where to locate it:

zwitterion --tsc-options-file tsc-options.json

TypeScript

TypeScript is a typed superset of JavaScript. You can learn more here.

Importing TypeScript is straightforward and works as expected. Simply use import and export statements without any modifications. It is recommended to use explicit file extensions:

./app.ts:

import { helloWorld } from './hello-world.ts';

console.log(helloWorld());

./hello-world.ts:

export function helloWorld(): string {
  return 'Hello world!';
}

By default, the TypeScript compiler's compilerOptions are set to the following:

  {
    "module": "ES2015",
    "target": "ES2015"
  }

You can override these options by creating a .json file with your own compilerOptions and telling Zwitterion where to locate it with the --tsc-options-file command line option. The available options can be found here. Options are specified as a JSON object. For example:

tsc-options.json:

{
  "target": "ES5"
}

Tell Zwitterion where to locate it:

zwitterion --tsc-options-file tsc-options.json

JSON

JSON is provided as a default export. It is recommended to use explicit file extensions:

./app.js:

import helloWorld from './hello-world.json';

console.log(helloWorld);

./hello-world.json:

{
  "hello": "world"
}

JSX

Importing JSX is straightforward and works as expected. Simply use import and export statements without any modifications. It is recommended to use explicit file extensions:

./app.js:

import { helloWorldElement } from './hello-world.jsx';

ReactDOM.render(
  helloWorldElement,
  document.getElementById('root')
);

./hello-world.jsx:

export const hellowWorldElement = <h1>Hello, world!</h1>;

JSX transpilation is done by the TypeScript compiler. By default, the TypeScript compiler's compilerOptions are set to the following:

  {
    "module": "ES2015",
    "target": "ES2015"
  }

You can override these options by creating a .json file with your own compilerOptions and telling Zwitterion where to locate it with the --tsc-options-file command line option. The available options can be found here. Options are specified as a JSON object. For example:

tsc-options.json:

{
  "target": "ES5"
}

Tell Zwitterion where to locate it:

zwitterion --tsc-options-file tsc-options.json

TSX

Importing TSX is straightforward and works as expected. Simply use import and export statements without any modifications. It is recommended to use explicit file extensions:

./app.js:

import { helloWorldElement } from './hello-world.tsx';

ReactDOM.render(
  helloWorldElement,
  document.getElementById('root')
);

./hello-world.tsx:

const helloWorld: string = 'Hello, world!';

export const hellowWorldElement = <h1>{ helloWorld }</h1>;

TSX transpilation is done by the TypeScript compiler. By default, the TypeScript compiler's compilerOptions are set to the following:

  {
    "module": "ES2015",
    "target": "ES2015"
  }

You can override these options by creating a .json file with your own compilerOptions and telling Zwitterion where to locate it with the --tsc-options-file command line option. The available options can be found here. Options are specified as a JSON object. For example:

tsc-options.json:

{
  "target": "ES5"
}

Tell Zwitterion where to locate it:

zwitterion --tsc-options-file tsc-options.json

AssemblyScript

AssemblyScript is a new language that compiles a strict subset of TypeScript to WebAssembly. You can learn more about it in The AssemblyScript Book.

Zwitterion assumes that AssemblyScript files have the .as file extension. This is a Zwitterion-specific extension choice, as the AssemblyScript project has not yet chosen its own official file extension. You can follow that discussion here. Zwitterion will follow the official extension choice once it is made.

Importing AssemblyScript is nearly identical to importing JavaScript or TypeScript. The key difference is that the default export of your entry AssemblyScript module is a function that returns a promise. This function takes as its one parameter an object containing imports to the AssemblyScript module.

Passing values to and from functions exported from AssemblyScript modules should be straightforward, but there are some limitations. Zwitterion uses as-bind under the hood to broker values to and from AssemblyScript modules. Look there if you need more information.

You can import AssemblyScript from JavaScript or TypeScript files like this:

./app.js:

import addModuleInit from './add.as';

runAssemblyScript();

async function runAssemblyScript() {
  const adddModule = await addModuleInit();

  console.log(addModule.add(1, 1));
}

./add.as:

export function add(x: i32, y: i32): i32 {
  return x + y;
}

If you want to pass in imports from outside of the AssemblyScript environment, you create a file with export declarations defining the types of the imports. You then pass your imports in as an object to the AssemblyScript module init function. The name of the property that defines your imports for a module must be the exact filename of the file exporting the import declarations. For example:

./app.js:

import addModuleInit from './add.as';

runAssemblyScript();

async function runAssemblyScript() {
  const adddModule = await addModuleInit({
    'env.as': {
      log: console.log
    }
  });

  console.log(addModule.add(1, 1));
}

./env.as:

export declare function log(x: number): void;

./add.as:

import { log } from './env.as';

export function add(x: i32, y: i32): i32 {

  log(x + y);

  return x + y;
}

You can also import AssemblyScript from within AssemblyScript files, like so:

./add.as:

import { subtract } from './subtract.as';

export function add(x: i32, y: i32): i32 {
  return subtract(x + y, 0);
}

./subtract.as:

export function subtract(x: i32, y: i32): i32 {
  return x - y;
}

By default, no compiler options have been set. The available options can be found here. You can add options by creating a .json file with an array of option names and values, and telling Zwitterion where to locate it with the --asc-options-file command line option. For example:

./asc-options.json:

[
  "--optimizeLevel", "3",
  "--runtime", "none",
  "--shrinkLevel", "2"
]

Tell Zwitterion where to locate it:

zwitterion --asc-options-file asc-options.json

Rust

Rust is a low-level language focused on performance, reliability, and productivity. Learn more here.

Rust support is currently very basic (i.e. no wasm-bindgen support). You must have Rust installed on your machine. You can find instructions for installing Rust here. It is a goal of Zwitterion to automatically install a local version of the necessary Rust tooling when Zwitterion is installed, but that is currently a work in progress.

Importing Rust is nearly identical to importing JavaScript or TypeScript. The key difference is that the default export of your entry Rust module is a function that returns a promise. This function takes as its one parameter an object containing imports to the Rust module. You can import Rust from JavaScript or TypeScript files like this:

./app.js

import addModuleInit from './add.rs';

runRust();

async function runRust() {
  const addModule = await addModuleInit();

  console.log(addModule.add(5, 5));
}

./add.rs

#![no_main]

#[no_mangle]
pub fn add(x: i32, y: i32) -> i32 {
  return x + y;
}

C

C support is currently very basic. You must have Emscripten installed on your machine. You can find instructions for installing Emscripten here. It is a goal of Zwitterion to automatically install a local version of the necessary C tooling when Zwitterion is installed, but that is currently a work in progress.

Importing C is nearly identical to importing JavaScript or TypeScript. The key difference is that the default export of your entry C module is a function that returns a promise. This function takes as its one parameter an object containing imports to the C module. You can import C from JavaScript or TypeScript files like this:

./app.js

import addModuleInit from './add.c';

runC();

async function runC() {
  const addModule = await addModuleInit();

  console.log(addModule.add(5, 5));
}

./add.c

int add(int x, int y) {
  return x + y;
}

C++

C++ support is currently very basic. You must have Emscripten installed on your machine. You can find instructions for installing Emscripten here. It is a goal of Zwitterion to automatically install a local version of the necessary C++ tooling when Zwitterion is installed, but that is currently a work in progress.

Importing C++ is nearly identical to importing JavaScript or TypeScript. The key difference is that the default export of your entry C++ module is a function that returns a promise. This function takes as its one parameter an object containing imports to the C++ module. You can import C++ from JavaScript or TypeScript files like this:

./app.js

import addModuleInit from './add.cpp';

runCPP();

async function runCPP() {
  const addModule = await addModuleInit();

  console.log(addModule.add(5, 5));
}

./add.cpp

extern "C" {
  int add(int x, int y) {
    return x + y;
  }
}

WebAssembly Text Format (Wat)

Wat is a textual representation of the Wasm binary format. It allows Wasm to be more easily written by hand. Learn more here.

Importing Wat is nearly identical to importing JavaScript or TypeScript. The key difference is that the default export of your entry Wat module is a function that returns a promise. This function takes as its one parameter an object containing imports to the Wat module. You can import Wat from JavaScript or TypeScript files like this:

./app.js

import addModuleInit from './add.wat';

runWat();

async function runWat() {
  const addModule = await addModuleInit();

  console.log(addModule.add(5, 5));
}

./add.wat

(module
  (func $add (param $x i32) (param $y i32) (result i32)
    (i32.add (get_local $x) (get_local $y))
  )
  (export "add" (func $add))
)

WebAssembly (Wasm)

Wasm is a binary instruction format built to be efficient, safe, portable, and open. Learn more here.

Importing Wasm is nearly identical to importing JavaScript or TypeScript. The key difference is that the default export of your entry Wasm module is a function that returns a promise. This function takes as its one parameter an object containing imports to the Wasm module. You can import Wasm from JavaScript or TypeScript files like this:

./app.js

import addModuleInit from './add.wasm';

runWasm();

async function runWasm() {
  const addModule = await addModuleInit();

  console.log(addModule.add(5, 5));
}

./add.wasm

Imagine this is a compiled Wasm binary file with a function called `add`

Command Line Options

Port

Specify the server's port:

--port [port]

Build Static

Create a static build of the current working directory. The output will be in a directory called dist in the current working directory:

--build-static

Exclude

A comma-separated list of paths, relative to the current directory, to exclude from the static build:

--exclude [exclude]

Include

A comma-separated list of paths, relative to the current directory, to include in the static build

--include [include]

SPA Root

A path to a file, relative to the current directory, to serve as the SPA root. It will be returned for the root path and when a file cannot be found:

--spa-root [spaRoot]

Disable SPA

Disable the SPA redirect to index.html:

--disable-spa

Headers File

A path to a JSON file, relative to the current directory, for custom HTTP headers:

--headers-file [headersFile]

Custom HTTP headers are specified as a JSON object with the following shape:

type CustomHTTPHeaders = {
    [regexp: string]: HTTPHeaders;
}

type HTTPHeaders = {
    [key: string]: string;
}

For example:

./headers.json

{
  "^service-worker.ts$": {
    "Service-Worker-Allowed": "/"
  }
}

TSC Options File

A path to a JSON file, relative to the current directory, for tsc compiler options:

--tsc-options-file [tscOptionsFile]

The available options can be found here. Options are specified as a JSON object. For example:

tsc-options.json:

{
  "target": "ES5"
}

ASC Options File

A path to a JSON file, relative to the current directory, for asc compiler options:

--asc-options-file [ascOptionsFile]

By default, no compiler options have been set. The available options can be found here. Options are specified as an array of option names and values. For example:

./asc-options.json:

[
  "--optimizeLevel", "3",
  "--runtime", "none",
  "--shrinkLevel", "2"
]

Special Considerations

Third-party Packages

Third-party packages must be authored as if they were using Zwitterion. Essentially this means they should be authored in standard JavaScript or TypeScript, and AssemblyScript, Rust, C, and C++ must be authored according to their WebAssembly documentation. Notable exceptions will be explained in this documentation. CommonJS (the require syntax), JSON, HTML, or CSS ES Module imports, and other non-standard features that bundlers commonly support are not suppored in source code.

Root File

It's important to note that Zwitterion assumes that the root file (the file found at /) of your web application is always an index.html file.

ES Module script elements

Zwitterion depends on native browser support for ES modules (import/export syntax). You must add the type="module" attribute to script elements that reference modules, for example:

<script type="module" src="amazing-module.ts"></script>

Performance

It's important to note that Zwitterion does not bundle files nor engage in tree shaking. This may impact the performance of your application. HTTP2 and ES modules may help with performance, but at this point in time signs tend to point toward worse performance. Zwitterion has plans to improve performance by automatically generating HTTP2 server push information from the static build, and looking into tree shaking, but it is unclear what affect this will have. Stay tuned for more information about performance as Zwitterion matures.

With all of the above being said, the performance implications are unclear. Measure for yourself.

Read the following for more information on bundling versus not bundling with HTTP2:

Under the Hood

Zwitterion is simple. It is more or less a static file server, but it rewrites requested files in memory as necessary to return to the client. For example, if a TypeScript file is requested from the client, Zwitterion will retrieve the text of the file, compile it to JavaScript, and then return the compiled text to the client. The same thing is done for JavaScript files. In fact, nearly the same process will be used for any file extension that we want to support in the future. For example, in the future, if a C file is requested it will be read into memory, the text will be compiled to WebAssembly, and the WebAssembly will be returned to the client. All of this compilation is done server-side and hidden from the user. To the user, it's just a static file server.

zwitterion's People

Contributors

dependabot[bot] avatar lastmjs avatar renovate-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zwitterion's Issues

Allow http2

It would be really nice if this thing could generate development certificates for you. Also, to make sure this can be used in production, allow the user to specify where the certs are located. That should probably be done in the zwitterion.json file.

HTTP2 server push

This might be the way to make HTTP2 at least as efficient as bundling, thereby obsoleting bundlers. If push allows us to send all assets that we need for a request at once, then imagine the efficiency gains. How we do this would be by analyzing the dependency graph of the current script being requested. This would only work for es modules, but I think that is the future and that is okay. There are tools available I believe that will allow us to get all of the dependency information that we need for a module. We could then grab and transpile all of the dependencies, and server push them to the client, thus hopefully saving many round-trips as the browser does not have to request files individually as the module is being parsed and its dependencies fetched on the client. One problem I see is that HTTP2 is not currently supported by this library. This library is just HTTP1, assuming that you'll have some kind of other wrapper to provide HTTP2/SSL support. That works really well with Dokku...but we might just have to change that and make this thing production ready stand-alone. This could be it. We should run benchmarks to prove its efficiency, and read through and disprove all of the articles that say HTTP2 does not obsolete bundling (most specifically I'm thinking about the Khan Academy article).

Create valid certificates

Right now the certificates that are automatically generated will work, but you have to tell the browser its okay, and the https thing in the URL has a red cross through it. See if you can remedy all of that by generating proper certificates.

Get rid of socket.io

Do not use socket.io, just use the native websocket api in the browser, along with this Node.js websocket server: https://github.com/websockets/ws

I do not see a compelling reason to keep using socket.io, since we are using very basic functionality, and the browser support for websockets seems overwhelming.

Send type checking to the client console

This would be awesome for using TS. We could get the benefits of type checking in the browser without the performance penalty. We might even be able to turn on strict type checking so that type checks stop the script being requested from running, if that's desirable, which I kind of think isn't because it is too restricting. But sending the type errors to the client is awesome.

Pre-compression

Some of the performance problems with HTTP2 seem to be that gzip compression of small files is less optimal than gzip compression of large files, so bundling can still perform better. To address this, see if you can get access to the gzipped files after they are sent initially. Store those compressed files in memory and then serve them up. With this and server push, hopefully we can start fighting back against the bundling claims.

Allow automatic selection of open port

If the default address is in use, think about whether we should automatically choose a different port, or perhaps allow that as a command-line parameter.

Write an article

Once this thing has been used for a while on multiple projects, and the production story is well-defined, write an article about it.

Allow for js extensions

It seems like we might have some serious issues in the future as the es6 module loader starts to be implemented in browsers...I'm not sure the spec will allow for no extension on an import statement. Also, it might confuse people to request a .ts file and receive a .js file that can run in the browser. I think it's awesome, and it works for now. But if there are problems, then consider the following:

When a .js file is requested by the client, the server will first check in its cache, then check on disk for a .js file, and finally if none of those have worked it will check for a .ts file. This way the browser can request .js files, and .js files can be put into the module syntax, but the files will really be stored as .ts files...well, I'm not sure how this will work out. Tooling might get confused because the files do not match up with their extensions. Developers will probably get confused as well. It seems like allowing .ts extensions in modules and script tags would really be the best thing, but I'm not sure that will be possible.

General overview

Somehow allow for live reload (potentially even hot code replacement), http2, and server-side transpilation of code. This would allow you to have no development build process at no cost (besides the incremental build time), and the user wouldn't have to worry about changing any of their file imports. They could write <script src="test.ts"></script> and the server would be able to serve up from memory the transpiled file. Just do in-memory incremental builds all of the time.

Allow zwitterion to be installed and used at the top level

Right now zwitterion needs to have plugin-typescript in the server context that it creates because of the way systemjs-builder is configured and gets a reference to the plugin. Figure out how to change that so it doesn't matter where the node_modules folder is that contains plugin-typescript

Create config file

Create the config file. Save to the file automatically upon request of a file the file that is being requested. When zwitterion first starts up, use this file to automatically transpile everything right away...then again, maybe it isn't that important? If there are performance issues, such as the first request takes forever to load, then do this. Otherwise it is probably not worth doing until later.

Contact all people who starred es-no-build

Contact those people and explain that if they had use for es-no-build, zwitterion would be much better. Also reply to all previous tweets you made about es-no-build, explaining the same thing.

Explain production more generically

Don't include instructions for Dokku, only a small subset of the devops world uses that. Describe things more generically, and if it does seem beneficial, explain how to get a Docker image up instead. Using containers seems much more reasonable...just explain the steps you would take to get this thing into production on any machine, and then people will be able to create their own containers to get it to work. You might consider creating a dockerfile or container image that people can use right away.

Don't write sync on zwitterion json

I'm doing this because it is easy at the moment, but it is bad for performance. The writeSyncs will be happening on each request, so it would be a lot better to make them asynchronous. But it looks like that is going to require synchronizing and queueing access to the file system, which I just don't want to figure out at the moment.

Allow for transpilation output to a directory

With the command line paramter --output [directory name], transpile everything to that directory. This will allow for zwitterion to be used to develop consumable components and applications that might not be able to be used with zwitterion server.

Allow choosing the location of the file to redirect to

The user should probably be able to choose which file gets redirected to (remember this is for single page applications, so we are emulating a server rewrite). Right not it defaults to index.html in the directory that the script is running in, process.cwd(). Also, allow the user to turn off SPA support if they don't want things redirecting.

Use async/await

Once NodeJS 8 comes out and async/await is supported without a flag, use that instead of promises. It's getting a little messy, especially the error handling.

Make it production and development ready

This thing need to be able to be used as a production and development server, thus keeping the build process in development equivalent to the build process in production (which should be close to none). Allow an option for minifying.

Fix http and socket.io

Right now the live reload will only work over HTTPS because of the socket.io configuration. Change that configuration so that it uses http if Zwitterion is serving over http

.mjs

If .mjs becomes the standard way to name an es module, then that might simplify everything because we can just transpile all .mjs files...and that .mjs file can be typescript or not, and we'll just transpile it. We need to make sure that our typescript plugins will still work for .mjs files

Gzip

Add gzip support

Inject all dependencies with the first file requested

To allow the server to be installed at the root level of a project, one of the things we need to do is get the dependencies to the client without the client needing to have them installed in the directory being served from. Do it!

New idea

We're getting close to es modules being supported in all major browsers. Once we drop support for SystemJS, we're going to have some issues. How do we know which files to transpile? How do we import .ts files if .ts extensions aren't allowed? A simple way to fix this is to allow .js files to contain ts. Perhaps put a simple directive at the top indicating the file should be transpiled. Then all files could be imported the same way, and only the files you indicate will be transpiled.

Use this for scram engine by default

Should I do this? I will be forcing everyone who uses scram engine to transpile...I don't think it should be the default...but it should be an option. Allow the user to specify if they want transpilation or not. Or maybe allow them to specify if they don't want transpilation.

Explain browser-config better

browser-config.js must be requested as if it were in the root directory of your server, so the serve-dir. You might have to use relative paths to get around that.

Explain issue with .ts mime type

The .ts file extension apparently has a mime type already for an iOS video stream thing. Explain that in production you'll need to override the mime type for .ts files if you choose to include .ts files directly through scripts tags.

Create a better Zwitterion

Use nginx. Create a very simple node server that nginx proxies requests to. That simple server will transpile the files and return them. Enable awesome caching. Enable that one special mime type by default. Get rid of https setup inside of zwitterion. Nginx should be able to take care of cacheing, https, and all of the other production stuff. Wrap this thing up so that it can be pushed to production with docker or dokku. Figure out how to push all of the files needed to production.

Here is how to get into a docker container: docker exec -it [container-id] bash

  • Figure out how to name docker containers from dokku

Out of memory errors

When refreshing the page a lot, sometimes the server crashes because the JavaScript heap runs out of memory.

Allow for no serveDir to be specified

If no serveDir is specified, default to the current working directory that the server was started up in as the root directory. I just want to make sure it will work, because I have reason to believe that because of /'s in some of the string literals, it might break.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.