https://battle-saga-jp.connpass.com/event/142700/ の発表資料
今日の webpack.config.js はこちら
https://gist.github.com/mizchi/0af8dee5c682a0f9ef8470a089ec41b9
注意: この記事中で出るもののうち、 まだ CDN でのサードパーティモードの publish に成功してない (localhost では動いた…)
https://mdbuf.netlify.com https://github.com/mizchi/mdbuf
- とにかく Markdown のプレビュー速いだけのツール
- WebWorker による off thread compile
- プレビューの差分レンダリング
- コードハイライト
- プレビュー位置の自動追従
- prettier による format
- 数式対応
https://mizchi.hatenablog.com/entry/2018/10/02/093750
要は webworker 使っていこうぜという話
- Main Thread の初期化に 500ms
- Worker Theard の初期化に 200ms
- 重いモジュールを WebWorker に追い出す
- KaTeX のフォントを必要になるまで読まないようにする
- remark とそのプラグイン: 400KB
- prettier/standalone: 1.2MB
これらを Comlink で Worker に追い出す
この辺 https://github.com/mizchi/mdbuf/blob/master/src/worker/index.ts
WebWorker を使いやすくラップしてくれる
// worker thread
import * as comlink from "comlink"
comlink.expose({
async foo() { return 1; }
});
// main thread
import * as comlink from "comlink"
const api = comlink.wrap(new Worker('./worker'));
const ret = await api.foo();
comlink は worker インスタンスを食うだけで、その生成はユーザーが頑張る
importScripts
使いたくない- Webpack で TS+ESM をコンパイルしたい
Webpack で WebWorker で作るぞ!
https://github.com/GoogleChromeLabs/worker-plugin
preact の developit 氏(@Google)
const worker = new Worker('./foo.ts', {type: 'module'});
{type: "module"}
で渡されると Webpack でコンパイルされる。
将来的な仕様に沿っている(らしい)
mdbuf は主にこれ
https://github.com/webpack-contrib/worker-loader
{
test: /\.worker\.ts$/,
use: [
"worker-loader",
"ts-loader"
]
},
import Worker from './foo.worker.ts';
comlink.wrap(new Worker());
loader で new すると Worker インスタンスになる loader。
やりたいこと: Mdbuf を WebComponents で配れるようにしたかった
<x-mdbuf-preview>
# Hello
</x-mdbuf-preview>
mdbuf では worker-loader を使ったが…
「でもお前自作の mdbuf のプレビューできるのそのツールだけじゃん」
<script src="http://localhost:9999/mdbuf-preview.js" async></script>
<!-- 後でできるように -->
<!-- <script src="https://cdn.jsdelivr.net/npm/@mizchi/[email protected]/dist/mdbuf-preview.js"></script>
-->
<mdbuf-preview>
<pre>
---
title: aaa
---
# Markdown Buffer
- Desktop PWA Support
- Autosave
- Off Thread Markdown Compiling
## Markdown
**emphasis** ~~strike~~ _italic_
> Quote
## Math by KaTeX
$ y = x^3 + 2ax^2 + b $
</pre>
</mdbuf-preview>
same origin じゃないと new Worker()
できない…
webpack の chunk を指定する場合、相対パスを与える必要がある
// 抜粋
const WorkerPlugin = require("worker-plugin");
module.exports = {
output: {
publicPath: process.env.ASSET_HOST || "/",
globalObject: "self",
filename: "[name].js"
},
module: {
rules: [
{
test: /\.w\.ts$/,
use: [
{
loader: "worker-loader",
options: {
publicPath: process.env.ASSET_HOST || "/",
inline: true
}
},
'ts-loader'
]
}
]
},
plugins: [
new WorkerPlugin(),
]
};
要はインラインワーカー技法を使う
// インラインワーカーの例
const url = URL.createObjectURL(
new Blob([ "console.log('hello from worker')" ], { type: "text/javascript" })
);
const worker = new Worker(url);
を内部的にやってくれる worker-loader のフラグが inline: true
。文字列が埋め込まれるだけなのでペイロードはあるがパースコストは安い。
これをリリースするエンドポイントに合わせてビルドする(TODO: ちゃんと動かす)
ASSET_HOST="https://cdn.jsdelivr.net/npm/@mizchi/[email protected]/dist/" webpack --mode production
手元でなんか
これが動くらしい
__webpack_public_path__ = process.env.ASSET_PATH;
https://webpack.js.org/guides/public-path/
なのでこれがしたい
__webpack_public_path__ = document.currentScript.url;
あと、CORS 許可が必要で netilfy じゃ動かない! 横着して jsdelivr に相乗りするぞ https://www.jsdelivr.com/package/npm/@mizchi/mdbuf?path=dist
__webpack_public_path__
動かない…(動かせた方がいたら教えて下さい)
そもそも document.currentScript で IE11 で動くポリフィルがない。
https://github.com/JamesMGreene/document.currentScript
(IE6~10 で動くポリフィル。何のために生まれてきたんだ)
Proxy Polyfill を要求する
https://github.com/GoogleChrome/proxy-polyfill
サードパーティなので Proxy を入れたくない。
なので軽量な comlink クローンを作った。
https://gist.github.com/mizchi/bf2735e6e31b5a4c66800c04d112effh