forked from TPReal/tp-vector
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathassets.ts
95 lines (89 loc) · 3.28 KB
/
assets.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/**
* An expression importing an asset module of type `A`, like this:
*
* import(`./my_module`)
* @see {@link asset}
*/
export type ModuleImport<A> = Promise<{default: A}>;
interface AssetLoaderFunc<A> {
(moduleImport: ModuleImport<A>): Promise<A>;
}
/**
* A helper function for loading assets of any type.
*
* Usage example:
* const importedValue = await assets.asset(import(`./asset_file`));
*
* __Explanation__: For this to work and type-check correctly, the following requirements
* must be met:
* - The TS compiler should treat this as a dynamic import, so that it doesn't check the imported
* file. For this reason, the asset file name is surrounded by backticks and not quotes.
* In TS 4.9 this is treated as a dynamic import.
* - The build/bundle tool should treat this as a static import, so that it knows which file
* is referenced, and can make it accessible at runtime. For this reason, the import function
* needs to be called at the call-site (as opposed to passing just the asset file name to the
* asset function). In esbuild 0.17 this is treated as a static import, even with the backticks.
* - The build/bundle tool needs to be configured to make the asset file available at runtime.
* In esbuild there are various loaders available for this, notably for:
* - text files:
* [text](https://esbuild.github.io/content-types/#text)
* - binary files:
* [binary](https://esbuild.github.io/content-types/#binary)
* or
* [base64](https://esbuild.github.io/content-types/#base64)
* - JSON files:
* [json](https://esbuild.github.io/content-types/#json)
* or
* [copy](https://esbuild.github.io/content-types/#copy)
* - any files accessed by URL:
* [dataurl](https://esbuild.github.io/content-types/#dataurl)
* or
* [file](https://esbuild.github.io/content-types/#file)
*
* See also the typed versions of the asset function below.
* @see https://esbuild.github.io/content-types/
*/
export async function asset<A>(moduleImport: ModuleImport<A>) {
return (await moduleImport).default;
}
/**
* Usage:
*
* const myText = await assets.text(import(`./my_text.txt`));
*
* The appropriate esbuild CLI param: `--loader:.txt=text`
* @see {@link asset}
*/
export const text: AssetLoaderFunc<string> = asset;
/**
* Usage:
*
* const myData = await assets.binary(import(`./my_data.data`));
*
* The appropriate esbuild CLI param: `--loader:.data=binary`
* @see {@link asset}
*/
export const binary: AssetLoaderFunc<Uint8Array> = asset;
/**
* Usage:
*
* const myDataBase64 = await assets.base64(import(`./my_data.data`));
*
* The appropriate esbuild CLI param: `--loader:.data=base64`
* @see {@link asset}
*/
export const base64: AssetLoaderFunc<string> = asset;
/**
* Usage examples:
*
* const urlOfMyImage = await assets.url(import(`./my_image.png`));
* const urlOfMyFont = await assets.url(import(`./fonts/my_font.woff2`));
*
* The appropriate esbuild CLI params:
* - To embed the assets as data URIs:
* `--loader:.png=dataurl --loader:.woff2=dataurl`
* - To obtain relative URLs and serve the asset files along with the code:
* `--loader:.png=file --loader:.woff2=file`
* @see {@link asset}
*/
export const url: AssetLoaderFunc<string> = asset;