Trying to bend webpack to my will

This commit is contained in:
Surma
2019-02-22 13:15:33 +00:00
parent f24d41ba74
commit 2e478b323a
6 changed files with 60 additions and 10 deletions

6
package-lock.json generated
View File

@@ -3078,9 +3078,9 @@
}
},
"comlink": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/comlink/-/comlink-3.1.1.tgz",
"integrity": "sha512-8H9/mrssKE9B4ZMLcN/2bZd1cukP61SrOjm8vhxpRSN8oCw7MSroNNm3Y7/vPUhK5a2AO55vb20rXm3840l3Pw==",
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/comlink/-/comlink-3.2.0.tgz",
"integrity": "sha512-sxkeOmy35tVBsEThqQcUs6KRlLuFSx//oAAm5QGuoRVmqUZtstfntOy/Ao6Lrzz52+an00JRI/FXWofG3ZeH1g==",
"dev": true
},
"commander": {

View File

@@ -22,12 +22,12 @@
"@webcomponents/custom-elements": "1.2.1",
"@webpack-cli/serve": "0.1.3",
"assets-webpack-plugin": "3.9.10",
"chokidar": "2.1.2",
"chalk": "2.4.2",
"chokidar": "2.1.2",
"classnames": "2.2.6",
"clean-webpack-plugin": "1.0.1",
"comlink": "3.1.1",
"copy-webpack-plugin": "5.0.1",
"comlink": "^3.2.0",
"critters-webpack-plugin": "2.3.0",
"css-loader": "1.0.1",
"ejs": "2.6.1",

View File

@@ -3,6 +3,11 @@ import { SquooshStartEventType, SquooshSideEventType } from '../compress/index';
import { expose } from 'comlink';
export interface ReadyMessage {
type: 'READY';
version: string;
}
export function exposeAPI(app: App) {
self.parent.postMessage({ type: 'READY', version: MAJOR_VERSION }, '*');
self.addEventListener('message', (event: MessageEvent) => {
@@ -10,7 +15,7 @@ export function exposeAPI(app: App) {
return;
}
event.stopImmediatePropagation();
self.parent.postMessage({ type: 'READY', version: MAJOR_VERSION }, '*');
self.parent.postMessage({ type: 'READY', version: MAJOR_VERSION } as ReadyMessage, '*');
});
expose(new API(app), self.parent);
}
@@ -22,9 +27,20 @@ function addRemovableGlobalListener<
return () => document.removeEventListener(name, listener);
}
class API {
/**
* The API class contains the methods that are exposed via Comlink to the outside world.
*/
export class API {
/**
* Internal constructor. Do not call.
*/
constructor(private _app: App) {}
/**
* Loads a given file into Squoosh.
* @param blob The `Blob` to load
* @param name The name of the file. The extension of this name will be used to deterime which decoder to use.
*/
async setFile(blob: Blob, name: string) {
return new Promise((resolve) => {
document.addEventListener(SquooshStartEventType.START, () => resolve(), {
@@ -34,6 +50,10 @@ class API {
});
}
/**
* Grabs one side from Squoosh as a `File`.
* @param side The side which to grab. 0 = left, 1 = right.
*/
async getBlob(side: 0 | 1) {
if (!this._app.state.file || !this._app.compressInstance) {
throw new Error('No file has been loaded');

View File

@@ -72,8 +72,7 @@ export default class App extends Component<Props, State> {
window.addEventListener('popstate', this.onPopState);
import(
/* webpackChunkName: "client-api" */
'./client-api',
).then(m => m.exposeAPI(this));
'./client-api').then(m => m.exposeAPI(this));
}
@bind openFile(file: File | Fileish) {

30
src/sdk.ts Normal file
View File

@@ -0,0 +1,30 @@
import {proxy, ProxyResult} from "comlink";
import {API, ReadyMessage} from "./components/App/client-api";
/**
* This function will load an iFrame
* @param {HTMLIFrameElement} ifr iFrame that will be used to load squoosh
* @param {string} src URL of squoosh instance to use
*/
export default async function loader(ifr: HTMLIFrameElement, src: string = "https://squoosh.app"): Promise<ProxyResult<API>> {
ifr.src = src;
await new Promise(resolve => ifr.onload = resolve);
ifr.contentWindow!.postMessage("READY?", "*");
await new Promise(resolve => {
window.addEventListener("message", function l(ev) {
const msg = ev.data as ReadyMessage;
if(!msg || msg.type !== "READY") {
return;
}
if(msg.version !== MAJOR_VERSION) {
throw Error(`Version mismatch. SDK version ${MAJOR_VERSION}, Squoosh version ${msg.version}`);
}
ev.stopPropagation();
window.removeEventListener("message", l);
resolve();
});
});
return proxy(ifr.contentWindow!);
}

View File

@@ -38,7 +38,8 @@ module.exports = async function (_, env) {
return {
mode: isProd ? 'production' : 'development',
entry: {
'first-interaction': './src/index'
'first-interaction': './src/index',
'sdk': './src/sdk'
},
devtool: isProd ? 'source-map' : 'inline-source-map',
stats: 'minimal',