「仮想DOM革命」書いた
合法ローカルプロキシ
// client
navigator.serviceWorker.register("/sw.js");
// sw.js
self.addEventListener('fetch', event => {
console.log('[fetch on sw]', event.request.url)
})
透過的 PWA
: 既存の振る舞いを守ったまま高速化積極的 PWA
: SW でしか再現できない機能を使う「キャッシュが駄目だったらネットワークへ」
「キャッシュを返しつつ裏でアップデートしておく」
初期化を SW ready まで遅延する
<!-- <script src="./main.js"></script> -->
<script type=module>
(async () => {
await navigator.serviceWorker.register("/sw.js");
await navigator.serviceWorker.ready;
import("./main.js");
})()
</script>
新しい SW に更新されたらリロード強制
const r = await navigator.serviceWorker.register("/sw.js");
navigator.serviceWorker.addEventListener("controllerchange", e =>
window.reload()
);
setInterval(() => r.update(), 1000);
chrome://serviceworker-internals
が友達self.addEventListener("fetch", event => {
event.respondWith(new Response("console.log('hello world')"));
});
import babel from '@babel/standalone'
event.respondWith((async () => {
const res = await fetch(event.request)
return new Response(babel.transform(await res.text()), {
mode: "no-cors",
headers: { "Content-Type": "text/javascript" }
});
})());
});
ServiceWorker で Webpack のエミュレーションすればいいのでは
動いたコード
import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";
ReactDOM.render(<App />, document.querySelector(".root"));
JSX / npm / 拡張子省略 / 相対パス解決
// trans-loader で動くコード
import Redux from 'redux'
Redux.createStore(...)
// 動かないコード
import { createStore } from 'redux'
addEventListener('fetch', event => {
event.respondWith(fetchAndApply(event.request))
})
async function fetchAndApply(request) {
if (request.headers.get('cf-connecting-ip') === '225.0.0.1') {
return new Response('Sorry, this page is not available.',
{ status: 403, statusText: 'Forbidden' })
}
return fetch(request)
}
const html = `
<script>window.initialState = ${JSON.stringify(initialState)};<script>
<body>${ReactDOM.renderToString(<App/ >)}</body>`
event.respondWith(new Request(html, ...))