Un servidor de desarrollo web que le permite importar cualquier cosa*
* Si es por algo que quiere decir: JavaScript ES2015+, TypeScript, JSON, JSX, TSX, AssemblyScript, Rust, C, C ++, WebAssembly, y en el futuro cualquier cosa que se compila a JavaScript o WebAssembly.
Zwitterion está diseñado para ser un reemplazo instantáneo para su servidor de archivos estático de desarrollo web actual.
Las implementaciones de producción también son posibles a través de la construcción estática.
Por ejemplo, puede escribir cosas como lo siguiente y simplemente funciona:
./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!' ;
}Realmente, solo funciona.
Zwitterion le permite volver a los viejos tiempos del desarrollo web.
Simplemente escriba su código fuente en cualquier idioma compatible y ejecútelo en el navegador.
Además ... Zwitterion no es un Bundler. Evita la agrupación para una experiencia más simple.
import * as stuff from 'library'; en lugar de import * as stuff from '../node_modules/library/index.js'; )index.html en rutas no controladas)Instale zwitterion en el directorio del que le gustaría servir archivos:
npm install zwitterionEjecute Zwitterion accediendo a su ejecutable directamente desde el terminal:
node_modules/.bin/zwitterion
o de un script npm:
{
...
"scripts": {
"start": "zwitterion"
}
...
}
Instale Zwitterion a nivel mundial para usar en todos los proyectos:
npm install -g zwitterionEjecute zwitterion desde la terminal:
zwitteriono de un script npm:
{
...
"scripts": {
"start": "zwitterion"
}
...
}
Se recomienda utilizar Zwitterion en producción creando una construcción estática de su proyecto. Una compilación estática esencialmente ejecuta todos los archivos relevantes a través de Zwitterion, y copia esos y todos los demás archivos en su proyecto a un directorio dist . Puede llevar este directorio y cargarlo a una red de entrega de contenido (CDN) u otro servicio de alojamiento de archivos estáticos.
También puede usar un servidor ZWItersion en su producción en producción, pero por el rendimiento y las posibles razones de seguridad no se recomienda.
Para crear una compilación estática, ejecute Zwitterion con la opción --build-static . Probablemente necesitará agregar el tipo de MIME application/javascript a su proveedor de alojamiento para sus archivos TypeScript, AssemblyScript, Rust, WASM y WAT.
Del terminal:
zwitterion --build-staticDe un script de NPM:
{
...
" scripts " : {
" build-static " : " zwitterion --build-static "
}
...
} La construcción estática se ubicará en un directorio llamado dist , en el mismo directorio que ejecutó el comando --build-static desde.
JavaScript es el idioma de la web. Puedes aprender más aquí.
La importación de JavaScript ES2015+ es sencilla y funciona como se esperaba. Simplemente use declaraciones de importación y exportación sin ninguna modificación. Se recomienda utilizar extensiones de archivos explícitos:
./app.js :
import { helloWorld } from './hello-world.js' ;
console . log ( helloWorld ( ) ) ; ./hello-world.js :
export function helloWorld ( ) {
return 'Hello world!' ;
} La transpilación de JavaScript es realizada por el compilador TypeScript. De forma predeterminada, las compilerOptions compilador de TypeScript se establecen en lo siguiente:
{
"module" : " ES2015 " ,
"target" : " ES2015 "
} Puede anular estas opciones creando un archivo .json con sus propias compilerOptions y diciéndole a Zwitterion dónde localizarlo con la opción de línea de comandos --tsc-options-file . Las opciones disponibles se pueden encontrar aquí. Las opciones se especifican como un objeto JSON. Por ejemplo:
tsc-options.json :
{
"target" : " ES5 "
}Dígale a Zwitterion dónde localizarlo:
zwitterion --tsc-options-file tsc-options.jsonTypeScript es un superconjunto escrito de JavaScript. Puedes aprender más aquí.
La importación de TypeScript es sencillo y funciona como se esperaba. Simplemente use declaraciones de importación y exportación sin ninguna modificación. Se recomienda utilizar extensiones de archivos explícitos:
./app.ts :
import { helloWorld } from './hello-world.ts' ;
console . log ( helloWorld ( ) ) ; ./hello-world.ts :
export function helloWorld ( ) : string {
return 'Hello world!' ;
} De forma predeterminada, las compilerOptions compilador de TypeScript se establecen en lo siguiente:
{
"module" : " ES2015 " ,
"target" : " ES2015 "
} Puede anular estas opciones creando un archivo .json con sus propias compilerOptions y diciéndole a Zwitterion dónde localizarlo con la opción de línea de comandos --tsc-options-file . Las opciones disponibles se pueden encontrar aquí. Las opciones se especifican como un objeto JSON. Por ejemplo:
tsc-options.json :
{
"target" : " ES5 "
}Dígale a Zwitterion dónde localizarlo:
zwitterion --tsc-options-file tsc-options.jsonJSON se proporciona como una exportación predeterminada. Se recomienda utilizar extensiones de archivos explícitos:
./app.js :
import helloWorld from './hello-world.json' ;
console . log ( helloWorld ) ; ./hello-world.json :
{
"hello" : " world "
}Importar JSX es sencillo y funciona como se esperaba. Simplemente use declaraciones de importación y exportación sin ninguna modificación. Se recomienda utilizar extensiones de archivos explícitos:
./app.js :
import { helloWorldElement } from './hello-world.jsx' ;
ReactDOM . render (
helloWorldElement ,
document . getElementById ( 'root' )
) ; ./hello-world.jsx :
export const hellowWorldElement = < h1 > Hello, world! </ h1 > ; La transpilación JSX lo realiza el compilador TypeScript. De forma predeterminada, las compilerOptions compilador de TypeScript se establecen en lo siguiente:
{
"module" : " ES2015 " ,
"target" : " ES2015 "
} Puede anular estas opciones creando un archivo .json con sus propias compilerOptions y diciéndole a Zwitterion dónde localizarlo con la opción de línea de comandos --tsc-options-file . Las opciones disponibles se pueden encontrar aquí. Las opciones se especifican como un objeto JSON. Por ejemplo:
tsc-options.json :
{
"target" : " ES5 "
}Dígale a Zwitterion dónde localizarlo:
zwitterion --tsc-options-file tsc-options.jsonImportar TSX es sencillo y funciona como se esperaba. Simplemente use declaraciones de importación y exportación sin ninguna modificación. Se recomienda utilizar extensiones de archivos explícitos:
./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 > ; La transpilación TSX lo realiza el compilador TypeScript. De forma predeterminada, las compilerOptions compilador de TypeScript se establecen en lo siguiente:
{
"module" : " ES2015 " ,
"target" : " ES2015 "
} Puede anular estas opciones creando un archivo .json con sus propias compilerOptions y diciéndole a Zwitterion dónde localizarlo con la opción de línea de comandos --tsc-options-file . Las opciones disponibles se pueden encontrar aquí. Las opciones se especifican como un objeto JSON. Por ejemplo:
tsc-options.json :
{
"target" : " ES5 "
}Dígale a Zwitterion dónde localizarlo:
zwitterion --tsc-options-file tsc-options.jsonAssemblyScript es un nuevo lenguaje que compila un subconjunto estricto de mecanografiado a WebAssembly. Puede obtener más información al respecto en el libro Assemblyscript.
Zwitterion supone que los archivos AssemblyScript tienen la extensión del archivo .as . Esta es una opción de extensión específica de Zwitterion, ya que el proyecto AssemblyScript aún no ha elegido su propia extensión de archivo oficial. Puedes seguir esa discusión aquí. Zwitterion seguirá la elección de extensión oficial una vez que se haga.
La importación de ensamblaje es casi idéntica a la importación de JavaScript o TypeScript. La diferencia clave es que la exportación predeterminada de su módulo de Entrada AssemblyScript es una función que devuelve una promesa. Esta función toma como su parámetro un objeto que contiene importaciones al módulo AssemblyScript.
Pasar valores hacia y desde las funciones exportadas desde los módulos de ensamblaje debe ser sencillo, pero hay algunas limitaciones. Zwitterion usa AS de enlace debajo del capó para corretear los valores hacia y desde los módulos AssemblyScript. Mire allí si necesita más información.
Puede importar AssemblyScript desde archivos JavaScript o TypeScript como este:
./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 ;
}Si desea transmitir importaciones desde fuera del entorno AssemblyScript, crea un archivo con declaraciones de exportación que definen los tipos de las importaciones. Luego pasa sus importaciones como un objeto a la función init de módulo ensambloncriptible. El nombre de la propiedad que define sus importaciones para un módulo debe ser el nombre de archivo exacto del archivo que exporta las declaraciones de importación. Por ejemplo:
./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 ;
}También puede importar AssemblyScript desde los archivos de ensamblaje, como así:
./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 ;
} Por defecto, no se han establecido opciones de compilador. Las opciones disponibles se pueden encontrar aquí. Puede agregar opciones creando un archivo .json con una matriz de nombres y valores de opciones, y diciéndole a ZWItersion dónde localizarlo con la opción de línea de comandos --asc-options-file . Por ejemplo:
./asc-options.json :
[
" --optimizeLevel " , " 3 " ,
" --runtime " , " none " ,
" --shrinkLevel " , " 2 "
]Dígale a Zwitterion dónde localizarlo:
zwitterion --asc-options-file asc-options.jsonEl óxido es un lenguaje de bajo nivel centrado en el rendimiento, la confiabilidad y la productividad. Obtenga más información aquí.
El soporte de óxido es actualmente muy básico (es decir, no soporta Wasm-Bindgen). Debe tener óxido instalado en su máquina. Puede encontrar instrucciones para instalar óxido aquí. Es un objetivo de Zwitterion instalar automáticamente una versión local de las herramientas de óxido necesarias cuando se instala Zwitterion, pero actualmente es un trabajo en progreso.
Importar óxido es casi idéntico a la importación de JavaScript o TypeScript. La diferencia clave es que la exportación predeterminada de su módulo de óxido de entrada es una función que devuelve una promesa. Esta función toma como su parámetro un objeto que contiene importaciones al módulo de óxido. Puede importar óxido de archivos JavaScript o TypeScript como este:
./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 ;
}El soporte C es actualmente muy básico. Debe tener Emscripten instalado en su máquina. Puede encontrar instrucciones para instalar Emscripten aquí. Es un objetivo de Zwitterion instalar automáticamente una versión local de las herramientas C necesarias cuando se instala Zwitterion, pero eso es actualmente un trabajo en progreso.
La importación de C es casi idéntica a la importación de JavaScript o TypeScript. La diferencia clave es que la exportación predeterminada de su módulo de entrada C es una función que devuelve una promesa. Esta función toma como su parámetro un objeto que contiene importaciones al módulo C. Puede importar C de archivos JavaScript o TypeScript como este:
./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 ;
}El soporte de C ++ es actualmente muy básico. Debe tener Emscripten instalado en su máquina. Puede encontrar instrucciones para instalar Emscripten aquí. Es un objetivo de Zwitterion instalar automáticamente una versión local de las herramientas C ++ necesarias cuando se instala Zwitterion, pero actualmente es un trabajo en progreso.
La importación de C ++ es casi idéntica a la importación de JavaScript o TypeScript. La diferencia clave es que la exportación predeterminada de su módulo de entrada C ++ es una función que devuelve una promesa. Esta función toma como su parámetro un objeto que contiene importaciones al módulo C ++. Puede importar C ++ desde archivos JavaScript o TypeScript como este:
./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;
}
}
Wat es una representación textual del formato binario WASM. Permite que WASM se escriba más fácilmente a mano. Obtenga más información aquí.
Importar WAT es casi idéntico a la importación de JavaScript o TypeScript. La diferencia clave es que la exportación predeterminada de su módulo WAT de entrada es una función que devuelve una promesa. Esta función toma como su parámetro un objeto que contiene importaciones al módulo WAT. Puede importar WAT desde archivos JavaScript o TypeScript como este:
./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))
)WASM es un formato de instrucción binaria diseñado para ser eficiente, seguro, portátil y abierto. Obtenga más información aquí.
Importar WASM es casi idéntico a la importación de JavaScript o TypeScript. La diferencia clave es que la exportación predeterminada de su módulo WASM de entrada es una función que devuelve una promesa. Esta función toma como su parámetro un objeto que contiene importaciones al módulo WASM. Puede importar WASM de archivos JavaScript o TypeScript como este:
./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`
Especificar el puerto del servidor:
--port [port]Cree una compilación estática del directorio de trabajo actual. La salida estará en un directorio llamado DIST en el directorio de trabajo actual:
--build-staticUna lista de rutas separadas por comas, en relación con el directorio actual, para excluir de la construcción estática:
--exclude [exclude]Una lista de rutas separadas por comas, en relación con el directorio actual, para incluir en la compilación estática
--include [include]Una ruta a un archivo, en relación con el directorio actual, para servir como raíz de spa. Se devolverá para la ruta raíz y cuando no se puede encontrar un archivo:
--spa-root [spaRoot]Deshabilite la redirección de spa a index.html:
--disable-spaUna ruta a un archivo JSON, en relación con el directorio actual, para encabezados HTTP personalizados:
--headers-file [headersFile]Los encabezados HTTP personalizados se especifican como un objeto JSON con la siguiente forma:
type CustomHTTPHeaders = {
[ regexp : string ] : HTTPHeaders ;
}
type HTTPHeaders = {
[ key : string ] : string ;
}Por ejemplo:
./headers.json
{
"^service-worker.ts$" : {
"Service-Worker-Allowed" : " / "
}
}Una ruta a un archivo JSON, en relación con el directorio actual, para las opciones del compilador TSC:
--tsc-options-file [tscOptionsFile]Las opciones disponibles se pueden encontrar aquí. Las opciones se especifican como un objeto JSON. Por ejemplo:
tsc-options.json :
{
"target" : " ES5 "
}Una ruta a un archivo JSON, en relación con el directorio actual, para las opciones del compilador de ASC:
--asc-options-file [ascOptionsFile]Por defecto, no se han establecido opciones de compilador. Las opciones disponibles se pueden encontrar aquí. Las opciones se especifican como una matriz de nombres y valores de opciones. Por ejemplo:
./asc-options.json :
[
" --optimizeLevel " , " 3 " ,
" --runtime " , " none " ,
" --shrinkLevel " , " 2 "
]Los paquetes de terceros deben ser escritos como si estuvieran usando zwitterion. Esencialmente, esto significa que deben ser escritos en JavaScript o TypeScript estándar, y AssemblyScript, Rust, C y C ++ debe ser autor de acuerdo con su documentación de WebAssembly. Las excepciones notables se explicarán en esta documentación. CommonJS (la sintaxis requerida), JSON, HTML o las importaciones del módulo CSS ES, y otras características no estándar que los Bundlers comúnmente admiten no se admiten en el código fuente.
Es importante tener en cuenta que Zwitterion supone que el archivo root (el archivo encontrado en / ) de su aplicación web siempre es un archivo index.html .
Zwitterion depende del soporte de navegador nativo para los módulos ES (sintaxis de importación/exportación). Debe agregar el atributo type="module" a los elementos de script que referen módulos, por ejemplo:
<script type="module" src="amazing-module.ts"></script>
Es importante tener en cuenta que Zwitterion no agrupa archivos ni participa en la sacudida de los árboles. Esto puede afectar el rendimiento de su aplicación. Los módulos HTTP2 y ES pueden ayudar con el rendimiento, pero en este momento los signos de tiempo tienden a apuntar hacia un peor rendimiento. Zwitterion tiene planes de mejorar el rendimiento al generar automáticamente la información del servidor HTTP2 desde la compilación estática y buscar sacudidas de árboles, pero no está claro qué afecta esto tendrá. Estén atentos para obtener más información sobre el rendimiento a medida que madura Zwitterion.
Con todo lo anterior que se dice, las implicaciones de rendimiento no están claras. Medir por ti mismo.
Lea lo siguiente para obtener más información sobre Bundling versus no agrupar con HTTP2:
Zwitterion es simple. Es más o menos un servidor de archivos estáticos, pero reescribe los archivos solicitados en la memoria según sea necesario para volver al cliente. Por ejemplo, si se solicita un archivo TypeScript del cliente, Zwitterion recuperará el texto del archivo, lo compilará a JavaScript y luego devolverá el texto compilado al cliente. Lo mismo se hace para archivos JavaScript. De hecho, casi el mismo proceso se utilizará para cualquier extensión de archivo que deseemos admitir en el futuro. Por ejemplo, en el futuro, si se solicita un archivo C, se lee en la memoria, el texto se compilará en WebAssembly y el WebAssembly se devolverá al cliente. Toda esta compilación se realiza del lado del servidor y está oculta al usuario. Para el usuario, es solo un servidor de archivos estáticos.