| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- // This file runs in the browser.
- window.process = window.process || {};
- window.process.env = window.process.env || {};
- window.process.env.NODE_ENV = __MODE__;
- const defines = __DEFINES__;
- Object.keys(defines).forEach((key) => {
- const segs = key.split('.');
- let target = window;
- for (let i = 0; i < segs.length; i++) {
- const seg = segs[i];
- if (i === segs.length - 1) {
- target[seg] = defines[key];
- }
- else {
- target = target[seg] || (target[seg] = {});
- }
- }
- });
- console.log('[vite] connecting...');
- // use server configuration, then fallback to inference
- const socketProtocol = __HMR_PROTOCOL__ || (location.protocol === 'https:' ? 'wss' : 'ws');
- const socketHost = `${__HMR_HOSTNAME__ || location.hostname}:${__HMR_PORT__}`;
- const socket = new WebSocket(`${socketProtocol}://${socketHost}`, 'vite-hmr');
- function warnFailedFetch(err, path) {
- if (!err.message.match('fetch')) {
- console.error(err);
- }
- console.error(`[hmr] Failed to reload ${path}. ` +
- `This could be due to syntax errors or importing non-existent ` +
- `modules. (see errors above)`);
- }
- // Listen for messages
- socket.addEventListener('message', async ({ data }) => {
- const payload = JSON.parse(data);
- if (payload.type === 'multi') {
- payload.updates.forEach(handleMessage);
- }
- else {
- handleMessage(payload);
- }
- });
- async function handleMessage(payload) {
- const { path, changeSrcPath, timestamp } = payload;
- switch (payload.type) {
- case 'connected':
- console.log(`[vite] connected.`);
- break;
- case 'vue-reload':
- queueUpdate(import(`${path}?t=${timestamp}`)
- .catch((err) => warnFailedFetch(err, path))
- .then((m) => () => {
- __VUE_HMR_RUNTIME__.reload(path, m.default);
- console.log(`[vite] ${path} reloaded.`);
- }));
- break;
- case 'vue-rerender':
- const templatePath = `${path}?type=template`;
- import(`${templatePath}&t=${timestamp}`).then((m) => {
- __VUE_HMR_RUNTIME__.rerender(path, m.render);
- console.log(`[vite] ${path} template updated.`);
- });
- break;
- case 'style-update':
- // check if this is referenced in html via <link>
- const el = document.querySelector(`link[href*='${path}']`);
- if (el) {
- el.setAttribute('href', `${path}${path.includes('?') ? '&' : '?'}t=${timestamp}`);
- break;
- }
- // imported CSS
- const importQuery = path.includes('?') ? '&import' : '?import';
- await import(`${path}${importQuery}&t=${timestamp}`);
- console.log(`[vite] ${path} updated.`);
- break;
- case 'style-remove':
- removeStyle(payload.id);
- break;
- case 'js-update':
- queueUpdate(updateModule(path, changeSrcPath, timestamp));
- break;
- case 'custom':
- const cbs = customUpdateMap.get(payload.id);
- if (cbs) {
- cbs.forEach((cb) => cb(payload.customData));
- }
- break;
- case 'full-reload':
- if (path.endsWith('.html')) {
- // if html file is edited, only reload the page if the browser is
- // currently on that page.
- const pagePath = location.pathname;
- if (pagePath === path ||
- (pagePath.endsWith('/') && pagePath + 'index.html' === path)) {
- location.reload();
- }
- return;
- }
- else {
- location.reload();
- }
- }
- }
- let pending = false;
- let queued = [];
- /**
- * buffer multiple hot updates triggered by the same src change
- * so that they are invoked in the same order they were sent.
- * (otherwise the order may be inconsistent because of the http request round trip)
- */
- async function queueUpdate(p) {
- queued.push(p);
- if (!pending) {
- pending = true;
- await Promise.resolve();
- pending = false;
- const loading = [...queued];
- queued = [];
- (await Promise.all(loading)).forEach((fn) => fn && fn());
- }
- }
- // ping server
- socket.addEventListener('close', () => {
- console.log(`[vite] server connection lost. polling for restart...`);
- setInterval(() => {
- fetch('/')
- .then(() => {
- location.reload();
- })
- .catch((e) => {
- /* ignore */
- });
- }, 1000);
- });
- // https://wicg.github.io/construct-stylesheets
- const supportsConstructedSheet = (() => {
- try {
- new CSSStyleSheet();
- return true;
- }
- catch (e) { }
- return false;
- })();
- const sheetsMap = new Map();
- export function updateStyle(id, content) {
- let style = sheetsMap.get(id);
- if (supportsConstructedSheet && !content.includes('@import')) {
- if (style && !(style instanceof CSSStyleSheet)) {
- removeStyle(id);
- style = undefined;
- }
- if (!style) {
- style = new CSSStyleSheet();
- style.replaceSync(content);
- // @ts-ignore
- document.adoptedStyleSheets = [...document.adoptedStyleSheets, style];
- }
- else {
- style.replaceSync(content);
- }
- }
- else {
- if (style && !(style instanceof HTMLStyleElement)) {
- removeStyle(id);
- style = undefined;
- }
- if (!style) {
- style = document.createElement('style');
- style.setAttribute('type', 'text/css');
- style.innerHTML = content;
- document.head.appendChild(style);
- }
- else {
- style.innerHTML = content;
- }
- }
- sheetsMap.set(id, style);
- }
- function removeStyle(id) {
- let style = sheetsMap.get(id);
- if (style) {
- if (style instanceof CSSStyleSheet) {
- // @ts-ignore
- const index = document.adoptedStyleSheets.indexOf(style);
- // @ts-ignore
- document.adoptedStyleSheets = document.adoptedStyleSheets.filter((s) => s !== style);
- }
- else {
- document.head.removeChild(style);
- }
- sheetsMap.delete(id);
- }
- }
- async function updateModule(id, changedPath, timestamp) {
- const mod = hotModulesMap.get(id);
- if (!mod) {
- // In a code-spliting project,
- // it is common that the hot-updating module is not loaded yet.
- // https://github.com/vitejs/vite/issues/721
- return;
- }
- const moduleMap = new Map();
- const isSelfUpdate = id === changedPath;
- // make sure we only import each dep once
- const modulesToUpdate = new Set();
- if (isSelfUpdate) {
- // self update - only update self
- modulesToUpdate.add(id);
- }
- else {
- // dep update
- for (const { deps } of mod.callbacks) {
- if (Array.isArray(deps)) {
- deps.forEach((dep) => modulesToUpdate.add(dep));
- }
- else {
- modulesToUpdate.add(deps);
- }
- }
- }
- // determine the qualified callbacks before we re-import the modules
- const callbacks = mod.callbacks.filter(({ deps }) => {
- return Array.isArray(deps)
- ? deps.some((dep) => modulesToUpdate.has(dep))
- : modulesToUpdate.has(deps);
- });
- await Promise.all(Array.from(modulesToUpdate).map(async (dep) => {
- const disposer = disposeMap.get(dep);
- if (disposer)
- await disposer(dataMap.get(dep));
- try {
- const newMod = await import(dep + (dep.includes('?') ? '&' : '?') + `t=${timestamp}`);
- moduleMap.set(dep, newMod);
- }
- catch (e) {
- warnFailedFetch(e, dep);
- }
- }));
- return () => {
- for (const { deps, fn } of callbacks) {
- if (Array.isArray(deps)) {
- fn(deps.map((dep) => moduleMap.get(dep)));
- }
- else {
- fn(moduleMap.get(deps));
- }
- }
- console.log(`[vite]: js module hot updated: `, id);
- };
- }
- const hotModulesMap = new Map();
- const disposeMap = new Map();
- const dataMap = new Map();
- const customUpdateMap = new Map();
- export const createHotContext = (id) => {
- if (!dataMap.has(id)) {
- dataMap.set(id, {});
- }
- // when a file is hot updated, a new context is created
- // clear its stale callbacks
- const mod = hotModulesMap.get(id);
- if (mod) {
- mod.callbacks = [];
- }
- const hot = {
- get data() {
- return dataMap.get(id);
- },
- accept(callback = () => { }) {
- hot.acceptDeps(id, callback);
- },
- acceptDeps(deps, callback = () => { }) {
- const mod = hotModulesMap.get(id) || {
- id,
- callbacks: []
- };
- mod.callbacks.push({
- deps: deps,
- fn: callback
- });
- hotModulesMap.set(id, mod);
- },
- dispose(cb) {
- disposeMap.set(id, cb);
- },
- // noop, used for static analysis only
- decline() { },
- invalidate() {
- location.reload();
- },
- // custom events
- on(event, cb) {
- const existing = customUpdateMap.get(event) || [];
- existing.push(cb);
- customUpdateMap.set(event, existing);
- }
- };
- return hot;
- };
|