Flazzo memiliki fokus utama untuk menambah nilai bisnis Anda.

Blog

Salah satu cara untuk mempercepat kompilasi TypeScript

esBw00PiB6koFEvH6k0gKi6jtMaZftvvCeBx3hI1.jpg
Blog

Salah satu cara untuk mempercepat kompilasi TypeScript


Data sumber: Mengkompilasi proyek NodeJS menghabiskan hampir 2 GB memori. Ini tidak mengganggu saya di komputer kerja saya, tetapi di laptop saya, saya secara berkala mengalami kesalahan OutOfMemory yang parah.

Saya mulai meneliti mengapa proyek sekecil itu memakan begitu banyak memori. Segera saya menemukan opsi yang tidak saya ketahui sebelum kompiler sc --listFiles di Google, yang mencantumkan file yang digunakan: ada 4500! Terlalu banyak. Sekilas daftar menunjukkan bahwa file yang paling banyak digunakan berasal dari perpustakaan: googleapis, @hubspot, @redis-client. Saya menyimpan daftar ke file dengan perintah npx tsc --listFiles > .files.ls dan mulai mengukur:

cat .files.ls | grep redis | wc -l     491
cat .files.ls | grep google | wc -l   907
cat .files.ls | grep hubspot | wc -l   1682

hubspot

Pustaka menyediakan metode untuk mengakses API layanan ini. Ada banyak metode, tetapi kami hanya menggunakan 6. Saya membuat file hubspot.js dengan satu baris: export {Client} from "@hubspot/api-client"; dan tulis impor kembali ke file ini. Hebat, saya menyingkirkan seribu setengah file! Tapi tanpa mengetik, Anda bisa membuat banyak kesalahan. Jadi saya menambahkan file hubspot.d.ts selanjutnya, di mana saya menentukan jenis hanya untuk API yang diperlukan.

import {IHttpOptions} from "@hubspot/api-client/lib/src/services/http/IHttpOptions";
import IConfiguration from "@hubspot/api-client/lib/src/configuration/IConfiguration";
import {PromisePipelinesApi} from "@hubspot/api-client/lib/codegen/crm/pipelines/types/PromiseAPI";
import {PromiseCoreApi} from "@hubspot/api-client/lib/codegen/crm/properties/types/PromiseAPI";
import {PromiseSearchApi} from "@hubspot/api-client/lib/codegen/crm/contacts/types/PromiseAPI";

export declare class Client {
    constructor(config?: IConfiguration);
    apiRequest(opts?: IHttpOptions): Promise<import("node-fetch").Response>;
    crm: {
        deals: {
            searchApi: PromiseSearchApi
        };
        contacts: {
            searchApi: PromiseSearchApi
        };
        properties: {
            coreApi: PromiseCoreApi;
        };
        pipelines: {
            pipelinesApi: PromisePipelinesApi;
        };
    }
}

Verifikasi:

Kami memeriksa dengan perintah npx tsc --listFiles | grep hubspot | wc -l dan dapatkan hasil dari 112. Cukup baik.

Google

Google juga menyediakan API untuk layanan mereka, yang menurut saya lebih dari sekadar Hubspot. Tetapi perpustakaan Google lebih bijaksana dan memungkinkan Anda mengimpor setiap layanan secara terpisah:

Alih-alih:

import { google } from 'googleapis';
google.cloudresourcemanager('v1')...

Kita harus menulis:

import { cloudresourcemanager } from 'googleapis/build/src/apis/cloudresourcemanager'
cloudresourcemanager('v1')...

Pengurangan ukuran paket

Ini adalah cara yang terkenal untuk mengurangi ukuran bundel, tetapi di backend orang biasanya tidak mempedulikannya, sedangkan di frontend, bundler dapat menghapus file yang tidak terpakai dari bundel. Verifikasi: npx tsc --listFiles | grep google | wc -l memberi kita 288.

Katakan lagi

Hampir 500 file, wow! Saya mungkin tidak tahu banyak tentang kemampuan luar biasa dari database ini. Saya mulai belajar mengetik @redis/client dan cepat bingung karena begitu canggih. Saya dapat mengambil perpustakaan lain, tetapi saya tidak tahu jebakan apa yang akan terjadi. Sebagai gantinya, saya hanya menyalin pengetikan dari metode yang digunakan dan menyederhanakannya sedikit, menghilangkan kemampuan untuk menggunakan Buffer alih-alih string:

export type RedisClientType = {
    on(type: 'error', cb: (err: Error) => void | any);
    on(type: 'end', cb: (err: any) => void | any);
    connect(): Promise<void>;
    set(key: string, value: string | number, options?: SetOptions): Promise<boolean>;
    del(keys: string | Array<string>): Promise<void>;
    get(key: string): Promise<string>;
    publish(channel: string, message: string): Promise<void>;
    subscribe: (channels: string | Array<string>, listener:  (message: string) => unknown) => Promise<void>;
}

export declare function createClient(config: {
    url: string;
    password: string;
}): RedisClientType;

declare type MaximumOneOf<T, K extends keyof T = keyof T> = K extends keyof T ? {
    [P in K]?: T[K];
} & Partial<Record<Exclude<keyof T, K>, never>> : never;
declare type SetTTL = MaximumOneOf<{
    EX: number;
    PX: number;
    EXAT: number;
    PXAT: number;
    KEEPTTL: true;
}>;
declare type SetGuards = MaximumOneOf<{
    NX: true;
    XX: true;
}>;
interface SetCommonOptions {
    GET?: true;
}
export declare type SetOptions = SetTTL & SetGuards & SetCommonOptions;

Kesimpulan

Jumlah file yang digunakan telah berkurang dari 4576 menjadi 1397, konsumsi memori telah dikurangi setengahnya menjadi 1 GB, dan waktu kompilasi di laptop telah berkurang secara signifikan. Perubahan hanya memengaruhi 24 file dalam proyek, jadi tinjauan kode akan langsung dilakukan.

Beberapa pustaka memungkinkan Anda mengimpor bagian terpisah – gunakan meskipun ukuran bundel tidak penting bagi Anda. Untuk perpustakaan lain, tipe terpisah dapat digunakan untuk mempercepat kompilasi. Sayangnya, masih ada perpustakaan populer yang pengetikannya sangat buruk sehingga lebih baik tidak memilikinya. Saat memilih rak buku, ada baiknya memperhatikannya.

Manfaat utama yang saya lihat adalah kemampuan untuk tidak mengkhawatirkan OutOfMemory di laptop, dan membiarkan semua mesin bekerja sedikit lebih sedikit, mudah-mudahan mereka akan mengampuni saya untuk itu selama peningkatan.

Jika Anda menemukan kesalahan dalam teks, kirimkan pesan ke penulis dengan menyorot kesalahan dan menekan Ctrl-Enter.