UNPKG

vite-plugin-browser-sync

Version:
330 lines (327 loc) 9.84 kB
// src/index.ts import { italic, red as red2 } from "kolorist"; // src/server.ts import process2 from "node:process"; import { create } from "browser-sync"; import { bold, lightYellow, red } from "kolorist"; var defaultPorts = { dev: 5173, preview: 4173, buildWatch: null }; var Server = class { constructor(obj) { this.logged = false; const { name, server, config, options, env } = obj; this.name = name; this.server = server; this.config = config; this.options = options; this.env = env; this.bsServer = create(this.name); if (typeof this.userBsOptions.logLevel === "undefined") this.logged = true; this.registerInit(); this.registerClose(); } /** * Get browser sync mode * @readonly */ get mode() { if (this.env === "preview") return "proxy"; let mode = this.userOptions && "mode" in this.userOptions && this.userOptions.mode ? this.userOptions.mode : "proxy"; if (this.userBsOptions.proxy) mode = "proxy"; return mode; } /** * Get browser sync instance * @readonly */ get bs() { return this.bsServer; } /** * Get vite server port * @readonly */ get port() { if (this.env === "buildWatch" || !this.server) return null; const defaultPort = defaultPorts[this.env]; const configPort = this.env === "dev" ? this.config.server.port : this.config.preview.port; return configPort || defaultPort; } /** * Get user options * @readonly */ get userOptions() { return this.options && this.env in this.options ? this.options[this.env] : {}; } /** * Get user browsersync options * @readonly */ get userBsOptions() { return this.userOptions && this.userOptions.bs ? this.userOptions.bs : {}; } /** * Get Final browsersync options */ get bsOptions() { var _a, _b, _c, _d; const bsOptions = this.userBsOptions; if (typeof bsOptions.logLevel === "undefined") bsOptions.logLevel = "silent"; if (this.server && typeof bsOptions.open === "undefined") bsOptions.open = typeof this.config.server.open !== "undefined"; if (this.env === "dev" && typeof bsOptions.codeSync === "undefined") bsOptions.codeSync = false; if (this.mode === "snippet") { bsOptions.logSnippet = false; bsOptions.snippet = false; } bsOptions.online = bsOptions.online === true || this.server && typeof this.config.server.host !== "undefined" || false; if (this.env === "buildWatch") return bsOptions; if (this.mode === "proxy") { let target; if ((_b = (_a = this.server) == null ? void 0 : _a.resolvedUrls) == null ? void 0 : _b.local[0]) { target = (_d = (_c = this.server) == null ? void 0 : _c.resolvedUrls) == null ? void 0 : _d.local[0]; } else if (this.port) { const protocol = this.config.server.https ? "https" : "http"; target = `${protocol}://localhost:${this.port}/`; } if (!bsOptions.proxy) { bsOptions.proxy = { target, ws: true }; } else if (typeof bsOptions.proxy === "string") { bsOptions.proxy = { target: bsOptions.proxy, ws: true }; } else if (typeof bsOptions.proxy === "object" && !bsOptions.proxy.ws) { bsOptions.proxy.ws = true; } } return bsOptions; } /** * Init browsersync server */ init() { return new Promise((resolve, reject) => { this.bsServer.init(this.bsOptions, (error, bs) => { if (error) { this.config.logger.error( red(`[vite-plugin-browser-sync] ${error.name} ${error.message}`), { error } ); reject(error); } resolve(bs); }); }); } /* c8 ignore start */ /** * Log browsersync infos */ log() { const colorUrl = (url) => lightYellow(url.replace(/:(\d+)$/, (_, port) => `:${bold(port)}/`)); const urls = this.bsServer.getOption("urls").toJS(); const consoleTexts = { "local": "Local", "external": "External", "ui": "UI", "ui-external": "UI External", "tunnel": "Tunnel" }; for (const key in consoleTexts) { if (Object.prototype.hasOwnProperty.call(consoleTexts, key)) { const text = consoleTexts[key]; if (Object.prototype.hasOwnProperty.call(urls, key)) { this.config.logger.info( ` ${lightYellow("\u279C")} ${bold( `BrowserSync - ${text}` )}: ${colorUrl(urls[key])}` ); } } } } /** * Register log function on vite */ registerLog() { if (!this.logged) return; if (this.server && this.env === "dev") { let astroServer = false; try { astroServer = "pluginContainer" in this.server && this.server.environments.client.plugins.findIndex( (plugin) => plugin.name === "astro:server" ) > -1; } catch (e) { astroServer = "pluginContainer" in this.server && this.server.pluginContainer.plugins.findIndex( (plugin) => plugin.name === "astro:server" ) > -1; } if (astroServer) { setTimeout(() => this.log(), 1e3); } else { const _print = this.server.printUrls; this.server.printUrls = () => { _print(); this.log(); }; } } else { this.log(); } } /* c8 ignore stop */ /** * Register init */ async registerInit() { if (this.server && "listen" in this.server) { const _listen = this.server.listen; this.server.listen = async () => { const out = await _listen(); await this.init(); return out; }; } else if (this.server) { await new Promise((resolve) => { var _a, _b; (_b = (_a = this.server) == null ? void 0 : _a.httpServer) == null ? void 0 : _b.once("listening", () => { resolve(true); }); }); await this.init(); } else { await this.init(); } this.registerLog(); } /** * Register close */ registerClose() { var _a; if (this.server) { const _close = this.server.close; this.server.close = async () => { this.bsServer.exit(); await _close(); }; (_a = this.server.httpServer) == null ? void 0 : _a.on("close", () => { this.bsServer.exit(); }); } process2.once("SIGINT", () => { this.bsServer.exit(); process2.exit(); }); } }; // src/index.ts function VitePluginBrowserSync(options) { const name = "vite-plugin-browser-sync"; const bsClientVersion = "3.0.3"; let config; let env = "dev"; let bsServer = null; let started = false; let applyOnDev = false; let applyOnPreview = false; let applyOnBuildWatch = false; return { name, apply(_config, env2) { var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k; if (options == null ? void 0 : options.bs) { console.error( red2( `[vite-plugin-browser-sync] Since 3.0, you should wrap your ${italic("bs")} option inside a ${italic("dev")} object.` ) ); return false; } applyOnDev = env2.command === "serve" && (typeof env2.isPreview === "undefined" || env2.isPreview === false) && ((_a = options == null ? void 0 : options.dev) == null ? void 0 : _a.enable) !== false; applyOnPreview = env2.command === "serve" && env2.isPreview === true && ((_b = options == null ? void 0 : options.preview) == null ? void 0 : _b.enable) === true; applyOnBuildWatch = env2.command === "build" && (((_c = _config.build) == null ? void 0 : _c.watch) === true || typeof ((_d = _config.build) == null ? void 0 : _d.watch) === "object") && ((_e = options == null ? void 0 : options.buildWatch) == null ? void 0 : _e.enable) === true; if (applyOnBuildWatch && ((_f = options == null ? void 0 : options.buildWatch) == null ? void 0 : _f.mode) !== "snippet" && typeof ((_h = (_g = options == null ? void 0 : options.buildWatch) == null ? void 0 : _g.bs) == null ? void 0 : _h.proxy) !== "string" && typeof ((_k = (_j = (_i = options == null ? void 0 : options.buildWatch) == null ? void 0 : _i.bs) == null ? void 0 : _j.proxy) == null ? void 0 : _k.target) !== "string") { console.error( red2( "[vite-plugin-browser-sync] You need to set a browsersync target." ) ); return false; } return applyOnDev || applyOnPreview || applyOnBuildWatch; }, configResolved(_config) { config = _config; }, buildStart() { if (started || !applyOnBuildWatch) return; env = "buildWatch"; bsServer = new Server({ env, name, options, config }); started = true; }, async configureServer(server) { env = "dev"; bsServer = new Server({ env, name, server, options, config }); }, async configurePreviewServer(server) { env = "preview"; bsServer = new Server({ env, name, server, options, config }); }, transformIndexHtml: { order: "post", handler: (html) => { const applySnippet = applyOnDev || applyOnBuildWatch; if (!bsServer || bsServer.mode !== "snippet" || !applySnippet) return html; const urls = bsServer.bs.getOption("urls").toJS(); const bsScript = { tag: "script", attrs: { async: "", src: `${urls.local}/browser-sync/browser-sync-client.js?v=${bsClientVersion}` }, injectTo: "body" }; return [bsScript]; } } }; } export { VitePluginBrowserSync as default };