isomorfeus-asset-manager 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +12 -0
  4. data/lib/iso_opal.rb +10 -0
  5. data/lib/isomorfeus/asset_manager/asset.rb +67 -0
  6. data/lib/isomorfeus/asset_manager/config.rb +69 -0
  7. data/lib/isomorfeus/asset_manager/js_import.rb +59 -0
  8. data/lib/isomorfeus/asset_manager/portfolio.rb +46 -0
  9. data/lib/isomorfeus/asset_manager/rack_middleware.rb +85 -0
  10. data/lib/isomorfeus/asset_manager/ruby_import.rb +33 -0
  11. data/lib/isomorfeus/asset_manager/server_socket_processor.rb +55 -0
  12. data/lib/isomorfeus/asset_manager/version.rb +5 -0
  13. data/lib/isomorfeus/asset_manager/view_helper.rb +9 -0
  14. data/lib/isomorfeus/asset_manager.rb +145 -0
  15. data/lib/isomorfeus-asset-manager.rb +27 -0
  16. data/node_modules/.bin/esbuild +12 -0
  17. data/node_modules/.bin/esbuild.cmd +17 -0
  18. data/node_modules/.bin/esbuild.ps1 +28 -0
  19. data/node_modules/.package-lock.json +18 -0
  20. data/node_modules/esbuild-wasm/README.md +3 -0
  21. data/node_modules/esbuild-wasm/bin/esbuild +84 -0
  22. data/node_modules/esbuild-wasm/esbuild.wasm +0 -0
  23. data/node_modules/esbuild-wasm/esm/browser.d.ts +397 -0
  24. data/node_modules/esbuild-wasm/esm/browser.js +2341 -0
  25. data/node_modules/esbuild-wasm/esm/browser.min.js +8 -0
  26. data/node_modules/esbuild-wasm/exit0.js +11 -0
  27. data/node_modules/esbuild-wasm/lib/browser.d.ts +397 -0
  28. data/node_modules/esbuild-wasm/lib/browser.js +2371 -0
  29. data/node_modules/esbuild-wasm/lib/browser.min.js +10 -0
  30. data/node_modules/esbuild-wasm/lib/main.d.ts +397 -0
  31. data/node_modules/esbuild-wasm/lib/main.js +1948 -0
  32. data/node_modules/esbuild-wasm/package.json +16 -0
  33. data/node_modules/esbuild-wasm/wasm_exec.js +654 -0
  34. data/package.json +9 -0
  35. metadata +162 -0
@@ -0,0 +1,5 @@
1
+ module Isomorfeus
2
+ class AssetManager
3
+ VERSION = '0.12.0'
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ module Isomorfeus
2
+ class AssetManager
3
+ module ViewHelper
4
+ def script_tag(path)
5
+ "<script type=\"application/javascript\" src=\"#{Isomorfeus.assets_path}/#{path}\"></script>"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,145 @@
1
+ module Isomorfeus
2
+ class AssetManager
3
+ def self.finalize(tmpdir)
4
+ proc { FileUtils.rm_rf(tmpdir) }
5
+ end
6
+
7
+ def initialize
8
+ Isomorfeus.set_node_paths
9
+
10
+ @tmpdir = Dir.mktmpdir
11
+ @imports_path = File.join(@tmpdir, 'imports')
12
+ @output_path = File.join(@tmpdir, 'output')
13
+ FileUtils.mkdir_p(@imports_path)
14
+ FileUtils.mkdir_p(@output_path)
15
+
16
+ @context = ExecJS.permissive_compile(init_js)
17
+
18
+ imports_path = File.expand_path(File.join(Isomorfeus.app_root, 'imports'))
19
+ if Dir.exist?(imports_path)
20
+ common_imports_file = File.join(imports_path, 'common.js')
21
+ Isomorfeus.add_common_js_import(common_imports_file) if File.exist?(common_imports_file)
22
+ web_imports_file = File.join(imports_path, 'web.js')
23
+ Isomorfeus.add_web_js_import(web_imports_file) if File.exist?(web_imports_file)
24
+ ssr_imports_file = File.join(imports_path, 'ssr.js')
25
+ Isomorfeus.add_ssr_js_import(ssr_imports_file) if File.exist?(ssr_imports_file)
26
+ end
27
+
28
+ ObjectSpace.define_finalizer(self, self.class.finalize(@tmpdir))
29
+ end
30
+
31
+ def transition(asset_key, asset)
32
+ return if !Isomorfeus.development? && asset.bundled?
33
+ compile_ruby_and_save(asset_key, asset)
34
+ save_imports(asset_key, asset)
35
+ run_esbuild(asset_key, asset)
36
+ asset.bundle = bundled_asset(asset_key)
37
+ if !Isomorfeus.production? && asset.target != :node
38
+ asset.bundle_map = bundled_asset_map(asset_key)
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def bundled_asset(asset_key)
45
+ File.read(File.join(@output_path, asset_key))
46
+ end
47
+
48
+ def bundled_asset_map(asset_key)
49
+ File.read(File.join(@output_path, asset_key + '.map'))
50
+ end
51
+
52
+ def save_imports(asset_key, asset)
53
+ File.write(File.join(@imports_path, asset_key), asset.to_s)
54
+ end
55
+
56
+ def compile_ruby_and_save(asset_key, asset)
57
+ asset.ruby_imports.each do |ruby_import|
58
+ result = Opal::Builder.build(ruby_import.resolved_path, { es6_wrap: true })
59
+ FileUtils.mkdir_p(File.join(*[@imports_path].concat(ruby_import.module_name.split('/')[0...-1]))) if ruby_import.module_name.include?('/')
60
+ js = result.to_s
61
+ if !Isomorfeus.production? && asset.target != :node
62
+ js_map_path = File.join(@imports_path, ruby_import.module_name + '.js.map')
63
+ js << "\n//# sourceMappingURL=file://#{js_map_path}\n"
64
+ File.write(js_map_path, result.source_map)
65
+ end
66
+ File.write(File.join(@imports_path, ruby_import.module_name + '.js'), js)
67
+ end
68
+ end
69
+
70
+ def print_message(m, level)
71
+ l = m['location']
72
+ STDERR.puts "#{l['file']}:#{l['line']}:#{l['column']}: #{level}: #{m['text']}"
73
+ STDERR.puts " #{l['line']} | #{l['lineText']}\n\n"
74
+ end
75
+
76
+ def handle_errors(asset_key, result)
77
+ # Todo simplify
78
+ unless result['warnings'].empty?
79
+ result['warnings'].each do |w|
80
+ print_message(w, 'warning')
81
+ unless w['notes'].empty?
82
+ w['notes'].each do |n|
83
+ print_message(n, 'note')
84
+ end
85
+ end
86
+ end
87
+ end
88
+ unless result['errors'].empty?
89
+ result['errors'].each do |e|
90
+ print_message(w, 'error')
91
+ unless w['notes'].empty?
92
+ e['notes'].each do |n|
93
+ print_message(n, 'note')
94
+ end
95
+ end
96
+ end
97
+ raise "Aseet Manager: error bundling '#{asset_key}'"
98
+ end
99
+ end
100
+
101
+ def init_js
102
+ <<~JAVASCRIPT
103
+ 'use strict';
104
+ const path = require('path');
105
+ var esbuild_r;
106
+ try { esbuild_r = require('esbuild'); }
107
+ catch { esbuild_r = require('esbuild-wasm'); }
108
+ const esbuild = esbuild_r;
109
+ global.imports_path = '#{@imports_path}';
110
+ global.output_path = '#{@output_path}';
111
+ JAVASCRIPT
112
+ end
113
+
114
+ # possible future improvement
115
+ # loader: {
116
+ # '.png': 'dataurl',
117
+ # '.svg': 'text',
118
+ # },
119
+ def run_esbuild(asset_key, asset)
120
+ resolve_paths = ENV['NODE_PATH'].split(Gem.win_platform? ? ';' : ':')
121
+ resolve_paths << 'node_modules'
122
+ resolve_paths.uniq!
123
+
124
+ result = @context.exec <<~JAVASCRIPT
125
+ return esbuild.buildSync({
126
+ entryPoints: [path.resolve(global.imports_path, '#{asset_key}')],
127
+ bundle: true,
128
+ color: false,
129
+ format: '#{asset.target == :node ? 'cjs' : 'iife'}',
130
+ legalComments: 'linked',
131
+ minify: #{Isomorfeus.production? ? 'true' : 'false'},
132
+ nodePaths: #{resolve_paths},
133
+ outdir: global.output_path,
134
+ platform: '#{asset.target}',
135
+ publicPath: '/assets',
136
+ sourcemap: #{(!Isomorfeus.production? && asset.target != :node) ? 'true' : 'false'},
137
+ splitting: false,
138
+ target: 'es6',
139
+ write: true
140
+ });
141
+ JAVASCRIPT
142
+ handle_errors(asset_key, result)
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,27 @@
1
+ require 'fileutils'
2
+ require 'tmpdir'
3
+ require 'zlib'
4
+ require 'opal'
5
+ require 'opal/builder'
6
+ require 'oj'
7
+ require 'rack'
8
+ require 'isomorfeus-speednode'
9
+ require 'isomorfeus/asset_manager/version'
10
+ require 'isomorfeus/asset_manager/js_import'
11
+ require 'isomorfeus/asset_manager/ruby_import'
12
+ require 'isomorfeus/asset_manager/asset'
13
+ require 'isomorfeus/asset_manager/portfolio'
14
+ require 'isomorfeus/asset_manager/rack_middleware'
15
+ require 'isomorfeus/asset_manager/server_socket_processor'
16
+ require 'isomorfeus/asset_manager'
17
+ require 'isomorfeus/asset_manager/config'
18
+ require 'isomorfeus/asset_manager/view_helper'
19
+ require 'iso_opal'
20
+
21
+ Isomorfeus.env = ENV['RACK_ENV']
22
+
23
+ Isomorfeus.node_paths << File.expand_path(File.join(File.dirname(__FILE__), '..', 'node_modules'))
24
+
25
+ Isomorfeus.root = File.expand_path('.')
26
+ Isomorfeus.app_root = File.expand_path('app')
27
+ Opal.append_path(Isomorfeus.app_root) unless IsoOpal.paths_include?(Isomorfeus.app_root)
@@ -0,0 +1,12 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
6
+ esac
7
+
8
+ if [ -x "$basedir/node" ]; then
9
+ exec "$basedir/node" "$basedir/../esbuild-wasm/bin/esbuild" "$@"
10
+ else
11
+ exec node "$basedir/../esbuild-wasm/bin/esbuild" "$@"
12
+ fi
@@ -0,0 +1,17 @@
1
+ @ECHO off
2
+ GOTO start
3
+ :find_dp0
4
+ SET dp0=%~dp0
5
+ EXIT /b
6
+ :start
7
+ SETLOCAL
8
+ CALL :find_dp0
9
+
10
+ IF EXIST "%dp0%\node.exe" (
11
+ SET "_prog=%dp0%\node.exe"
12
+ ) ELSE (
13
+ SET "_prog=node"
14
+ SET PATHEXT=%PATHEXT:;.JS;=;%
15
+ )
16
+
17
+ endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\esbuild-wasm\bin\esbuild" %*
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env pwsh
2
+ $basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
3
+
4
+ $exe=""
5
+ if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
6
+ # Fix case when both the Windows and Linux builds of Node
7
+ # are installed in the same directory
8
+ $exe=".exe"
9
+ }
10
+ $ret=0
11
+ if (Test-Path "$basedir/node$exe") {
12
+ # Support pipeline input
13
+ if ($MyInvocation.ExpectingInput) {
14
+ $input | & "$basedir/node$exe" "$basedir/../esbuild-wasm/bin/esbuild" $args
15
+ } else {
16
+ & "$basedir/node$exe" "$basedir/../esbuild-wasm/bin/esbuild" $args
17
+ }
18
+ $ret=$LASTEXITCODE
19
+ } else {
20
+ # Support pipeline input
21
+ if ($MyInvocation.ExpectingInput) {
22
+ $input | & "node$exe" "$basedir/../esbuild-wasm/bin/esbuild" $args
23
+ } else {
24
+ & "node$exe" "$basedir/../esbuild-wasm/bin/esbuild" $args
25
+ }
26
+ $ret=$LASTEXITCODE
27
+ }
28
+ exit $ret
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "isomorfeus-asset-manager",
3
+ "lockfileVersion": 2,
4
+ "requires": true,
5
+ "packages": {
6
+ "node_modules/esbuild-wasm": {
7
+ "version": "0.12.25",
8
+ "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.12.25.tgz",
9
+ "integrity": "sha512-/lgWzZ1O5sXEVHw2gEQpSnVFc5kOMXiloNRQ3rASX+7/dswSMhlZ2Fw/4t4wTjqyq3cO51Fr48y5Yc4u4r74Cg==",
10
+ "bin": {
11
+ "esbuild": "bin/esbuild"
12
+ },
13
+ "engines": {
14
+ "node": ">=8"
15
+ }
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,3 @@
1
+ # esbuild
2
+
3
+ This is the cross-platform WebAssembly binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild and the [JavaScript API documentation](https://esbuild.github.io/api/) for details.
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Forward to the automatically-generated WebAssembly loader from the Go compiler
4
+
5
+ const crypto = require('crypto');
6
+ const path = require('path');
7
+ const zlib = require('zlib');
8
+ const fs = require('fs');
9
+ const os = require('os');
10
+
11
+ const wasm_exec = path.join(__dirname, '..', 'wasm_exec.js');
12
+ const esbuild_wasm = path.join(__dirname, '..', 'esbuild.wasm');
13
+
14
+ const code = fs.readFileSync(wasm_exec, 'utf8');
15
+ const wrapper = new Function('require', 'module', 'process', 'WebAssembly', code);
16
+
17
+ function instantiate(bytes, importObject) {
18
+ // Using this API causes "./esbuild --version" to run around 1 second faster
19
+ // than using the "WebAssembly.instantiate()" API when run in node (v12.16.2)
20
+ const module = new WebAssembly.Module(bytes);
21
+ const instance = new WebAssembly.Instance(module, importObject);
22
+ return Promise.resolve({ instance, module });
23
+ }
24
+
25
+ // Node has an unfortunate bug where the node process is unnecessarily kept open while a
26
+ // WebAssembly module is being optimized: https://github.com/nodejs/node/issues/36616.
27
+ // This means cases where running "esbuild" should take a few milliseconds can end up
28
+ // taking many seconds instead. To work around this bug, it is possible to force node to
29
+ // exit by calling the operating system's exit function. That's what this code does.
30
+ process.on('exit', code => {
31
+ // If it's a non-zero exit code, we can just kill our own process to stop. This will
32
+ // preserve the fact that there is a non-zero exit code although the exit code will
33
+ // be different. We cannot use this if the exit code is supposed to be zero.
34
+ if (code !== 0) {
35
+ try {
36
+ process.kill(process.pid, 'SIGINT');
37
+ } catch (e) {
38
+ }
39
+ return;
40
+ }
41
+
42
+ // Otherwise if the exit code is zero, try to fall back to a binary N-API module that
43
+ // calls the operating system's "exit(0)" function.
44
+ const nativeModule = `${process.platform}-${os.arch()}-${os.endianness()}.node`;
45
+ const base64 = require('../exit0')[nativeModule];
46
+ if (base64) {
47
+ try {
48
+ const data = zlib.inflateRawSync(Buffer.from(base64, 'base64'));
49
+ const hash = crypto.createHash('sha256').update(base64).digest().toString('hex').slice(0, 16);
50
+ const tempFile = path.join(os.tmpdir(), `${hash}-${nativeModule}`);
51
+ try {
52
+ if (fs.readFileSync(tempFile).equals(data)) {
53
+ require(tempFile);
54
+ }
55
+ } finally {
56
+ fs.writeFileSync(tempFile, data);
57
+ require(tempFile);
58
+ }
59
+ } catch (e) {
60
+ }
61
+ }
62
+ });
63
+
64
+ // Node has another bug where using "fs.read" to read from stdin reads
65
+ // everything successfully and then throws an error, but only on Windows. Go's
66
+ // WebAssembly support uses "fs.read" so it hits this problem. This is a patch
67
+ // to try to work around the bug in node. This bug has been reported to node
68
+ // at least twice in https://github.com/nodejs/node/issues/35997 and in
69
+ // https://github.com/nodejs/node/issues/19831. This issue has also been
70
+ // reported to the Go project: https://github.com/golang/go/issues/43913.
71
+ const read = fs.read;
72
+ fs.read = function () {
73
+ const callback = arguments[5];
74
+ arguments[5] = function (err, count) {
75
+ if (count === 0 && err && err.code === 'EOF') {
76
+ arguments[0] = null;
77
+ }
78
+ return callback.apply(this, arguments);
79
+ };
80
+ return read.apply(this, arguments);
81
+ };
82
+
83
+ const argv = ['node', wasm_exec, esbuild_wasm].concat(process.argv.slice(2));
84
+ wrapper(require, require.main, Object.assign(Object.create(process), { argv }), Object.assign(Object.create(WebAssembly), { instantiate }));
@@ -0,0 +1,397 @@
1
+ export type Platform = 'browser' | 'node' | 'neutral';
2
+ export type Format = 'iife' | 'cjs' | 'esm';
3
+ export type Loader = 'js' | 'jsx' | 'ts' | 'tsx' | 'css' | 'json' | 'text' | 'base64' | 'file' | 'dataurl' | 'binary' | 'default';
4
+ export type LogLevel = 'verbose' | 'debug' | 'info' | 'warning' | 'error' | 'silent';
5
+ export type Charset = 'ascii' | 'utf8';
6
+ export type TreeShaking = true | 'ignore-annotations';
7
+
8
+ interface CommonOptions {
9
+ sourcemap?: boolean | 'inline' | 'external' | 'both';
10
+ legalComments?: 'none' | 'inline' | 'eof' | 'linked' | 'external';
11
+ sourceRoot?: string;
12
+ sourcesContent?: boolean;
13
+
14
+ format?: Format;
15
+ globalName?: string;
16
+ target?: string | string[];
17
+
18
+ minify?: boolean;
19
+ minifyWhitespace?: boolean;
20
+ minifyIdentifiers?: boolean;
21
+ minifySyntax?: boolean;
22
+ charset?: Charset;
23
+ treeShaking?: TreeShaking;
24
+
25
+ jsx?: 'transform' | 'preserve';
26
+ jsxFactory?: string;
27
+ jsxFragment?: string;
28
+
29
+ define?: { [key: string]: string };
30
+ pure?: string[];
31
+ keepNames?: boolean;
32
+
33
+ color?: boolean;
34
+ logLevel?: LogLevel;
35
+ logLimit?: number;
36
+ }
37
+
38
+ export interface BuildOptions extends CommonOptions {
39
+ bundle?: boolean;
40
+ splitting?: boolean;
41
+ preserveSymlinks?: boolean;
42
+ outfile?: string;
43
+ metafile?: boolean;
44
+ outdir?: string;
45
+ outbase?: string;
46
+ platform?: Platform;
47
+ external?: string[];
48
+ loader?: { [ext: string]: Loader };
49
+ resolveExtensions?: string[];
50
+ mainFields?: string[];
51
+ conditions?: string[];
52
+ write?: boolean;
53
+ allowOverwrite?: boolean;
54
+ tsconfig?: string;
55
+ outExtension?: { [ext: string]: string };
56
+ publicPath?: string;
57
+ entryNames?: string;
58
+ chunkNames?: string;
59
+ assetNames?: string;
60
+ inject?: string[];
61
+ banner?: { [type: string]: string };
62
+ footer?: { [type: string]: string };
63
+ incremental?: boolean;
64
+ entryPoints?: string[] | Record<string, string>;
65
+ stdin?: StdinOptions;
66
+ plugins?: Plugin[];
67
+ absWorkingDir?: string;
68
+ nodePaths?: string[]; // The "NODE_PATH" variable from Node.js
69
+ watch?: boolean | WatchMode;
70
+ }
71
+
72
+ export interface WatchMode {
73
+ onRebuild?: (error: BuildFailure | null, result: BuildResult | null) => void;
74
+ }
75
+
76
+ export interface StdinOptions {
77
+ contents: string;
78
+ resolveDir?: string;
79
+ sourcefile?: string;
80
+ loader?: Loader;
81
+ }
82
+
83
+ export interface Message {
84
+ pluginName: string;
85
+ text: string;
86
+ location: Location | null;
87
+ notes: Note[];
88
+
89
+ // Optional user-specified data that is passed through unmodified. You can
90
+ // use this to stash the original error, for example.
91
+ detail: any;
92
+ }
93
+
94
+ export interface Note {
95
+ text: string;
96
+ location: Location | null;
97
+ }
98
+
99
+ export interface Location {
100
+ file: string;
101
+ namespace: string;
102
+ line: number; // 1-based
103
+ column: number; // 0-based, in bytes
104
+ length: number; // in bytes
105
+ lineText: string;
106
+ suggestion: string;
107
+ }
108
+
109
+ export interface OutputFile {
110
+ path: string;
111
+ contents: Uint8Array; // "text" as bytes
112
+ text: string; // "contents" as text
113
+ }
114
+
115
+ export interface BuildInvalidate {
116
+ (): Promise<BuildIncremental>;
117
+ dispose(): void;
118
+ }
119
+
120
+ export interface BuildIncremental extends BuildResult {
121
+ rebuild: BuildInvalidate;
122
+ }
123
+
124
+ export interface BuildResult {
125
+ errors: Message[];
126
+ warnings: Message[];
127
+ outputFiles?: OutputFile[]; // Only when "write: false"
128
+ rebuild?: BuildInvalidate; // Only when "incremental: true"
129
+ stop?: () => void; // Only when "watch: true"
130
+ metafile?: Metafile; // Only when "metafile: true"
131
+ }
132
+
133
+ export interface BuildFailure extends Error {
134
+ errors: Message[];
135
+ warnings: Message[];
136
+ }
137
+
138
+ export interface ServeOptions {
139
+ port?: number;
140
+ host?: string;
141
+ servedir?: string;
142
+ onRequest?: (args: ServeOnRequestArgs) => void;
143
+ }
144
+
145
+ export interface ServeOnRequestArgs {
146
+ remoteAddress: string;
147
+ method: string;
148
+ path: string;
149
+ status: number;
150
+ timeInMS: number; // The time to generate the response, not to send it
151
+ }
152
+
153
+ export interface ServeResult {
154
+ port: number;
155
+ host: string;
156
+ wait: Promise<void>;
157
+ stop: () => void;
158
+ }
159
+
160
+ export interface TransformOptions extends CommonOptions {
161
+ tsconfigRaw?: string | {
162
+ compilerOptions?: {
163
+ jsxFactory?: string,
164
+ jsxFragmentFactory?: string,
165
+ useDefineForClassFields?: boolean,
166
+ importsNotUsedAsValues?: 'remove' | 'preserve' | 'error',
167
+ },
168
+ };
169
+
170
+ sourcefile?: string;
171
+ loader?: Loader;
172
+ banner?: string;
173
+ footer?: string;
174
+ }
175
+
176
+ export interface TransformResult {
177
+ code: string;
178
+ map: string;
179
+ warnings: Message[];
180
+ }
181
+
182
+ export interface TransformFailure extends Error {
183
+ errors: Message[];
184
+ warnings: Message[];
185
+ }
186
+
187
+ export interface Plugin {
188
+ name: string;
189
+ setup: (build: PluginBuild) => (void | Promise<void>);
190
+ }
191
+
192
+ export interface PluginBuild {
193
+ initialOptions: BuildOptions;
194
+ onStart(callback: () =>
195
+ (OnStartResult | null | void | Promise<OnStartResult | null | void>)): void;
196
+ onEnd(callback: (result: BuildResult) =>
197
+ (void | Promise<void>)): void;
198
+ onResolve(options: OnResolveOptions, callback: (args: OnResolveArgs) =>
199
+ (OnResolveResult | null | undefined | Promise<OnResolveResult | null | undefined>)): void;
200
+ onLoad(options: OnLoadOptions, callback: (args: OnLoadArgs) =>
201
+ (OnLoadResult | null | undefined | Promise<OnLoadResult | null | undefined>)): void;
202
+ }
203
+
204
+ export interface OnStartResult {
205
+ errors?: PartialMessage[];
206
+ warnings?: PartialMessage[];
207
+ }
208
+
209
+ export interface OnResolveOptions {
210
+ filter: RegExp;
211
+ namespace?: string;
212
+ }
213
+
214
+ export interface OnResolveArgs {
215
+ path: string;
216
+ importer: string;
217
+ namespace: string;
218
+ resolveDir: string;
219
+ kind: ImportKind;
220
+ pluginData: any;
221
+ }
222
+
223
+ export type ImportKind =
224
+ | 'entry-point'
225
+
226
+ // JS
227
+ | 'import-statement'
228
+ | 'require-call'
229
+ | 'dynamic-import'
230
+ | 'require-resolve'
231
+
232
+ // CSS
233
+ | 'import-rule'
234
+ | 'url-token'
235
+
236
+ export interface OnResolveResult {
237
+ pluginName?: string;
238
+
239
+ errors?: PartialMessage[];
240
+ warnings?: PartialMessage[];
241
+
242
+ path?: string;
243
+ external?: boolean;
244
+ sideEffects?: boolean;
245
+ namespace?: string;
246
+ pluginData?: any;
247
+
248
+ watchFiles?: string[];
249
+ watchDirs?: string[];
250
+ }
251
+
252
+ export interface OnLoadOptions {
253
+ filter: RegExp;
254
+ namespace?: string;
255
+ }
256
+
257
+ export interface OnLoadArgs {
258
+ path: string;
259
+ namespace: string;
260
+ pluginData: any;
261
+ }
262
+
263
+ export interface OnLoadResult {
264
+ pluginName?: string;
265
+
266
+ errors?: PartialMessage[];
267
+ warnings?: PartialMessage[];
268
+
269
+ contents?: string | Uint8Array;
270
+ resolveDir?: string;
271
+ loader?: Loader;
272
+ pluginData?: any;
273
+
274
+ watchFiles?: string[];
275
+ watchDirs?: string[];
276
+ }
277
+
278
+ export interface PartialMessage {
279
+ pluginName?: string;
280
+ text?: string;
281
+ location?: Partial<Location> | null;
282
+ notes?: PartialNote[];
283
+ detail?: any;
284
+ }
285
+
286
+ export interface PartialNote {
287
+ text?: string;
288
+ location?: Partial<Location> | null;
289
+ }
290
+
291
+ export interface Metafile {
292
+ inputs: {
293
+ [path: string]: {
294
+ bytes: number
295
+ imports: {
296
+ path: string
297
+ kind: ImportKind
298
+ }[]
299
+ }
300
+ }
301
+ outputs: {
302
+ [path: string]: {
303
+ bytes: number
304
+ inputs: {
305
+ [path: string]: {
306
+ bytesInOutput: number
307
+ }
308
+ }
309
+ imports: {
310
+ path: string
311
+ kind: ImportKind
312
+ }[]
313
+ exports: string[]
314
+ entryPoint?: string
315
+ }
316
+ }
317
+ }
318
+
319
+ export interface FormatMessagesOptions {
320
+ kind: 'error' | 'warning';
321
+ color?: boolean;
322
+ terminalWidth?: number;
323
+ }
324
+
325
+ // This function invokes the "esbuild" command-line tool for you. It returns a
326
+ // promise that either resolves with a "BuildResult" object or rejects with a
327
+ // "BuildFailure" object.
328
+ //
329
+ // Works in node: yes
330
+ // Works in browser: yes
331
+ export declare function build(options: BuildOptions & { write: false }): Promise<BuildResult & { outputFiles: OutputFile[] }>;
332
+ export declare function build(options: BuildOptions & { incremental: true }): Promise<BuildIncremental>;
333
+ export declare function build(options: BuildOptions): Promise<BuildResult>;
334
+
335
+ // This function is similar to "build" but it serves the resulting files over
336
+ // HTTP on a localhost address with the specified port.
337
+ //
338
+ // Works in node: yes
339
+ // Works in browser: no
340
+ export declare function serve(serveOptions: ServeOptions, buildOptions: BuildOptions): Promise<ServeResult>;
341
+
342
+ // This function transforms a single JavaScript file. It can be used to minify
343
+ // JavaScript, convert TypeScript/JSX to JavaScript, or convert newer JavaScript
344
+ // to older JavaScript. It returns a promise that is either resolved with a
345
+ // "TransformResult" object or rejected with a "TransformFailure" object.
346
+ //
347
+ // Works in node: yes
348
+ // Works in browser: yes
349
+ export declare function transform(input: string, options?: TransformOptions): Promise<TransformResult>;
350
+
351
+ // Converts log messages to formatted message strings suitable for printing in
352
+ // the terminal. This allows you to reuse the built-in behavior of esbuild's
353
+ // log message formatter. This is a batch-oriented API for efficiency.
354
+ //
355
+ // Works in node: yes
356
+ // Works in browser: yes
357
+ export declare function formatMessages(messages: PartialMessage[], options: FormatMessagesOptions): Promise<string[]>;
358
+
359
+ // A synchronous version of "build".
360
+ //
361
+ // Works in node: yes
362
+ // Works in browser: no
363
+ export declare function buildSync(options: BuildOptions & { write: false }): BuildResult & { outputFiles: OutputFile[] };
364
+ export declare function buildSync(options: BuildOptions): BuildResult;
365
+
366
+ // A synchronous version of "transform".
367
+ //
368
+ // Works in node: yes
369
+ // Works in browser: no
370
+ export declare function transformSync(input: string, options?: TransformOptions): TransformResult;
371
+
372
+ // A synchronous version of "formatMessages".
373
+ //
374
+ // Works in node: yes
375
+ // Works in browser: no
376
+ export declare function formatMessagesSync(messages: PartialMessage[], options: FormatMessagesOptions): string[];
377
+
378
+ // This configures the browser-based version of esbuild. It is necessary to
379
+ // call this first and wait for the returned promise to be resolved before
380
+ // making other API calls when using esbuild in the browser.
381
+ //
382
+ // Works in node: yes
383
+ // Works in browser: yes ("options" is required)
384
+ export declare function initialize(options: InitializeOptions): Promise<void>;
385
+
386
+ export interface InitializeOptions {
387
+ // The URL of the "esbuild.wasm" file. This must be provided when running
388
+ // esbuild in the browser.
389
+ wasmURL?: string
390
+
391
+ // By default esbuild runs the WebAssembly-based browser API in a web worker
392
+ // to avoid blocking the UI thread. This can be disabled by setting "worker"
393
+ // to false.
394
+ worker?: boolean
395
+ }
396
+
397
+ export let version: string;