Server web dev yang memungkinkan Anda mengimpor apa pun*
* Jika dengan apa pun yang Anda maksud: JavaScript ES2015+, TypeScript, JSON, JSX, TSX, Assemblyscript, Rust, C, C ++, WebAssembly, dan di masa depan apa pun yang dikompilasi untuk JavaScript atau WebAssembly.
Zwitterion dirancang untuk menjadi pengganti instan untuk server file statis pengembangan web Anda saat ini.
Penyebaran produksi juga dimungkinkan melalui bangunan statis.
Misalnya, Anda dapat menulis hal -hal seperti berikut dan hanya berfungsi:
./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!' ;
}Sungguh, itu hanya berhasil.
Zwitterion memungkinkan Anda kembali ke masa lalu yang indah dalam pengembangan web.
Cukup tulis kode sumber Anda dalam bahasa apa pun yang didukung dan jalankan di browser.
Juga ... zwitterion bukan bundler. Ini menghindari bundling untuk pengalaman yang lebih sederhana.
import * as stuff from 'library'; bukannya import * as stuff from '../node_modules/library/index.js'; )index.html pada rute yang tidak ditangani)Instal zwitterion di direktori yang ingin Anda sajikan file dari:
npm install zwitterionJalankan Zwitterion dengan mengaksesnya dapat dieksekusi langsung dari terminal:
node_modules/.bin/zwitterion
atau dari skrip NPM:
{
...
"scripts": {
"start": "zwitterion"
}
...
}
Instal Zwitterion secara global untuk digunakan di seluruh proyek:
npm install -g zwitterionJalankan zwitterion dari terminal:
zwitterionatau dari skrip NPM:
{
...
"scripts": {
"start": "zwitterion"
}
...
}
Disarankan untuk menggunakan zwitterion dalam produksi dengan membuat bangunan statis dari proyek Anda. Bangunan statis pada dasarnya menjalankan semua file yang relevan melalui Zwitterion, dan menyalinnya dan semua file lain dalam proyek Anda ke direktori dist . Anda dapat mengambil direktori ini dan mengunggahnya ke jaringan pengiriman konten (CDN), atau layanan hosting file statis lainnya.
Anda juga dapat menggunakan server Zwitterion yang sedang berjalan dalam produksi, tetapi untuk kinerja dan alasan keamanan potensial tidak disarankan.
Untuk membuat build statis, jalankan Zwitterion dengan opsi --build-static . Anda mungkin perlu menambahkan jenis application/javascript mime ke penyedia hosting Anda untuk file naskah, rakitan, karat, wasm, dan file wat Anda.
Dari terminal:
zwitterion --build-staticDari skrip NPM:
{
...
" scripts " : {
" build-static " : " zwitterion --build-static "
}
...
} Bangunan statis akan ditempatkan di direktori yang disebut dist , di direktori yang sama dengan yang Anda jalankan dari perintah --build-static .
JavaScript adalah bahasa web. Anda dapat mempelajari lebih lanjut di sini.
Mengimpor JavaScript ES2015+ langsung dan berfungsi seperti yang diharapkan. Cukup gunakan pernyataan impor dan ekspor tanpa modifikasi apa pun. Disarankan untuk menggunakan ekstensi file eksplisit:
./app.js :
import { helloWorld } from './hello-world.js' ;
console . log ( helloWorld ( ) ) ; ./hello-world.js :
export function helloWorld ( ) {
return 'Hello world!' ;
} Transpilasi JavaScript dilakukan oleh kompiler TypeScript. Secara default, compilerOptions kompiler TypeScript diatur ke yang berikut:
{
"module" : " ES2015 " ,
"target" : " ES2015 "
} Anda dapat mengganti opsi ini dengan membuat file .json dengan compilerOptions Anda sendiri dan memberi tahu Zwitterion di mana menemukannya dengan opsi baris perintah --tsc-options-file . Opsi yang tersedia dapat ditemukan di sini. Opsi ditentukan sebagai objek JSON. Misalnya:
tsc-options.json :
{
"target" : " ES5 "
}Tell Zwitterion di mana menemukannya:
zwitterion --tsc-options-file tsc-options.jsonTypescript adalah superset JavaScript yang diketik. Anda dapat mempelajari lebih lanjut di sini.
Mengimpor naskah langsung dan berfungsi seperti yang diharapkan. Cukup gunakan pernyataan impor dan ekspor tanpa modifikasi apa pun. Disarankan untuk menggunakan ekstensi file eksplisit:
./app.ts :
import { helloWorld } from './hello-world.ts' ;
console . log ( helloWorld ( ) ) ; ./hello-world.ts :
export function helloWorld ( ) : string {
return 'Hello world!' ;
} Secara default, compilerOptions kompiler TypeScript diatur ke yang berikut:
{
"module" : " ES2015 " ,
"target" : " ES2015 "
} Anda dapat mengganti opsi ini dengan membuat file .json dengan compilerOptions Anda sendiri dan memberi tahu Zwitterion di mana menemukannya dengan opsi baris perintah --tsc-options-file . Opsi yang tersedia dapat ditemukan di sini. Opsi ditentukan sebagai objek JSON. Misalnya:
tsc-options.json :
{
"target" : " ES5 "
}Tell Zwitterion di mana menemukannya:
zwitterion --tsc-options-file tsc-options.jsonJSON disediakan sebagai ekspor default. Disarankan untuk menggunakan ekstensi file eksplisit:
./app.js :
import helloWorld from './hello-world.json' ;
console . log ( helloWorld ) ; ./hello-world.json :
{
"hello" : " world "
}Mengimpor JSX mudah dan berfungsi seperti yang diharapkan. Cukup gunakan pernyataan impor dan ekspor tanpa modifikasi apa pun. Disarankan untuk menggunakan ekstensi file eksplisit:
./app.js :
import { helloWorldElement } from './hello-world.jsx' ;
ReactDOM . render (
helloWorldElement ,
document . getElementById ( 'root' )
) ; ./hello-world.jsx :
export const hellowWorldElement = < h1 > Hello, world! </ h1 > ; Transpilasi JSX dilakukan oleh kompiler TypeScript. Secara default, compilerOptions kompiler TypeScript diatur ke yang berikut:
{
"module" : " ES2015 " ,
"target" : " ES2015 "
} Anda dapat mengganti opsi ini dengan membuat file .json dengan compilerOptions Anda sendiri dan memberi tahu Zwitterion di mana menemukannya dengan opsi baris perintah --tsc-options-file . Opsi yang tersedia dapat ditemukan di sini. Opsi ditentukan sebagai objek JSON. Misalnya:
tsc-options.json :
{
"target" : " ES5 "
}Tell Zwitterion di mana menemukannya:
zwitterion --tsc-options-file tsc-options.jsonMengimpor TSX mudah dan berfungsi seperti yang diharapkan. Cukup gunakan pernyataan impor dan ekspor tanpa modifikasi apa pun. Disarankan untuk menggunakan ekstensi file eksplisit:
./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 > ; Transpilasi TSX dilakukan oleh kompiler TypeScript. Secara default, compilerOptions kompiler TypeScript diatur ke yang berikut:
{
"module" : " ES2015 " ,
"target" : " ES2015 "
} Anda dapat mengganti opsi ini dengan membuat file .json dengan compilerOptions Anda sendiri dan memberi tahu Zwitterion di mana menemukannya dengan opsi baris perintah --tsc-options-file . Opsi yang tersedia dapat ditemukan di sini. Opsi ditentukan sebagai objek JSON. Misalnya:
tsc-options.json :
{
"target" : " ES5 "
}Tell Zwitterion di mana menemukannya:
zwitterion --tsc-options-file tsc-options.jsonAssemblyScript adalah bahasa baru yang menyusun subset yang ketat dari naskah ke WebAssembly. Anda dapat mempelajari lebih lanjut tentang hal itu dalam buku assemblyscript.
Zwitterion mengasumsikan bahwa file perakitan memiliki ekstensi file .as . Ini adalah pilihan ekstensi khusus Zwitterion, karena proyek perakitan belum memilih ekstensi file resminya sendiri. Anda dapat mengikuti diskusi itu di sini. Zwitterion akan mengikuti pilihan ekstensi resmi setelah dibuat.
Mengimpor rakitan hampir identik dengan mengimpor JavaScript atau naskah. Perbedaan utama adalah bahwa ekspor default modul rakitan entri Anda adalah fungsi yang mengembalikan janji. Fungsi ini dianggap sebagai satu parameter objek yang berisi impor ke modul rakitan.
Nilai yang lewat ke dan dari fungsi yang diekspor dari modul rakitan harus langsung, tetapi ada beberapa keterbatasan. Zwitterion menggunakan sebagai pengikat di bawah kap untuk broker nilai ke dan dari modul rakitan. Lihatlah di sana jika Anda membutuhkan informasi lebih lanjut.
Anda dapat mengimpor AssemblyScript dari file JavaScript atau TypeScript seperti ini:
./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 ;
}Jika Anda ingin lulus impor dari luar lingkungan perakitan, Anda membuat file dengan deklarasi ekspor yang mendefinisikan jenis impor. Anda kemudian meneruskan impor Anda sebagai objek ke fungsi Init modul rakitan. Nama properti yang mendefinisikan impor Anda untuk suatu modul harus menjadi nama file yang tepat dari file yang mengekspor deklarasi impor. Misalnya:
./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 ;
}Anda juga dapat mengimpor AssemblyScript dari dalam file rakitan, seperti itu:
./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 ;
} Secara default, tidak ada opsi kompiler yang telah ditetapkan. Opsi yang tersedia dapat ditemukan di sini. Anda dapat menambahkan opsi dengan membuat file .json dengan array nama dan nilai opsi, dan memberi tahu Zwitterion di mana untuk menemukannya dengan opsi baris perintah --asc-options-file . Misalnya:
./asc-options.json :
[
" --optimizeLevel " , " 3 " ,
" --runtime " , " none " ,
" --shrinkLevel " , " 2 "
]Tell Zwitterion di mana menemukannya:
zwitterion --asc-options-file asc-options.jsonRust adalah bahasa tingkat rendah yang berfokus pada kinerja, keandalan, dan produktivitas. Pelajari lebih lanjut di sini.
Dukungan karat saat ini sangat mendasar (yaitu dukungan wasm-bindgen). Anda harus memasang karat di mesin Anda. Anda dapat menemukan instruksi untuk memasang karat di sini. Ini adalah tujuan Zwitterion untuk secara otomatis menginstal versi lokal dari perkakas karat yang diperlukan ketika zwitterion diinstal, tetapi saat ini merupakan pekerjaan yang sedang berlangsung.
Mengimpor karat hampir identik dengan mengimpor JavaScript atau naskah. Perbedaan utama adalah bahwa ekspor default modul karat entri Anda adalah fungsi yang mengembalikan janji. Fungsi ini dianggap sebagai satu parameter objek yang berisi impor ke modul karat. Anda dapat mengimpor karat dari file javascript atau naskah seperti ini:
./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 ;
}Dukungan C saat ini sangat mendasar. Anda harus menginstal Emscripten di mesin Anda. Anda dapat menemukan instruksi untuk menginstal Emscripten di sini. Ini adalah tujuan Zwitterion untuk secara otomatis menginstal versi lokal dari alat C yang diperlukan ketika zwitterion diinstal, tetapi saat ini merupakan pekerjaan yang sedang berlangsung.
Mengimpor C hampir identik dengan mengimpor JavaScript atau naskah. Perbedaan utama adalah bahwa ekspor default modul entri C Anda adalah fungsi yang mengembalikan janji. Fungsi ini dianggap sebagai satu parameter objek yang berisi impor ke modul C. Anda dapat mengimpor C dari file JavaScript atau TypeScript seperti ini:
./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 ;
}Dukungan C ++ saat ini sangat mendasar. Anda harus menginstal Emscripten di mesin Anda. Anda dapat menemukan instruksi untuk menginstal Emscripten di sini. Ini adalah tujuan Zwitterion untuk secara otomatis menginstal versi lokal dari alat C ++ yang diperlukan saat zwitterion diinstal, tetapi saat ini merupakan pekerjaan yang sedang berlangsung.
Mengimpor C ++ hampir identik dengan mengimpor JavaScript atau TypeScript. Perbedaan utama adalah bahwa ekspor default modul entri C ++ Anda adalah fungsi yang mengembalikan janji. Fungsi ini dianggap sebagai satu parameter objek yang berisi impor ke modul C ++. Anda dapat mengimpor C ++ dari file JavaScript atau TypeScript seperti ini:
./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 adalah representasi tekstual dari format biner WASM. Ini memungkinkan WASM untuk lebih mudah ditulis dengan tangan. Pelajari lebih lanjut di sini.
Mengimpor WAT hampir identik dengan mengimpor JavaScript atau naskah. Perbedaan utama adalah bahwa ekspor default modul entri Anda adalah fungsi yang mengembalikan janji. Fungsi ini dianggap sebagai satu parameter objek yang berisi impor ke modul WAT. Anda dapat mengimpor WAT dari file JavaScript atau TypeScript seperti ini:
./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 adalah format instruksi biner yang dibangun untuk efisien, aman, portabel, dan terbuka. Pelajari lebih lanjut di sini.
Mengimpor WASM hampir identik dengan mengimpor JavaScript atau naskah. Perbedaan utama adalah bahwa ekspor default modul Wasm Entri Anda adalah fungsi yang mengembalikan janji. Fungsi ini dianggap sebagai satu parameter objek yang berisi impor ke modul WASM. Anda dapat mengimpor WASM dari file JavaScript atau TypeScript seperti ini:
./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`
Tentukan port server:
--port [port]Buat build statis dari direktori kerja saat ini. Output akan berada di direktori yang disebut dist di direktori kerja saat ini:
--build-staticDaftar jalur yang dipisahkan secara koma, relatif terhadap direktori saat ini, untuk mengecualikan dari bangunan statis:
--exclude [exclude]Daftar jalur yang dipisahkan secara koma, relatif terhadap direktori saat ini, untuk dimasukkan dalam bangunan statis
--include [include]Jalur ke file, relatif terhadap direktori saat ini, untuk berfungsi sebagai root spa. Itu akan dikembalikan untuk jalur root dan ketika file tidak dapat ditemukan:
--spa-root [spaRoot]Nonaktifkan Spa Redirect ke Index.html:
--disable-spaJalur ke file JSON, relatif terhadap direktori saat ini, untuk header http khusus:
--headers-file [headersFile]Header HTTP khusus ditentukan sebagai objek JSON dengan bentuk berikut:
type CustomHTTPHeaders = {
[ regexp : string ] : HTTPHeaders ;
}
type HTTPHeaders = {
[ key : string ] : string ;
}Misalnya:
./headers.json
{
"^service-worker.ts$" : {
"Service-Worker-Allowed" : " / "
}
}Jalur ke file JSON, relatif terhadap direktori saat ini, untuk opsi kompiler TSC:
--tsc-options-file [tscOptionsFile]Opsi yang tersedia dapat ditemukan di sini. Opsi ditentukan sebagai objek JSON. Misalnya:
tsc-options.json :
{
"target" : " ES5 "
}Jalur ke file JSON, relatif terhadap direktori saat ini, untuk opsi kompiler ASC:
--asc-options-file [ascOptionsFile]Secara default, tidak ada opsi kompiler yang telah ditetapkan. Opsi yang tersedia dapat ditemukan di sini. Opsi ditentukan sebagai array nama dan nilai opsi. Misalnya:
./asc-options.json :
[
" --optimizeLevel " , " 3 " ,
" --runtime " , " none " ,
" --shrinkLevel " , " 2 "
]Paket pihak ketiga harus ditulis seolah-olah mereka menggunakan Zwitterion. Pada dasarnya ini berarti mereka harus ditulis dalam JavaScript atau naskah standar, dan AssemblyScript, Rust, C, dan C ++ harus ditulis sesuai dengan dokumentasi WebAssembly mereka. Pengecualian penting akan dijelaskan dalam dokumentasi ini. CommonJS (sintaksis yang membutuhkan), JSON, HTML, atau Impor Modul CSS ES, dan fitur-fitur non-standar lainnya yang biasanya didukung oleh bundler tidak disimpan dalam kode sumber.
Penting untuk dicatat bahwa Zwitterion mengasumsikan bahwa file root (file yang ditemukan di / ) dari aplikasi web Anda selalu merupakan file index.html .
Zwitterion tergantung pada dukungan browser asli untuk modul ES (sintaks impor/ekspor). Anda harus menambahkan atribut type="module" ke elemen skrip yang modul referensi, misalnya:
<script type="module" src="amazing-module.ts"></script>
Penting untuk dicatat bahwa Zwitterion tidak menggabungkan file atau terlibat dalam pengocok pohon. Ini dapat memengaruhi kinerja aplikasi Anda. Modul HTTP2 dan ES dapat membantu kinerja, tetapi pada titik ini tanda -tanda waktu cenderung mengarah ke kinerja yang lebih buruk. Zwitterion memiliki rencana untuk meningkatkan kinerja dengan secara otomatis menghasilkan informasi dorong server HTTP2 dari build statis, dan melihat ke pohon bergetar, tetapi tidak jelas apa yang mempengaruhi hal ini. Nantikan informasi lebih lanjut tentang kinerja saat Zwitterion matang.
Dengan semua yang di atas dikatakan, implikasi kinerja tidak jelas. Ukur untuk diri sendiri.
Baca berikut untuk informasi lebih lanjut tentang bundling versus tidak bundling dengan http2:
Zwitterion sederhana. Ini kurang lebih merupakan server file statis, tetapi menulis ulang file yang diminta dalam memori yang diperlukan untuk kembali ke klien. Misalnya, jika file TypeScript diminta dari klien, Zwitterion akan mengambil teks file, mengkompilasi ke JavaScript, dan kemudian mengembalikan teks yang dikompilasi ke klien. Hal yang sama dilakukan untuk file JavaScript. Bahkan, hampir proses yang sama akan digunakan untuk ekstensi file apa pun yang ingin kami dukung di masa depan. Misalnya, di masa depan, jika file C diminta, itu akan dibaca ke dalam memori, teks akan dikompilasi ke WebAssembly, dan WebAssembly akan dikembalikan ke klien. Semua kompilasi ini dilakukan di sisi server dan disembunyikan dari pengguna. Untuk pengguna, itu hanya server file statis.