From e307410301c9058c3749a8e2eb5185938ca63024 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Wed, 15 May 2019 14:55:16 -0600 Subject: [PATCH] A task to inline workers --- package.json | 9 +++- src/ol/worker/version.js | 13 ++++++ tasks/serialize-workers.js | 96 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 src/ol/worker/version.js create mode 100644 tasks/serialize-workers.js diff --git a/package.json b/package.json index d32955ad30..337d1658bf 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "build-index": "npm run build-package && node tasks/generate-index", "build-legacy": "shx rm -rf build && npm run build-index && webpack --config config/webpack-config-legacy-build.js && cleancss --source-map src/ol/ol.css -o build/legacy/ol.css", "copy-css": "shx cp src/ol/ol.css build/ol/ol.css", - "transpile": "shx rm -rf build/ol && shx mkdir -p build/ol && shx cp -rf src/ol build/ol/src && tsc --project config/tsconfig-build.json", + "transpile": "shx rm -rf build/ol && shx mkdir -p build/ol && shx cp -rf src/ol build/ol/src && node tasks/serialize-workers && tsc --project config/tsconfig-build.json", "typecheck": "tsc --pretty", "apidoc": "jsdoc -R config/jsdoc/api/index.md -c config/jsdoc/api/conf.json -P package.json -d build/apidoc" }, @@ -42,7 +42,7 @@ }, "devDependencies": { "@babel/core": "^7.4.0", - "@babel/preset-env": "^7.4.2", + "@babel/preset-env": "^7.4.4", "@openlayers/eslint-plugin": "^4.0.0-beta.2", "@types/arcgis-rest-api": "^10.4.4", "@types/geojson": "^7946.0.7", @@ -85,6 +85,11 @@ "pngjs": "^3.4.0", "proj4": "2.5.0", "puppeteer": "~1.16.0", + "rollup": "^1.12.0", + "rollup-plugin-babel": "^4.3.2", + "rollup-plugin-commonjs": "^10.0.0", + "rollup-plugin-node-resolve": "^5.0.0", + "rollup-plugin-terser": "^4.0.4", "serve-static": "^1.14.0", "shx": "^0.3.2", "sinon": "^7.3.2", diff --git a/src/ol/worker/version.js b/src/ol/worker/version.js new file mode 100644 index 0000000000..0c466b8bcd --- /dev/null +++ b/src/ol/worker/version.js @@ -0,0 +1,13 @@ +/** + * @module ol/worker/version + * A worker that responds to messages by posting a message with the version identifer. + */ +import {VERSION} from '../util'; + +onmessage = event => { + console.log('version worker received message:', event.data); // eslint-disable-line + // @ts-ignore + postMessage(`version: ${VERSION}`); +}; + +export let create; diff --git a/tasks/serialize-workers.js b/tasks/serialize-workers.js new file mode 100644 index 0000000000..dbf7e12c1c --- /dev/null +++ b/tasks/serialize-workers.js @@ -0,0 +1,96 @@ +const path = require('path'); +const babel = require('rollup-plugin-babel'); +const resolve = require('rollup-plugin-node-resolve'); +const common = require('rollup-plugin-commonjs'); +const rollup = require('rollup'); +const terser = require('rollup-plugin-terser').terser; +const fse = require('fs-extra'); + +async function build(input, {minify = true} = {}) { + const plugins = [ + { + name: 'remove export let create', + transform(code, id) { + if (id !== input) { + return null; + } + return code.replace('export let create;\n', ''); + } + }, + common(), + resolve(), + babel({ + 'presets': [ + [ + '@babel/preset-env', + { + 'modules': false, + 'targets': 'last 2 version, not dead' + } + ] + ] + }), + { + name: 'serialize worker and export create function', + renderChunk(code) { + return ` + const source = ${JSON.stringify(code)}; + const blob = new Blob([source], {type: 'application/javascript'}); + const url = URL.createObjectURL(blob); + export function create() { + return new Worker(url); + } + `; + } + } + ]; + + if (minify) { + plugins.push(terser()); + } + + const bundle = await rollup.rollup({input, plugins}); + const {output} = await bundle.generate({format: 'es'}); + + if (output.length !== 1) { + throw new Error(`Unexpected output length: ${output.length}`); + } + + const chunk = output[0]; + if (chunk.isAsset) { + throw new Error('Expected a chunk, got an asset'); + } + + return chunk; +} + +exports.build = build; + + +/** + * Creates modules with inlined versions of the worker sources. These modules + * export a `create` function for creating a worker. + */ +async function main() { + const inputDir = path.join(__dirname, '../src/ol/worker'); + const outputDir = path.join(__dirname, '../build/ol/src/worker'); + + await fse.ensureDir(outputDir); + + const entries = await fse.readdir(inputDir); + for (const entry of entries) { + if (!entry.endsWith('.js')) { + continue; + } + + const chunk = await build(path.join(inputDir, entry)); + await fse.writeFile(path.join(outputDir, entry), chunk.code); + } +} + +if (require.main === module) { + main().catch(err => { + process.stderr.write(`${err.stack}\n`); + process.exit(1); + }); +}