chore:更换到主分支

This commit is contained in:
张益铭
2021-03-01 15:26:05 +08:00
parent 9064b372e8
commit 6a5f1810f9
3530 changed files with 59613 additions and 479452 deletions

View File

@@ -1,15 +0,0 @@
export declare function updateStyle(id: string, content: string): void;
interface HotCallback {
deps: string | string[];
fn: (modules: object | object[]) => void;
}
export declare const createHotContext: (id: string) => {
readonly data: any;
accept(callback?: HotCallback['fn']): void;
acceptDeps(deps: HotCallback['deps'], callback?: HotCallback['fn']): void;
dispose(cb: (data: any) => void): void;
decline(): void;
invalidate(): void;
on(event: string, cb: () => void): void;
};
export {};

View File

@@ -1,26 +1,188 @@
// 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];
import './env';
const template = /*html*/ `
<style>
:host {
position: fixed;
z-index: 99999;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow-y: scroll;
margin: 0;
background: rgba(0, 0, 0, 0.66);
--monospace: 'SFMono-Regular', Consolas,
'Liberation Mono', Menlo, Courier, monospace;
--red: #ff5555;
--yellow: #e2aa53;
--purple: #cfa4ff;
--cyan: #2dd9da;
--dim: #c9c9c9;
}
.window {
font-family: var(--monospace);
line-height: 1.5;
width: 800px;
color: #d8d8d8;
margin: 30px auto;
padding: 25px 40px;
position: relative;
background: #181818;
border-radius: 6px 6px 8px 8px;
box-shadow: 0 19px 38px rgba(0,0,0,0.30), 0 15px 12px rgba(0,0,0,0.22);
overflow: hidden;
border-top: 8px solid var(--red);
}
pre {
font-family: var(--monospace);
font-size: 16px;
margin-top: 0;
margin-bottom: 1em;
overflow-x: scroll;
scrollbar-width: none;
}
pre::-webkit-scrollbar {
display: none;
}
.message {
line-height: 1.3;
font-weight: 600;
white-space: pre-wrap;
}
.message-body {
color: var(--red);
}
.plugin {
color: var(--purple);
}
.file {
color: var(--cyan);
margin-bottom: 0;
white-space: pre-wrap;
word-break: break-all;
}
.frame {
color: var(--yellow);
}
.stack {
font-size: 13px;
color: var(--dim);
}
.tip {
font-size: 13px;
color: #999;
border-top: 1px dotted #999;
padding-top: 13px;
}
code {
font-size: 13px;
font-family: var(--monospace);
color: var(--yellow);
}
.file-link {
text-decoration: underline;
cursor: pointer;
}
</style>
<div class="window">
<pre class="message"><span class="plugin"></span><span class="message-body"></span></pre>
<pre class="file"></pre>
<pre class="frame"></pre>
<pre class="stack"></pre>
<div class="tip">
Click outside or fix the code to dismiss.<br>
You can also disable this overlay with
<code>hmr: { overlay: false }</code> in <code>vite.config.js.</code>
</div>
</div>
`;
const fileRE = /(?:[a-zA-Z]:\\|\/).*?:\d+:\d+/g;
const codeframeRE = /^(?:>?\s+\d+\s+\|.*|\s+\|\s*\^.*)\r?\n/gm;
class ErrorOverlay extends HTMLElement {
constructor(err) {
var _a;
super();
this.root = this.attachShadow({ mode: 'open' });
this.root.innerHTML = template;
codeframeRE.lastIndex = 0;
const hasFrame = err.frame && codeframeRE.test(err.frame);
const message = hasFrame
? err.message.replace(codeframeRE, '')
: err.message;
if (err.plugin) {
this.text('.plugin', `[plugin:${err.plugin}] `);
}
this.text('.message-body', message.trim());
const [file] = (((_a = err.loc) === null || _a === void 0 ? void 0 : _a.file) || err.id || 'unknown file').split(`?`);
if (err.loc) {
this.text('.file', `${file}:${err.loc.line}:${err.loc.column}`, true);
}
else if (err.id) {
this.text('.file', file);
}
if (hasFrame) {
this.text('.frame', err.frame.trim());
}
this.text('.stack', err.stack, true);
this.root.querySelector('.window').addEventListener('click', (e) => {
e.stopPropagation();
});
this.addEventListener('click', () => {
this.close();
});
}
text(selector, text, linkFiles = false) {
const el = this.root.querySelector(selector);
if (!linkFiles) {
el.textContent = text;
}
else {
target = target[seg] || (target[seg] = {});
let curIndex = 0;
let match;
while ((match = fileRE.exec(text))) {
const { 0: file, index } = match;
if (index != null) {
const frag = text.slice(curIndex, index);
el.appendChild(document.createTextNode(frag));
const link = document.createElement('a');
link.textContent = file;
link.className = 'file-link';
link.onclick = () => {
fetch('/__open-in-editor?file=' + encodeURIComponent(file));
};
el.appendChild(link);
curIndex += frag.length + file.length;
}
}
}
}
});
close() {
var _a;
(_a = this.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(this);
}
}
const overlayId = 'vite-error-overlay';
customElements.define(overlayId, ErrorOverlay);
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');
const base = __BASE__ || '/';
function warnFailedFetch(err, path) {
if (!err.message.match('fetch')) {
console.error(err);
@@ -31,66 +193,65 @@ function warnFailedFetch(err, path) {
}
// Listen for messages
socket.addEventListener('message', async ({ data }) => {
const payload = JSON.parse(data);
if (payload.type === 'multi') {
payload.updates.forEach(handleMessage);
}
else {
handleMessage(payload);
}
handleMessage(JSON.parse(data));
});
let isFirstUpdate = true;
async function handleMessage(payload) {
const { path, changeSrcPath, timestamp } = payload;
switch (payload.type) {
case 'connected':
console.log(`[vite] connected.`);
// proxy(nginx, docker) hmr ws maybe caused timeout,
// so send ping package let ws keep alive.
setInterval(() => socket.send('ping'), __HMR_TIMEOUT__);
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.`);
case 'update':
// if this is the first update and there's already an error overlay, it
// means the page opened with existing server compile error and the whole
// module script failed to load (since one of the nested imports is 500).
// in this case a normal update won't work and a full reload is needed.
if (isFirstUpdate && hasErrorOverlay()) {
window.location.reload();
return;
}
else {
clearErrorOverlay();
isFirstUpdate = false;
}
payload.updates.forEach((update) => {
if (update.type === 'js-update') {
queueUpdate(fetchUpdate(update));
}
else {
// css-update
// this is only sent when a css file referenced with <link> is updated
let { path, timestamp } = update;
path = path.replace(/\?.*/, '');
// can't use querySelector with `[href*=]` here since the link may be
// using relative paths so we need to use link.href to grab the full
// URL for the include check.
const el = [].slice.call(document.querySelectorAll(`link`)).find((e) => e.href.includes(path));
if (el) {
const newPath = `${path}${path.includes('?') ? '&' : '?'}t=${timestamp}`;
el.href = new URL(newPath, el.href).href;
}
console.log(`[vite] css hot updated: ${path}`);
}
});
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);
const cbs = customListenersMap.get(payload.event);
if (cbs) {
cbs.forEach((cb) => cb(payload.customData));
cbs.forEach((cb) => cb(payload.data));
}
break;
case 'full-reload':
if (path.endsWith('.html')) {
if (payload.path && payload.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)) {
const payloadPath = base + payload.path.slice(1);
if (pagePath === payloadPath ||
(pagePath.endsWith('/') && pagePath + 'index.html' === payloadPath)) {
location.reload();
}
return;
@@ -98,8 +259,48 @@ async function handleMessage(payload) {
else {
location.reload();
}
break;
case 'prune':
// After an HMR update, some modules are no longer imported on the page
// but they may have left behind side effects that need to be cleaned up
// (.e.g style injections)
// TODO Trigger their dispose callbacks.
payload.paths.forEach((path) => {
const fn = pruneMap.get(path);
if (fn) {
fn(dataMap.get(path));
}
});
break;
case 'error':
const err = payload.err;
if (enableOverlay) {
createErrorOverlay(err);
}
else {
console.error(`[vite] Internal Server Error\n${err.stack}`);
}
break;
default:
const check = payload;
return check;
}
}
const enableOverlay = __HMR_ENABLE_OVERLAY__;
function createErrorOverlay(err) {
if (!enableOverlay)
return;
clearErrorOverlay();
document.body.appendChild(new ErrorOverlay(err));
}
function clearErrorOverlay() {
document
.querySelectorAll(overlayId)
.forEach((n) => n.close());
}
function hasErrorOverlay() {
return document.querySelectorAll(overlayId).length;
}
let pending = false;
let queued = [];
/**
@@ -119,10 +320,12 @@ async function queueUpdate(p) {
}
}
// ping server
socket.addEventListener('close', () => {
socket.addEventListener('close', ({ wasClean }) => {
if (wasClean)
return;
console.log(`[vite] server connection lost. polling for restart...`);
setInterval(() => {
fetch('/')
fetch(`${base}__vite_ping`)
.then(() => {
location.reload();
})
@@ -131,34 +334,10 @@ socket.addEventListener('close', () => {
});
}, 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) {
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;
@@ -180,7 +359,7 @@ function removeStyle(id) {
if (style) {
if (style instanceof CSSStyleSheet) {
// @ts-ignore
const index = document.adoptedStyleSheets.indexOf(style);
document.adoptedStyleSheets.indexOf(style);
// @ts-ignore
document.adoptedStyleSheets = document.adoptedStyleSheets.filter((s) => s !== style);
}
@@ -190,45 +369,47 @@ function removeStyle(id) {
sheetsMap.delete(id);
}
}
async function updateModule(id, changedPath, timestamp) {
const mod = hotModulesMap.get(id);
async function fetchUpdate({ path, acceptedPath, timestamp }) {
const mod = hotModulesMap.get(path);
if (!mod) {
// In a code-spliting project,
// In a code-splitting 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;
const isSelfUpdate = path === acceptedPath;
// make sure we only import each dep once
const modulesToUpdate = new Set();
if (isSelfUpdate) {
// self update - only update self
modulesToUpdate.add(id);
modulesToUpdate.add(path);
}
else {
// dep update
for (const { deps } of mod.callbacks) {
if (Array.isArray(deps)) {
deps.forEach((dep) => modulesToUpdate.add(dep));
}
else {
modulesToUpdate.add(deps);
}
deps.forEach((dep) => {
if (acceptedPath === dep) {
modulesToUpdate.add(dep);
}
});
}
}
// 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);
const qualifiedCallbacks = mod.callbacks.filter(({ deps }) => {
return deps.some((dep) => modulesToUpdate.has(dep));
});
await Promise.all(Array.from(modulesToUpdate).map(async (dep) => {
const disposer = disposeMap.get(dep);
if (disposer)
await disposer(dataMap.get(dep));
const [path, query] = dep.split(`?`);
try {
const newMod = await import(dep + (dep.includes('?') ? '&' : '?') + `t=${timestamp}`);
const newMod = await import(
/* @vite-ignore */
base +
path.slice(1) +
`?import&t=${timestamp}${query ? `&${query}` : ''}`);
moduleMap.set(dep, newMod);
}
catch (e) {
@@ -236,63 +417,107 @@ async function updateModule(id, changedPath, timestamp) {
}
}));
return () => {
for (const { deps, fn } of callbacks) {
if (Array.isArray(deps)) {
fn(deps.map((dep) => moduleMap.get(dep)));
}
else {
fn(moduleMap.get(deps));
}
for (const { deps, fn } of qualifiedCallbacks) {
fn(deps.map((dep) => moduleMap.get(dep)));
}
console.log(`[vite]: js module hot updated: `, id);
const loggedPath = isSelfUpdate ? path : `${acceptedPath} via ${path}`;
console.log(`[vite] hot updated: ${loggedPath}`);
};
}
const hotModulesMap = new Map();
const disposeMap = new Map();
const pruneMap = new Map();
const dataMap = new Map();
const customUpdateMap = new Map();
export const createHotContext = (id) => {
if (!dataMap.has(id)) {
dataMap.set(id, {});
const customListenersMap = new Map();
const ctxToListenersMap = new Map();
const createHotContext = (ownerPath) => {
if (!dataMap.has(ownerPath)) {
dataMap.set(ownerPath, {});
}
// when a file is hot updated, a new context is created
// clear its stale callbacks
const mod = hotModulesMap.get(id);
const mod = hotModulesMap.get(ownerPath);
if (mod) {
mod.callbacks = [];
}
// clear stale custom event listeners
const staleListeners = ctxToListenersMap.get(ownerPath);
if (staleListeners) {
for (const [event, staleFns] of staleListeners) {
const listeners = customListenersMap.get(event);
if (listeners) {
customListenersMap.set(event, listeners.filter((l) => !staleFns.includes(l)));
}
}
}
const newListeners = new Map();
ctxToListenersMap.set(ownerPath, newListeners);
function acceptDeps(deps, callback = () => { }) {
const mod = hotModulesMap.get(ownerPath) || {
id: ownerPath,
callbacks: []
};
mod.callbacks.push({
deps,
fn: callback
});
hotModulesMap.set(ownerPath, mod);
}
const hot = {
get data() {
return dataMap.get(id);
return dataMap.get(ownerPath);
},
accept(callback = () => { }) {
hot.acceptDeps(id, callback);
accept(deps, callback) {
if (typeof deps === 'function' || !deps) {
// self-accept: hot.accept(() => {})
acceptDeps([ownerPath], ([mod]) => deps && deps(mod));
}
else if (typeof deps === 'string') {
// explicit deps
acceptDeps([deps], ([mod]) => callback && callback(mod));
}
else if (Array.isArray(deps)) {
acceptDeps(deps, callback);
}
else {
throw new Error(`invalid hot.accept() usage.`);
}
},
acceptDeps(deps, callback = () => { }) {
const mod = hotModulesMap.get(id) || {
id,
callbacks: []
};
mod.callbacks.push({
deps: deps,
fn: callback
});
hotModulesMap.set(id, mod);
acceptDeps() {
throw new Error(`hot.acceptDeps() is deprecated. ` +
`Use hot.accept() with the same signature instead.`);
},
dispose(cb) {
disposeMap.set(id, cb);
disposeMap.set(ownerPath, cb);
},
// noop, used for static analysis only
prune(cb) {
pruneMap.set(ownerPath, cb);
},
// TODO
decline() { },
invalidate() {
// TODO should tell the server to re-perform hmr propagation
// from this module as root
location.reload();
},
// custom events
on(event, cb) {
const existing = customUpdateMap.get(event) || [];
existing.push(cb);
customUpdateMap.set(event, existing);
const addToMap = (map) => {
const existing = map.get(event) || [];
existing.push(cb);
map.set(event, existing);
};
addToMap(customListenersMap);
addToMap(newListeners);
}
};
return hot;
};
function injectQuery(url, queryToInject) {
// can't use pathname from URL since it may be relative like ../
const pathname = url.replace(/#.*$/, '').replace(/\?.*$/, '');
const { search, hash } = new URL(url, 'http://vitejs.dev');
return `${pathname}?${queryToInject}${search ? `&` + search.slice(1) : ''}${hash || ''}`;
}
export { createHotContext, injectQuery, removeStyle, updateStyle };

View File

@@ -1,3 +0,0 @@
export declare function jsx(tag: any, props?: null, children?: any): import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>;

View File

@@ -1,13 +0,0 @@
import { createVNode, isVNode } from 'vue';
if (import.meta.env.MODE === 'development') {
console.log(`[vue tip] You are using an non-optimized version of Vue 3 JSX, ` +
`which does not take advantage of Vue 3's runtime fast paths. An improved ` +
`JSX transform will be provided at a later stage.`);
}
const slice = Array.prototype.slice;
export function jsx(tag, props = null, children = null) {
if (arguments.length > 3 || isVNode(children)) {
children = slice.call(arguments, 2);
}
return createVNode(tag, props, children);
}