UNPKG

7.53 kBJavaScriptView Raw
1const imba1 = require('./bootstrap.compiler.js');
2const imba2 = require('./bootstrap.compiler2.js');
3const chokidar = require('chokidar');
4const fs = require('fs');
5const np = require('path');
6const esbuild = require('esbuild');
7
8let helpers = imba2.helpers;
9let time = 0;
10let argv = helpers.parseArgs(process.argv.slice(2), {
11 alias: { w: 'watch' }
12})
13
14let meta = Symbol();
15let compileCache = {};
16let globalNames = {
17 compiler: 'imbac'
18}
19
20let distdir = np.resolve(__dirname, '..', 'dist')
21// Create the dist directory
22fs.mkdirSync(distdir, { recursive: true });
23
24function plugin(build) {
25 // console.log('setting up plugin',build,this);
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 // find the output dir
47 // console.log('resolve compiler?',p,options);
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 // console.log('loading imba',args);
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 // console.log('loading imba',args);
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 // console.log('found cached version',key);
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 // console.log('loading js',args);
109 if (watcher) watcher.add(args.path);
110 return;
111 })
112}
113async 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 // && o.platform == 'node'
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) { // name != file.path
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
147async 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
201let 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];
286bundle(bundles)