diff --git a/cli/tauri.js/package.json b/cli/tauri.js/package.json index 000182f40..bda9f531e 100644 --- a/cli/tauri.js/package.json +++ b/cli/tauri.js/package.json @@ -1,6 +1,6 @@ { "name": "tauri", - "version": "0.6.0", + "version": "0.6.1", "description": "Multi-binding collection of libraries and templates for building Tauri apps", "bin": { "tauri": "./bin/tauri.js" @@ -51,6 +51,7 @@ "cross-spawn": "7.0.2", "fast-glob": "3.2.2", "fs-extra": "9.0.0", + "http-proxy": "^1.18.0", "imagemin": "7.0.1", "imagemin-optipng": "7.1.0", "imagemin-pngquant": "8.0.0", @@ -73,6 +74,7 @@ "@babel/preset-typescript": "7.9.0", "@types/cross-spawn": "6.0.1", "@types/fs-extra": "8.1.0", + "@types/http-proxy": "^1.17.4", "@types/imagemin": "7.0.0", "@types/imagemin-optipng": "5.2.0", "@types/jsdom": "16.2.1", diff --git a/cli/tauri.js/src/helpers/net.ts b/cli/tauri.js/src/helpers/net.ts index 82083594b..600f6875e 100644 --- a/cli/tauri.js/src/helpers/net.ts +++ b/cli/tauri.js/src/helpers/net.ts @@ -3,17 +3,16 @@ import net from 'net' async function findClosestOpenPort(port: number, host: string): Promise { - let portProposal = port - - do { - if (await isPortAvailable(portProposal, host)) { - return portProposal - } - portProposal++ - } - while (portProposal < 65535) - - throw new Error('ERROR_NETWORK_PORT_NOT_AVAIL') + return await isPortAvailable(port, host) + .then(isAvailable => { + if (isAvailable) { + return port + } else if (port < 65535) { + return findClosestOpenPort(port + 1, host) + } else { + throw new Error('ERROR_NETWORK_PORT_NOT_AVAIL') + } + }) } async function isPortAvailable(port: number, host: string): Promise { diff --git a/cli/tauri.js/src/runner.ts b/cli/tauri.js/src/runner.ts index aabf36aba..624c0af72 100644 --- a/cli/tauri.js/src/runner.ts +++ b/cli/tauri.js/src/runner.ts @@ -14,8 +14,10 @@ import { tauriDir, appDir } from './helpers/app-paths' import logger from './helpers/logger' import onShutdown from './helpers/on-shutdown' import { spawn, spawnSync } from './helpers/spawn' +import { exec } from 'child_process' import { TauriConfig } from './types/config' import getTauriConfig from './helpers/tauri-config' +import httpProxy from 'http-proxy' const log = logger('app:tauri', 'green') const warn = logger('app:tauri (runner)', 'red') @@ -51,10 +53,18 @@ class Runner { if (!this.ranBeforeDevCommand && cfg.build.beforeDevCommand) { this.ranBeforeDevCommand = true // prevent calling it twice on recursive call on our watcher - const [command, ...args] = cfg.build.beforeDevCommand.split(' ') - spawn(command, args, appDir, code => { - process.exit(code) + log('Running `' + cfg.build.beforeDevCommand + '`') + const ls = exec(cfg.build.beforeDevCommand, { + cwd: appDir, + env: process.env + }, error => { + if (error) { + process.exit(1) + } }) + + ls.stderr && ls.stderr.pipe(process.stderr) + ls.stdout && ls.stdout.pipe(process.stdout) } const tomlContents = this.__getManifest() @@ -68,51 +78,51 @@ class Runner { let inlinedAssets: string[] = [] if (runningDevServer) { + const self = this const devUrl = new URL(devPath) - const app = http.createServer((req, res) => { - const options = { - hostname: devUrl.hostname, - port: devUrl.port, - path: req.url, - method: req.method - } - - const self = this - - const proxy = http.request(options, function (originalResponse) { - if (options.path === '/') { - let body: Uint8Array[] = [] - originalResponse.on('data', chunk => { - body.push(chunk) - }) - originalResponse.on('end', () => { - const originalHtml = body.join('') - const indexDir = os.tmpdir() - writeFileSync(path.join(indexDir, 'index.html'), originalHtml) - self.__parseHtml(cfg, indexDir, false) - .then(({ html }) => { - res.writeHead(200) - res.end(html) - }).catch(err => { - res.writeHead(500, JSON.stringify(err)) - res.end() - }) - }) - } else { - res.writeHead(res.statusCode, originalResponse.headers) - originalResponse.pipe(res, { - end: true - }) - } - }) - - req.pipe(proxy, { - end: true - }) + const proxy = httpProxy.createProxyServer({ + ws: true, + target: { + host: devUrl.hostname, + port: devUrl.port + }, + selfHandleResponse: true }) + + proxy.on('proxyRes', function (proxyRes, req, res) { + if (req.url === '/') { + let body: Uint8Array[] = [] + proxyRes.on('data', function (chunk) { + body.push(chunk) + }) + proxyRes.on('end', function () { + let bodyStr = body.join('') + const indexDir = os.tmpdir() + writeFileSync(path.join(indexDir, 'index.html'), bodyStr) + self.__parseHtml(cfg, indexDir, false) + .then(({ html }) => { + res.end(html) + }).catch(err => { + res.writeHead(500, JSON.stringify(err)) + res.end() + }) + }) + } else { + proxyRes.pipe(res) + } + }) + + const proxyServer = http.createServer((req, res) => { + delete req.headers['accept-encoding'] + proxy.web(req, res) + }) + proxyServer.on('upgrade', (req, socket, head) => { + proxy.ws(req, socket, head) + }) + const port = await findClosestOpenPort(parseInt(devUrl.port) + 1, devUrl.hostname) - const server = app.listen(port) - this.devServer = server + const devServer = proxyServer.listen(port) + this.devServer = devServer devPath = `${devUrl.protocol}//localhost:${port}` cfg.build.devPath = devPath process.env.TAURI_CONFIG = JSON.stringify(cfg) diff --git a/cli/tauri.js/yarn.lock b/cli/tauri.js/yarn.lock index 6344ed7a9..0c5ef25c6 100644 --- a/cli/tauri.js/yarn.lock +++ b/cli/tauri.js/yarn.lock @@ -1234,6 +1234,13 @@ dependencies: "@types/node" "*" +"@types/http-proxy@^1.17.4": + version "1.17.4" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.4.tgz#e7c92e3dbe3e13aa799440ff42e6d3a17a9d045b" + integrity sha512-IrSHl2u6AWXduUaDLqYpt45tLVCtYv7o4Z0s1KghBCDgIIS9oW5K1H8mZG/A2CfeLdEa7rTd1ACOiHBc1EMT2Q== + dependencies: + "@types/node" "*" + "@types/imagemin-optipng@5.2.0": version "5.2.0" resolved "https://registry.yarnpkg.com/@types/imagemin-optipng/-/imagemin-optipng-5.2.0.tgz#83046e0695739661fa738ad253bdbf51bc4f9e9d" @@ -3056,6 +3063,13 @@ debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: dependencies: ms "2.0.0" +debug@^3.0.0: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" @@ -3776,6 +3790,11 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +eventemitter3@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb" + integrity sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg== + events@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" @@ -4195,6 +4214,13 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" +follow-redirects@^1.0.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.11.0.tgz#afa14f08ba12a52963140fe43212658897bc0ecb" + integrity sha512-KZm0V+ll8PfBrKwMzdo5D13b1bur9Iq9Zd/RMmAoQQcl2PxxFml8cxXPaaPYVbV0RjNjq1CU7zIzAOqtUPudmA== + dependencies: + debug "^3.0.0" + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -4716,6 +4742,15 @@ http-cache-semantics@^4.0.0: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== +http-proxy@^1.18.0: + version "1.18.0" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.0.tgz#dbe55f63e75a347db7f3d99974f2692a314a6a3a" + integrity sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -7776,6 +7811,11 @@ require-main-filename@^2.0.0: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" diff --git a/tauri/examples/communication/dist/index.tauri.html b/tauri/examples/communication/dist/index.tauri.html index dff5ca124..839cf70d9 100644 --- a/tauri/examples/communication/dist/index.tauri.html +++ b/tauri/examples/communication/dist/index.tauri.html @@ -624,4 +624,4 @@ if (document.readyState === 'complete' || document.readyState === 'interactive') __openLinks() }, true) } -
\ No newline at end of file +
\ No newline at end of file