Впервые опубликовано в публичном аккаунтеПередняя часть от продвинутого до допуска, добро пожаловать, чтобы следовать.
Привет всем, я ssh, и когда я несколько дней назад был в серфинге, я увидел, как Франсуа Вальди объявил, что он сделалbrowser-vite, успешно запустите Vite в браузере. Это вызвало у меня интерес, как запустить Vite, который сильно зависит от узла в браузере? Затем присоединяйтесь ко мне в изучении секретов.
Кратко о принципах
-
Service Worker: HTTP-сервер, используемый для замены Vite.
-
Web Worker: запустить browser-vite для обработки основного потока.
-
Файловая система заменяется файловой системой, эмулируемой в памяти.
-
Конвертируйте импорт со специальными расширениями (.ts, .tsx, .scss…).
проблемы, с которыми столкнулись
нет реальной файловой системы
ViteМного работы делается с файловыми системами. Чтение файлов проекта, прослушивание изменений в файлах, обработка глобусов и т. д. Их сложно реализовать в имитируемой браузером файловой системе в памяти, поэтому браузер-vite удаляет прослушивание, глобы и файлы конфигурации для размещения. Сложность снижается.
Файлы проекта хранятся в файловой системе в памяти, поэтому плагины broswer-vite и vite могут нормально их обрабатывать.
нет "node_modules"
Vite-зависимостиnode_modules
существует для разрешения зависимостей. поставить их на автозагрузкуЗависимость от предварительной сборкиоптимизировать.
Также для уменьшения сложности broswer-vite был тщательно удален из Vite.node_modules
Синтаксический анализ и зависимости предварительно упакованы.
Поэтому пользователям, использующим браузер-vite, необходимо создатьVite pluginдля разрешения импорта голых модулей.
регулярное выражение "обратное утверждение"
Некоторый код в Vite используетретроспективное утверждение. Это нормально в Node.js, но Safari его не поддерживает.
Вот автор и переписывает эти закономерности.
Горячее обновление (HMR)
Вите используетсяWebSocketsдля синхронизации изменений кода между сервером (узлом) и клиентом (браузером).
В браузере-vite сервер — ServiceWorker + Vite worker, а клиент — iframe. Поэтому автор переключил WebSockets на использование почтовых сообщений для iframe.
как использовать
На момент написания этой статьи этот инструмент не готов к использованию «из коробки», и если вы хотите его использовать, вам нужно прочитать множество деталей внутренней обработки Vite.
Если вы заинтересованы, вы можете следить за обновлениямиREADME браузера-viteчтобы получить последнее использование.
Установить
Установите пакет npm для браузера-vite.
$ npm install --save browser-vite
или
$ npm install --save vite@npm:browser-vite
переписать импорт "vite" на "browser-vite"
iframe - окно браузера-vite
iframe требуется для отображения внутренней страницы, обслуживаемой браузером-vite.
Service Worker — встроенный в браузер веб-сервер.
Service Worker перехватывает определенные URL-запросы от iframe.
один используетworkboxпример:
workbox.routing.registerRoute(
/^https?:\/\/HOST/BASE_URL\/(\/.*)$/,
async ({
request,
params,
url,
}: import('workbox-routing/types/RouteHandler').RouteHandlerCallbackContext): Promise<Response> => {
const req = request?.url || url.toString();
const [pathname] = params as string[];
// send the request to vite worker
const response = await postToViteWorker(pathname)
return response;
}
);
В большинстве случаев для отправки сообщений в «Vite Worker» используетсяpostMessageа такжеbroadcast-channel.
Vite Worker — обрабатывает запросы
Vite Worker — это веб-воркер, который обрабатывает запросы, захваченные Service Worker.
Пример создания сервера Vite:
import {
transformWithEsbuild,
ModuleGraph,
transformRequest,
createPluginContainer,
createDevHtmlTransformFn,
resolveConfig,
generateCodeFrame,
ssrTransform,
ssrLoadModule,
ViteDevServer,
PluginOption
} from 'vite';
export async function createServer = async () => {
const config = await resolveConfig(
{
plugins: [
// virtual plugin to provide vite client/env special entries (see below)
viteClientPlugin,
// virtual plugin to resolve NPM dependencies, e.g. using unpkg, skypack or another provider (browser-vite only handles project files)
nodeResolvePlugin,
// add vite plugins you need here (e.g. vue, react, astro ...)
]
base: BASE_URL, // as hooked in service worker
// not really used, but needs to be defined to enable dep optimizations
cacheDir: 'browser',
root: VFS_ROOT,
// any other configuration (e.g. resolve alias)
},
'serve'
);
const plugins = config.plugins;
const pluginContainer = await createPluginContainer(config);
const moduleGraph = new ModuleGraph((url) => pluginContainer.resolveId(url));
const watcher: any = {
on(what: string, cb: any) {
return watcher;
},
add() {},
};
const server: ViteDevServer = {
config,
pluginContainer,
moduleGraph,
transformWithEsbuild,
transformRequest(url, options) {
return transformRequest(url, server, options);
},
ssrTransform,
printUrls() {},
_globImporters: {},
ws: {
send(data) {
// send HMR data to vite client in iframe however you want (post/broadcast-channel ...)
},
async close() {},
on() {},
off() {},
},
watcher,
async ssrLoadModule(url) {
return ssrLoadModule(url, server, loadModule);
},
ssrFixStacktrace() {},
async close() {},
async restart() {},
_optimizeDepsMetadata: null,
_isRunningOptimizer: false,
_ssrExternals: [],
_restartPromise: null,
_forceOptimizeOnRestart: false,
_pendingRequests: new Map(),
};
server.transformIndexHtml = createDevHtmlTransformFn(server);
// apply server configuration hooks from plugins
const postHooks: ((() => void) | void)[] = [];
for (const plugin of plugins) {
if (plugin.configureServer) {
postHooks.push(await plugin.configureServer(server));
}
}
// run post config hooks
// This is applied before the html middleware so that user middleware can
// serve custom content instead of index.html.
postHooks.forEach((fn) => fn && fn());
await pluginContainer.buildStart({});
await runOptimize(server);
return server;
}
Псевдокод для обработки запросов через браузер-vite:
import {
transformRequest,
isCSSRequest,
isDirectCSSRequest,
injectQuery,
removeImportQuery,
unwrapId,
handleFileAddUnlink,
handleHMRUpdate,
} from 'vite/dist/browser';
...
async (req) => {
let { url, accept } = req
const html = accept?.includes('text/html');
// strip ?import
url = removeImportQuery(url);
// Strip valid id prefix. This is prepended to resolved Ids that are
// not valid browser import specifiers by the importAnalysis plugin.
url = unwrapId(url);
// for CSS, we need to differentiate between normal CSS requests and
// imports
if (isCSSRequest(url) && accept?.includes('text/css')) {
url = injectQuery(url, 'direct');
}
let path: string | undefined = url;
try {
let code;
path = url.slice(1);
if (html) {
code = await server.transformIndexHtml(`/${path}`, fs.readFileSync(path,'utf8'));
} else {
const ret = await transformRequest(url, server, { html });
code = ret?.code;
}
// Return code reponse
} catch (err: any) {
// Return error response
}
}
ПроверитьИсходный код внутреннего промежуточного программного обеспечения ViteПолучить больше деталей.
Чем это отличается от веб-контейнеров Stackblitz?
"WebContainers": запустить Node.js в браузере
Веб-контейнеры Stackblitz также могут запускать Vite в браузере. Вы можете изящно перейти на vite.new, чтобы иметь рабочую среду.
Автор говорит, что он не эксперт по WebContainers, но в двух словах, browser-vite эмулирует серверы FS и HTTPS на уровне Vite, WebContainers эмулирует FS и множество других вещей на уровне Node.js, а Vite просто нужно делать. некоторые Дополнительные модификации могут быть запущены на нем.
Он может хранить node_modules в веб-контейнере браузера. Но он не будет запускать npm или пряжу напрямую, вероятно, потому что это займет слишком много места. Они связывают эти команды сTurbo———— их менеджер пакетов.
WebContainers также могут запускать другие фреймворки, такие какRemix,SvelteKitилиAstro.
Это потрясающе ✨Это захватывающе 🤯 Огромный респект команде WebContainer, команда Stackblitz потрясающая!
Одним из недостатков WebContainers является то, что в настоящее времяРаботает только в Chrome, но может быть скороРаботает в Фаерфоксе. В настоящее время browser-vite доступен для браузеров Chrome, Firefox и Safari.
Короче говоря, веб-контейнеры запускают Vite на более низком уровне абстракции. browser-vite работает на более высоком уровне абстракции, очень близком к самому Vite.
Например, browser-vite чем-то напоминает UltraHLE (эмулятор Nintendo N64) для ретро-геймеров 🕹️😊
(*) gametechwiki.com: эмуляторы высокого/низкого уровня
Следующий план автора
browser-vite лежит в основе запланированного автором решения. Намерены постепенно выкатывать на них весь ассортимент продукции:
- Backlight.dev
- Components.studio
- WebComponents.dev
- Replic.dev (скоро появится новое приложение)
В дальнейшем автор будет продолжать инвестировать в браузерное приглашение и создавать отчеты вверх по течению. В прошлом месяце они также объявилиСпонсируйте Эвана Ю и Патака, чтобы поддержать Vite, чтобы поддержать этот замечательный проект.
Хотите узнать больше?
- Репозиторий GitHub:browser-vite
- ПрисоединяйсяDiscord, имеет канал #browser-vite. 🤗
использованная литература
Впервые опубликовано в публичном аккаунтеПередняя часть от продвинутого до допуска, более интересные статьи о внешнем интерфейсе, добро пожаловать на внимание.