somewhat works, but not everything we need

it's missing still:
 - non-css assets like the download sandbox and the olm worker aren't written for some reason
 - the es and cjs lib.js entry points end up in assets with a hash for some reason
 - in these entry files, apart from our exports, something is adding an import statement for every import that was found in the tree
 - all assets are hashed even though the config tries to disable that
 - tests are included
This commit is contained in:
Bruno Windels 2021-12-17 14:28:25 +01:00
parent 14b854ad4f
commit ceb0b5793b
11 changed files with 118 additions and 50 deletions

View file

@ -2,7 +2,6 @@
"name": "hydrogen-web", "name": "hydrogen-web",
"version": "0.2.22", "version": "0.2.22",
"description": "A javascript matrix client prototype, trying to minize RAM usage by offloading as much as possible to IndexedDB", "description": "A javascript matrix client prototype, trying to minize RAM usage by offloading as much as possible to IndexedDB",
"main": "src/lib.ts",
"directories": { "directories": {
"doc": "doc" "doc": "doc"
}, },
@ -12,7 +11,8 @@
"lint-ci": "eslint src/", "lint-ci": "eslint src/",
"test": "impunity --entry-point src/platform/web/main.js src/platform/web/Platform.js --force-esm-dirs lib/ src/ --root-dir src/", "test": "impunity --entry-point src/platform/web/main.js src/platform/web/Platform.js --force-esm-dirs lib/ src/ --root-dir src/",
"start": "vite --port 3000", "start": "vite --port 3000",
"build": "vite build" "build": "vite build",
"build:sdk": "./scripts/sdk/build.sh"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View file

@ -12,6 +12,7 @@ function injectServiceWorker(swFile, otherUnhashedFiles, placeholdersPerChunk) {
const swName = path.basename(swFile); const swName = path.basename(swFile);
let root; let root;
let version; let version;
let logger;
return { return {
name: "hydrogen:injectServiceWorker", name: "hydrogen:injectServiceWorker",
@ -27,6 +28,7 @@ function injectServiceWorker(swFile, otherUnhashedFiles, placeholdersPerChunk) {
configResolved: config => { configResolved: config => {
root = config.root; root = config.root;
version = JSON.parse(config.define.DEFINE_VERSION); // unquote version = JSON.parse(config.define.DEFINE_VERSION); // unquote
logger = config.logger;
}, },
generateBundle: async function(options, bundle) { generateBundle: async function(options, bundle) {
const unhashedFilenames = [swName].concat(otherUnhashedFiles); const unhashedFilenames = [swName].concat(otherUnhashedFiles);
@ -46,7 +48,7 @@ function injectServiceWorker(swFile, otherUnhashedFiles, placeholdersPerChunk) {
...getCacheFileNamePlaceholderValues(swName, unhashedFilenames, assets, placeholdersPerChunk) ...getCacheFileNamePlaceholderValues(swName, unhashedFilenames, assets, placeholdersPerChunk)
}; };
replacePlaceholdersInChunks(assets, placeholdersPerChunk, placeholderValues); replacePlaceholdersInChunks(assets, placeholdersPerChunk, placeholderValues);
console.log(`\nBuilt ${version} (${globalHash})`); logger.info(`\nBuilt ${version} (${globalHash})`);
} }
}; };
} }

3
scripts/sdk/build.sh Executable file
View file

@ -0,0 +1,3 @@
yarn run vite build -c vite.sdk-config.js
yarn tsc -p tsconfig-declaration.json
./scripts/sdk/create-manifest.js ./target/package.json

21
scripts/sdk/create-manifest.js Executable file
View file

@ -0,0 +1,21 @@
#!/usr/bin/env node
const fs = require("fs");
const baseManifest = JSON.parse(fs.readFileSync("package.json", "utf8"));
const mergeOptions = require('merge-options');
const manifestExtension = {
name: "hydrogen-sdk",
main: "./hydrogen.cjs.js",
exports: {
import: "./hydrogen.es.js",
require: "./hydrogen.cjs.js"
},
files: [],
types: "types/lib.d.ts",
devDependencies: undefined,
scripts: undefined,
};
const manifest = mergeOptions(baseManifest, manifestExtension);
const json = JSON.stringify(manifest, undefined, 2);
const outFile = process.argv[2];
fs.writeFileSync(outFile, json, {encoding: "utf8"});

View file

@ -1,43 +0,0 @@
const path = require("path");
const mergeOptions = require('merge-options').bind({concatArrays: true});
const commonOptions = require("./vite.common-config.js");
const srcDir = path.join(__dirname, "src/");
const modulesDir = path.join(srcDir, "node_modules/");
const mocksDir = path.join(srcDir, "mocks/");
const fixturesDir = path.join(srcDir, "fixtures/");
export default mergeOptions(commonOptions, {
root: "src/",
build: {
outDir: "../target",
lib: {
entry: "lib.ts",
fileName: "hydrogen",
formats: ["cjs", "es"]
},
rollupOptions: {
external: (id, parentId) => {
const resolveId = (id.startsWith("./") || id.startsWith("../")) ? path.join(path.dirname(parentId), id) : id;
return !resolveId.startsWith(srcDir) || resolveId.startsWith(mocksDir) || resolveId.startsWith(fixturesDir);
},
output: {
manualChunks: (id) => {
if (id.startsWith(srcDir)) {
const idPath = id.substring(srcDir.length);
const pathWithoutExt = idPath.substring(0, idPath.lastIndexOf("."));
return pathWithoutExt;
} else {
return "index";
}
},
chunkFileNames: `[format]/[name].js`,
// important to preserve export names of every module
// so we can still override the file and provider alternative impls
minifyInternalExports: false,
preferConst: true,
}
}
},
});

16
src/foo-index.html Normal file
View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" type="text/css" href="./platform/web/ui/css/main.css">
<link rel="stylesheet" type="text/css" href="./platform/web/ui/css/themes/element/theme.css">
</head>
<body>
<script type="module">
export * from "./lib.ts";
import downloadSandboxPath from "./platform/web/assets/download-sandbox.html?url";
import workerPath from "./platform/web/worker/main.js?url";
</script>
</body>
</html>

View file

@ -32,5 +32,11 @@ export {RoomView} from "./platform/web/ui/session/room/RoomView.js";
export {TimelineViewModel} from "./domain/session/room/timeline/TimelineViewModel.js"; export {TimelineViewModel} from "./domain/session/room/timeline/TimelineViewModel.js";
export {TimelineView} from "./platform/web/ui/session/room/TimelineView"; export {TimelineView} from "./platform/web/ui/session/room/TimelineView";
// @ts-ignore
export * from "./platform/web/ui/css/main.css"; export * from "./platform/web/ui/css/main.css";
// @ts-ignore
export * from "./platform/web/ui/css/themes/element/theme.css"; export * from "./platform/web/ui/css/themes/element/theme.css";
// @ts-ignore
import _downloadSandboxPath from "./platform/web/assets/download-sandbox.html?url";
// @ts-ignore
import _workerPath from "./platform/web/worker/main.js?url";

View file

@ -4,7 +4,7 @@
"noEmit": false, "noEmit": false,
"emitDeclarationOnly": true, "emitDeclarationOnly": true,
"declaration": true, "declaration": true,
"outDir": "dist/types", "outDir": "target/types",
"rootDir": "src" "rootDir": "src"
}, },
"exclude": [ "exclude": [

View file

@ -5,7 +5,7 @@ const path = require("path");
const version = JSON.parse(fs.readFileSync(path.join(__dirname, "package.json"), "utf8")).version; const version = JSON.parse(fs.readFileSync(path.join(__dirname, "package.json"), "utf8")).version;
const commonOptions = { const commonOptions = {
logLevel: "warn", logLevel: "info",
public: false, public: false,
server: { server: {
hmr: false hmr: false
@ -21,8 +21,6 @@ const commonOptions = {
}, },
build: { build: {
emptyOutDir: true, emptyOutDir: true,
minify: true,
sourcemap: true,
assetsInlineLimit: 0, assetsInlineLimit: 0,
polyfillModulePreload: false, polyfillModulePreload: false,
}, },

View file

@ -11,6 +11,8 @@ export default defineConfig(({mode}) => {
base: "./", base: "./",
build: { build: {
outDir: "../../../target", outDir: "../../../target",
minify: true,
sourcemap: true,
}, },
plugins: [ plugins: [
// important this comes before service worker // important this comes before service worker

63
vite.sdk-config.js Normal file
View file

@ -0,0 +1,63 @@
const path = require("path");
const mergeOptions = require('merge-options').bind({concatArrays: true});
const commonOptions = require("./vite.common-config.js");
const srcDir = path.join(__dirname, "src/");
const modulesDir = path.join(srcDir, "node_modules/");
const mocksDir = path.join(srcDir, "mocks/");
const fixturesDir = path.join(srcDir, "fixtures/");
const commonOutput = {
manualChunks: (id) => {
if (id.endsWith("/lib.ts")) {
console.log(id, arguments);
return "es/lib";
}
if (id.startsWith(srcDir)) {
const idPath = id.substring(srcDir.length);
const pathWithoutExt = idPath.substring(0, idPath.lastIndexOf("."));
return pathWithoutExt;
} else {
return "index";
}
},
chunkFileNames: `[format]/[name].js`,
assetFileNames: `assets/[name][extname]`,
// important to preserve export names of every module
// so we can still override the file and provider alternative impls
minifyInternalExports: false,
preferConst: true,
};
export default mergeOptions(commonOptions, {
root: "src/",
plugins: [
{
name: "showconfig",
buildStart(rollupOptions) {
console.dir(rollupOptions, {depth: 100});
},
resolveId(source, importer) {
console.log(source, importer);
}
}
],
build: {
minify: false,
sourcemap: false,
outDir: "../target",
rollupOptions: {
input: "./src/lib.ts",
treeshake: false,
external: (id, parentId) => {
const resolveId = (id.startsWith("./") || id.startsWith("../")) ? path.join(path.dirname(parentId), id) : id;
return !resolveId.startsWith(srcDir) || resolveId.startsWith(mocksDir) || resolveId.startsWith(fixturesDir);
},
preserveEntrySignatures: "strict",
output: [
Object.assign({}, commonOutput, {format: "es"}),
Object.assign({}, commonOutput, {format: "cjs"}),
]
}
},
});