1 | const imba1 = require('./bootstrap.compiler.js');
|
2 | const imba2 = require('./bootstrap.compiler2.js');
|
3 | const chokidar = require('chokidar');
|
4 | const fs = require('fs');
|
5 | const np = require('path');
|
6 | const esbuild = require('esbuild');
|
7 |
|
8 | let helpers = imba2.helpers;
|
9 | let time = 0;
|
10 | let argv = helpers.parseArgs(process.argv.slice(2), {
|
11 | alias: { w: 'watch' }
|
12 | })
|
13 |
|
14 | let meta = Symbol();
|
15 | let compileCache = {};
|
16 | let globalNames = {
|
17 | compiler: 'imbac'
|
18 | }
|
19 |
|
20 | let distdir = np.resolve(__dirname, '..', 'dist')
|
21 |
|
22 | fs.mkdirSync(distdir, { recursive: true });
|
23 |
|
24 | function plugin(build) {
|
25 |
|
26 | let options = this.options;
|
27 | let self = this;
|
28 | let watcher = this.watcher;
|
29 | let fs = require('fs');
|
30 | let basedir = np.resolve(__dirname, '..');
|
31 | let outdir = options.outdir || np.dirname(options.outfile);
|
32 | let distrel = './' + np.relative(distdir, outdir);
|
33 | let absoutdir = np.resolve(__dirname, '..', outdir);
|
34 |
|
35 | function relative(path) {
|
36 | let res = np.relative(absoutdir, np.resolve(basedir, path)).split('\\').join('/');
|
37 | if (res[0] != '.') res = './' + res;
|
38 | return res;
|
39 | }
|
40 |
|
41 | build.onResolve({ filter: /^dist\// }, (p) => {
|
42 | return { path: relative(p.path), external: true }
|
43 | });
|
44 |
|
45 | build.onResolve({ filter: /^compiler1?$/ }, (p) => {
|
46 |
|
47 |
|
48 | let src = p.path == 'compiler1' ? "../scripts/bootstrap.compiler.js" : "./dist/compiler.cjs";
|
49 | return { path: src, external: true }
|
50 | });
|
51 |
|
52 | build.onLoad({ filter: /\.imba1/ }, async (args) => {
|
53 |
|
54 | if (watcher) watcher.add(args.path);
|
55 |
|
56 | let key = `${args.path}:${options.platform}`
|
57 | let raw = await fs.promises.readFile(args.path, 'utf8');
|
58 | let cached = compileCache[key];
|
59 |
|
60 | if (cached && cached.input == raw) {
|
61 | return { contents: cached.output };
|
62 | }
|
63 |
|
64 | let target = {
|
65 | browser: 'web',
|
66 | worker: 'webworker'
|
67 | }[options.platform] || options.platform || 'web';
|
68 | let t0 = Date.now();
|
69 |
|
70 | let body = imba1.compile(raw, {
|
71 | target: target,
|
72 | filename: args.path,
|
73 | sourcePath: args.path
|
74 | });
|
75 | time += (Date.now() - t0);
|
76 | compileCache[key] = { input: raw, output: body.js };
|
77 | return { contents: body.js }
|
78 | })
|
79 |
|
80 | build.onLoad({ filter: /\.imba/ }, async (args) => {
|
81 |
|
82 | if (watcher) watcher.add(args.path);
|
83 | let raw = await fs.promises.readFile(args.path, 'utf8');
|
84 | let key = `${args.path}:${options.platform}`
|
85 | let cached = compileCache[key];
|
86 |
|
87 | if (cached && cached.input == raw) {
|
88 |
|
89 | return { contents: cached.output };
|
90 | }
|
91 |
|
92 | let t0 = Date.now();
|
93 | let body = imba2.compile(raw, Object.assign({
|
94 | platform: options.platform || 'browser',
|
95 | format: 'esm',
|
96 | sourcePath: args.path,
|
97 | }, self.imbaOptions));
|
98 |
|
99 | time += (Date.now() - t0);
|
100 | compileCache[key] = { input: raw, output: body.js };
|
101 |
|
102 | return {
|
103 | contents: body.js
|
104 | }
|
105 | })
|
106 |
|
107 | build.onLoad({ filter: /\.js/ }, async (args) => {
|
108 |
|
109 | if (watcher) watcher.add(args.path);
|
110 | return;
|
111 | })
|
112 | }
|
113 | async function universalise(result, o) {
|
114 | for (let file of result.outputFiles) {
|
115 |
|
116 | let bname = np.basename(file.path).split(".")[0];
|
117 | console.log("output", file.path, bname);
|
118 | fs.writeFileSync(file.path, file.contents);
|
119 |
|
120 | if (o.format == 'esm' && file.path.indexOf('.mjs') >= 0) {
|
121 | let cjs = esbuild.transformSync(file.text, {
|
122 | format: 'cjs',
|
123 | minify: o.minify
|
124 | });
|
125 |
|
126 | let name = file.path.replace('.mjs', '.cjs');
|
127 | console.log("transformed to cjs", name, cjs.code.length, file.text.length);
|
128 | fs.writeFileSync(name, cjs.code);
|
129 | }
|
130 |
|
131 | if (o.format == 'esm' && o.platform == 'browser' && globalNames[bname]) {
|
132 | let iife = esbuild.transformSync(file.text, {
|
133 | format: 'iife',
|
134 | minify: o.minify,
|
135 | globalName: globalNames[bname]
|
136 | })
|
137 |
|
138 | let name = file.path.replace('.mjs', '.js');
|
139 | if (true) {
|
140 | console.log("transformed to iife", name, globalNames[bname], iife.code.length, file.text.length);
|
141 | fs.writeFileSync(name, iife.code);
|
142 | }
|
143 | }
|
144 | }
|
145 | }
|
146 |
|
147 | async function bundle(o) {
|
148 | if (o instanceof Array) {
|
149 | for (let config of o) {
|
150 | bundle(config);
|
151 | }
|
152 | return;
|
153 | }
|
154 | let input = o.entryPoints[0];
|
155 | let entry = { options: o }
|
156 | let watcher = entry.watcher = argv.watch && chokidar.watch([]);
|
157 |
|
158 | entry.imbaOptions = o.options || {};
|
159 |
|
160 | o.plugins = [{ name: 'imba', setup: plugin.bind(entry) }];
|
161 |
|
162 | if (o.platform == 'node') {
|
163 | o.resolveExtensions = ['.node.imba', '.imba', '.imba1', '.ts', '.mjs', '.cjs', '.js', '.css', '.json'];
|
164 | } else {
|
165 | o.resolveExtensions = ['.web.imba', '.imba', '.imba1', '.ts', '.mjs', '.cjs', '.js', '.css', '.json'];
|
166 | o.nodePaths = [np.resolve(__dirname, '..', 'polyfills')]
|
167 | o.target = ['chrome88','edge79','safari15']
|
168 | }
|
169 |
|
170 | if (!o.outdir && !o.outfile) {
|
171 | o.outdir = `dist/${o.platform}`;
|
172 | }
|
173 |
|
174 | o.target = o.target || ['es2020'];
|
175 | o.format = o.format || 'esm';
|
176 |
|
177 | if (o.bundle == undefined) o.bundle = true;
|
178 | o.loader = { '.txt': 'text' }
|
179 | o.incremental = !!watcher;
|
180 | o.logLevel = 'info';
|
181 | o.charset = 'utf8';
|
182 | o.pure = ['Symbol.for','Symbol'];
|
183 | o.minify = !argv.watch;
|
184 | o.supported = {bigint: true}
|
185 | o.define = {'process.env.NODE_ENV': "'production'"};
|
186 | if (o.write == undefined) o.write = false;
|
187 |
|
188 | delete o.options;
|
189 | let result = await esbuild.build(o);
|
190 | await universalise(result, o);
|
191 | if (watcher) {
|
192 | watcher.on('change', async () => {
|
193 | console.log('rebuilding', input);
|
194 | let rebuilt = await result.rebuild();
|
195 | await universalise(rebuilt, o);
|
196 | console.log('rebuilt', input);
|
197 | })
|
198 | }
|
199 | }
|
200 |
|
201 | let bundles = [
|
202 | {
|
203 | entryPoints: ["src/imba/hmr.imba"],
|
204 | outdir: "dist",
|
205 | platform: "browser",
|
206 | format: "esm",
|
207 | },
|
208 | {
|
209 | entryPoints: ["src/imba/imba.imba"],
|
210 | outdir: "dist",
|
211 | platform: "browser",
|
212 | external: [ "vite"],
|
213 | format: "esm",
|
214 | outExtension: { ".js": ".mjs" },
|
215 | },
|
216 | {
|
217 | entryPoints: ["compiler.imba"],
|
218 | outdir: "dist",
|
219 | platform: "browser",
|
220 | format: "esm",
|
221 | outExtension: { ".js": ".mjs" }
|
222 | },
|
223 | {
|
224 | entryPoints: ["src/imba/imba.imba"],
|
225 | outExtension: { ".js": ".node.js" },
|
226 | format: "cjs",
|
227 | outdir: "dist",
|
228 | external: ["lodash.mergewith", "vite", 'colors', 'local-pkg'],
|
229 | platform: "node",
|
230 | },
|
231 | {
|
232 | entryPoints: ["src/imba/imba.imba"],
|
233 | outExtension: { ".js": ".node.mjs" },
|
234 | format: "esm",
|
235 | outdir: "dist",
|
236 | external: [ "vite", 'colors', 'local-pkg', 'get-port'],
|
237 | platform: "node",
|
238 | },
|
239 | {
|
240 | entryPoints: [
|
241 | "bin/imba.imba",
|
242 | "program.imba",
|
243 | "workers.imba"
|
244 | ],
|
245 | outExtension: { ".js": ".imba.js" },
|
246 | minify: true,
|
247 | external: ["lodash.mergewith", "chokidar", "esbuild", "vite-node/client","vite-node/server", "vite"],
|
248 | outdir: ".",
|
249 | format: "cjs",
|
250 | platform: "node",
|
251 | },
|
252 | {
|
253 | entryPoints: [
|
254 | "program.imba"
|
255 | ],
|
256 | outExtension: { ".js": ".browser.imba.js" },
|
257 | minify: true,
|
258 | external: ["chokidar", "esbuild", "vite-node/client","vite-node/server", "vite"],
|
259 | outdir: ".",
|
260 | format: "esm",
|
261 | platform: "browser",
|
262 | },
|
263 | {
|
264 | entryPoints: [
|
265 | "src/vite-plugin/plugin.imba"
|
266 | ],
|
267 | outExtension: { ".js": ".mjs" },
|
268 | minify: true,
|
269 | external: ["lodash.mergewith", "colors", "vite", "imba", "debug", "diff", "picomatch", "get-port", "esbuild"],
|
270 | outdir: "dist",
|
271 | format: "esm",
|
272 | platform: "node",
|
273 | },
|
274 | {
|
275 | entryPoints: [
|
276 | "src/vite-plugin/plugin.imba"
|
277 | ],
|
278 | outExtension: { ".js": ".cjs" },
|
279 | minify: true,
|
280 | external: ["lodash.mergewith", "colors", "vite", "imba", "debug", "diff", "picomatch", "get-port", "esbuild"],
|
281 | outdir: "dist",
|
282 | format: "cjs",
|
283 | platform: "node",
|
284 | },
|
285 | ];
|
286 | bundle(bundles)
|