Make service worker work with sdk

This commit is contained in:
R Midhun Suresh 2024-08-16 15:33:39 +05:30
parent 3967d26f9d
commit 8f7d94eb75
No known key found for this signature in database
7 changed files with 333 additions and 200 deletions

View File

@ -1,6 +1,5 @@
const fs = require('fs/promises'); const path = require("path");
const path = require('path'); const xxhash = require("xxhashjs");
const xxhash = require('xxhashjs');
function contentHash(str) { function contentHash(str) {
var hasher = new xxhash.h32(0); var hasher = new xxhash.h32(0);
@ -8,16 +7,21 @@ function contentHash(str) {
return hasher.digest(); return hasher.digest();
} }
function injectServiceWorker(swFile, findUnhashedFileNamesFromBundle, placeholdersPerChunk) { function injectServiceWorker(
swFile,
findUnhashedFileNamesFromBundle,
placeholdersPerChunk
) {
const swName = path.basename(swFile); const swName = path.basename(swFile);
let root;
let version; let version;
let logger; let logger;
let mode;
return { return {
name: "hydrogen:injectServiceWorker", name: "hydrogen:injectServiceWorker",
apply: "build", apply: "build",
enforce: "post", enforce: "post",
buildStart() { buildStart() {
this.emitFile({ this.emitFile({
type: "chunk", type: "chunk",
@ -25,39 +29,63 @@ function injectServiceWorker(swFile, findUnhashedFileNamesFromBundle, placeholde
id: swFile, id: swFile,
}); });
}, },
configResolved: config => {
root = config.root; configResolved: (config) => {
mode = config.mode;
version = JSON.parse(config.define.DEFINE_VERSION); // unquote version = JSON.parse(config.define.DEFINE_VERSION); // unquote
logger = config.logger; logger = config.logger;
}, },
generateBundle: async function(options, bundle) {
generateBundle: async function (options, bundle) {
const otherUnhashedFiles = findUnhashedFileNamesFromBundle(bundle); const otherUnhashedFiles = findUnhashedFileNamesFromBundle(bundle);
const unhashedFilenames = [swName].concat(otherUnhashedFiles); const unhashedFilenames = [swName].concat(otherUnhashedFiles);
const unhashedFileContentMap = unhashedFilenames.reduce((map, fileName) => { const unhashedFileContentMap = unhashedFilenames.reduce(
const chunkOrAsset = bundle[fileName]; (map, fileName) => {
if (!chunkOrAsset) { const chunkOrAsset = bundle[fileName];
throw new Error("could not get content for uncached asset or chunk " + fileName); if (!chunkOrAsset) {
} throw new Error(
map[fileName] = chunkOrAsset.source || chunkOrAsset.code; "could not get content for uncached asset or chunk " +
return map; fileName
}, {}); );
}
map[fileName] = chunkOrAsset.source || chunkOrAsset.code;
return map;
},
{}
);
const assets = Object.values(bundle); const assets = Object.values(bundle);
const hashedFileNames = assets.map(o => o.fileName).filter(fileName => !unhashedFileContentMap[fileName]); const hashedFileNames = assets
const globalHash = getBuildHash(hashedFileNames, unhashedFileContentMap); .map((o) => o.fileName)
.filter((fileName) => !unhashedFileContentMap[fileName]);
const globalHash = getBuildHash(
hashedFileNames,
unhashedFileContentMap
);
const placeholderValues = { const placeholderValues = {
DEFINE_GLOBAL_HASH: `"${globalHash}"`, DEFINE_GLOBAL_HASH: `"${globalHash}"`,
...getCacheFileNamePlaceholderValues(swName, unhashedFilenames, assets, placeholdersPerChunk) ...getCacheFileNamePlaceholderValues(
swName,
unhashedFilenames,
assets,
mode
),
}; };
replacePlaceholdersInChunks(assets, placeholdersPerChunk, placeholderValues); replacePlaceholdersInChunks(
assets,
placeholdersPerChunk,
placeholderValues
);
logger.info(`\nBuilt ${version} (${globalHash})`); logger.info(`\nBuilt ${version} (${globalHash})`);
} },
}; };
} }
function getBuildHash(hashedFileNames, unhashedFileContentMap) { function getBuildHash(hashedFileNames, unhashedFileContentMap) {
const unhashedHashes = Object.entries(unhashedFileContentMap).map(([fileName, content]) => { const unhashedHashes = Object.entries(unhashedFileContentMap).map(
return `${fileName}-${contentHash(Buffer.from(content))}`; ([fileName, content]) => {
}); return `${fileName}-${contentHash(Buffer.from(content))}`;
}
);
const globalHashAssets = hashedFileNames.concat(unhashedHashes); const globalHashAssets = hashedFileNames.concat(unhashedHashes);
globalHashAssets.sort(); globalHashAssets.sort();
return contentHash(globalHashAssets.join(",")).toString(); return contentHash(globalHashAssets.join(",")).toString();
@ -66,60 +94,87 @@ function getBuildHash(hashedFileNames, unhashedFileContentMap) {
const NON_PRECACHED_JS = [ const NON_PRECACHED_JS = [
"hydrogen-legacy", "hydrogen-legacy",
"olm_legacy.js", "olm_legacy.js",
// most environments don't need the worker // most environments don't need the worker
"main.js" "main.js",
]; ];
function isPreCached(asset) { function isPreCached(asset) {
const {name, fileName} = asset; const { name, fileName } = asset;
return name.endsWith(".svg") || return (
name.endsWith(".png") || name?.endsWith(".svg") ||
name.endsWith(".css") || name?.endsWith(".png") ||
name.endsWith(".wasm") || name?.endsWith(".css") ||
name.endsWith(".html") || name?.endsWith(".wasm") ||
// the index and vendor chunks don't have an extension in `name`, so check extension on `fileName` name?.endsWith(".html") ||
fileName.endsWith(".js") && !NON_PRECACHED_JS.includes(path.basename(name)); // the index and vendor chunks don't have an extension in `name`, so check extension on `fileName`
(fileName.endsWith(".js") &&
!NON_PRECACHED_JS.includes(path.basename(name)))
);
} }
function getCacheFileNamePlaceholderValues(swName, unhashedFilenames, assets) { function getCacheFileNamePlaceholderValues(
swName,
unhashedFilenames,
assets,
mode
) {
const unhashedPreCachedAssets = []; const unhashedPreCachedAssets = [];
const hashedPreCachedAssets = []; const hashedPreCachedAssets = [];
const hashedCachedOnRequestAssets = []; const hashedCachedOnRequestAssets = [];
for (const asset of assets) { if (mode === "production") {
const {name, fileName} = asset; for (const asset of assets) {
// the service worker should not be cached at all, const { name, fileName } = asset;
// it's how updates happen // the service worker should not be cached at all,
if (fileName === swName) { // it's how updates happen
continue; if (fileName === swName) {
} else if (unhashedFilenames.includes(fileName)) { continue;
unhashedPreCachedAssets.push(fileName); } else if (unhashedFilenames.includes(fileName)) {
} else if (isPreCached(asset)) { unhashedPreCachedAssets.push(fileName);
hashedPreCachedAssets.push(fileName); } else if (isPreCached(asset)) {
} else { hashedPreCachedAssets.push(fileName);
hashedCachedOnRequestAssets.push(fileName); } else {
hashedCachedOnRequestAssets.push(fileName);
}
} }
} }
return { return {
DEFINE_UNHASHED_PRECACHED_ASSETS: JSON.stringify(unhashedPreCachedAssets), DEFINE_UNHASHED_PRECACHED_ASSETS: JSON.stringify(
unhashedPreCachedAssets
),
DEFINE_HASHED_PRECACHED_ASSETS: JSON.stringify(hashedPreCachedAssets), DEFINE_HASHED_PRECACHED_ASSETS: JSON.stringify(hashedPreCachedAssets),
DEFINE_HASHED_CACHED_ON_REQUEST_ASSETS: JSON.stringify(hashedCachedOnRequestAssets) DEFINE_HASHED_CACHED_ON_REQUEST_ASSETS: JSON.stringify(
} hashedCachedOnRequestAssets
),
};
} }
function replacePlaceholdersInChunks(assets, placeholdersPerChunk, placeholderValues) { function replacePlaceholdersInChunks(
assets,
placeholdersPerChunk,
placeholderValues
) {
for (const [name, placeholderMap] of Object.entries(placeholdersPerChunk)) { for (const [name, placeholderMap] of Object.entries(placeholdersPerChunk)) {
const chunk = assets.find(a => a.type === "chunk" && a.name === name); const chunk = assets.find((a) => a.type === "chunk" && a.name === name);
if (!chunk) { if (!chunk) {
throw new Error(`could not find chunk ${name} to replace placeholders`); throw new Error(
`could not find chunk ${name} to replace placeholders`
);
} }
for (const [placeholderName, placeholderLiteral] of Object.entries(placeholderMap)) { for (const [placeholderName, placeholderLiteral] of Object.entries(
placeholderMap
)) {
const replacedValue = placeholderValues[placeholderName]; const replacedValue = placeholderValues[placeholderName];
const oldCode = chunk.code; const oldCode = chunk.code;
chunk.code = chunk.code.replaceAll(placeholderLiteral, replacedValue); chunk.code = chunk.code.replaceAll(
placeholderLiteral,
replacedValue
);
if (chunk.code === oldCode) { if (chunk.code === oldCode) {
throw new Error(`Could not replace ${placeholderName} in ${name}, looking for literal ${placeholderLiteral}:\n${chunk.code}`); throw new Error(
`Could not replace ${placeholderName} in ${name}, looking for literal ${placeholderLiteral}`
);
} }
} }
} }
@ -134,7 +189,7 @@ function replacePlaceholdersInChunks(assets, placeholdersPerChunk, placeholderVa
* transformation will touch them (minifying, ...) and we can do a * transformation will touch them (minifying, ...) and we can do a
* string replacement still at the end of the build. */ * string replacement still at the end of the build. */
function definePlaceholderValue(mode, name, devValue) { function definePlaceholderValue(mode, name, devValue) {
if (mode === "production") { if (mode === "production" || mode === "sdk") {
// note that `prompt(...)` will never be in the final output, it's replaced by the final value // note that `prompt(...)` will never be in the final output, it's replaced by the final value
// once we know at the end of the build what it is and just used as a temporary value during the build // once we know at the end of the build what it is and just used as a temporary value during the build
// as something that will not be transformed. // as something that will not be transformed.
@ -145,13 +200,40 @@ function definePlaceholderValue(mode, name, devValue) {
} }
} }
/**
* Returns the short sha for the latest git commit
* @see https://stackoverflow.com/a/35778030
*/
function getLatestGitCommitHash() {
return require("child_process")
.execSync("git rev-parse --short HEAD")
.toString()
.trim();
}
function createPlaceholderValues(mode) { function createPlaceholderValues(mode) {
return { return {
DEFINE_GLOBAL_HASH: definePlaceholderValue(mode, "DEFINE_GLOBAL_HASH", null), DEFINE_GLOBAL_HASH: definePlaceholderValue(
DEFINE_UNHASHED_PRECACHED_ASSETS: definePlaceholderValue(mode, "UNHASHED_PRECACHED_ASSETS", []), mode,
DEFINE_HASHED_PRECACHED_ASSETS: definePlaceholderValue(mode, "HASHED_PRECACHED_ASSETS", []), "DEFINE_GLOBAL_HASH",
DEFINE_HASHED_CACHED_ON_REQUEST_ASSETS: definePlaceholderValue(mode, "HASHED_CACHED_ON_REQUEST_ASSETS", []), `git commit: ${getLatestGitCommitHash()}`
),
DEFINE_UNHASHED_PRECACHED_ASSETS: definePlaceholderValue(
mode,
"UNHASHED_PRECACHED_ASSETS",
[]
),
DEFINE_HASHED_PRECACHED_ASSETS: definePlaceholderValue(
mode,
"HASHED_PRECACHED_ASSETS",
[]
),
DEFINE_HASHED_CACHED_ON_REQUEST_ASSETS: definePlaceholderValue(
mode,
"HASHED_CACHED_ON_REQUEST_ASSETS",
[]
),
}; };
} }
module.exports = {injectServiceWorker, createPlaceholderValues}; module.exports = { injectServiceWorker, createPlaceholderValues };

View File

@ -8,8 +8,8 @@ shopt -s extglob
# Only remove the directory contents instead of the whole directory to maintain # Only remove the directory contents instead of the whole directory to maintain
# the `npm link`/`yarn link` symlink # the `npm link`/`yarn link` symlink
rm -rf target/* rm -rf target/*
yarn run vite build -c vite.sdk-assets-config.js yarn run vite build -c vite.sdk-assets-config.js --mode sdk
yarn run vite build -c vite.sdk-lib-config.js yarn run vite build -c vite.sdk-lib-config.js --mode sdk
yarn tsc -p tsconfig-declaration.json yarn tsc -p tsconfig-declaration.json
./scripts/sdk/create-manifest.js ./target/package.json ./scripts/sdk/create-manifest.js ./target/package.json
mkdir target/paths mkdir target/paths

View File

@ -103,8 +103,22 @@ export class ServiceWorkerHandler {
if (document.hidden) { if (document.hidden) {
return; return;
} }
const version = await this._sendAndWaitForReply("version", null, this._registration.waiting); const version = await this._sendAndWaitForReply(
if (confirm(`Version ${version.version} (${version.buildHash}) is available. Reload to apply?`)) { "version",
null,
this._registration.waiting
);
const isSdk = DEFINE_IS_SDK;
const isDev = this.version === "develop";
// Don't ask for confirmation when being used as an sdk/ when being run in dev server
if (
isSdk ||
isDev ||
confirm(
`Version ${version.version} (${version.buildHash}) is available. Reload to apply?`
)
) {
console.log("Service Worker has been updated!");
// prevent any fetch requests from going to the service worker // prevent any fetch requests from going to the service worker
// from any client, so that it is not kept active // from any client, so that it is not kept active
// when calling skipWaiting on the new one // when calling skipWaiting on the new one

View File

@ -1,59 +1,78 @@
const cssvariables = require("postcss-css-variables"); const {
createPlaceholderValues,
} = require("./scripts/build-plugins/service-worker");
const flexbugsFixes = require("postcss-flexbugs-fixes"); const flexbugsFixes = require("postcss-flexbugs-fixes");
const compileVariables = require("./scripts/postcss/css-compile-variables"); const compileVariables = require("./scripts/postcss/css-compile-variables");
const urlVariables = require("./scripts/postcss/css-url-to-variables"); const urlVariables = require("./scripts/postcss/css-url-to-variables");
const urlProcessor = require("./scripts/postcss/css-url-processor"); const urlProcessor = require("./scripts/postcss/css-url-processor");
const fs = require("fs"); const appManifest = require("./package.json");
const path = require("path"); const sdkManifest = require("./scripts/sdk/base-manifest.json");
const manifest = require("./package.json");
const version = manifest.version;
const compiledVariables = new Map(); const compiledVariables = new Map();
import {buildColorizedSVG as replacer} from "./scripts/postcss/svg-builder.mjs"; import { buildColorizedSVG as replacer } from "./scripts/postcss/svg-builder.mjs";
import {derive} from "./src/platform/web/theming/shared/color.mjs"; import { derive } from "./src/platform/web/theming/shared/color.mjs";
const commonOptions = { const commonOptions = (mode) => {
logLevel: "warn", const definePlaceholders = createPlaceholderValues(mode);
publicDir: false, return {
server: { logLevel: "warn",
hmr: false publicDir: false,
}, server: {
resolve: { hmr: false,
alias: { },
// these should only be imported by the base-x package in any runtime code resolve: {
// and works in the browser with a Uint8Array shim, alias: {
// rather than including a ton of polyfill code // these should only be imported by the base-x package in any runtime code
"safe-buffer": "./scripts/package-overrides/safe-buffer/index.js", // and works in the browser with a Uint8Array shim,
"buffer": "./scripts/package-overrides/buffer/index.js", // rather than including a ton of polyfill code
} "safe-buffer":
}, "./scripts/package-overrides/safe-buffer/index.js",
build: { buffer: "./scripts/package-overrides/buffer/index.js",
emptyOutDir: true, },
assetsInlineLimit: 0, },
polyfillModulePreload: false, build: {
}, emptyOutDir: true,
assetsInclude: ['**/config.json'], assetsInlineLimit: 0,
define: { polyfillModulePreload: false,
DEFINE_VERSION: JSON.stringify(version), },
DEFINE_GLOBAL_HASH: JSON.stringify(null), assetsInclude: ["**/config.json"],
}, define: Object.assign(
css: { {
postcss: { DEFINE_VERSION: `"${getVersion(mode)}"`,
plugins: [ DEFINE_GLOBAL_HASH: JSON.stringify(null),
compileVariables({derive, compiledVariables}), DEFINE_IS_SDK: mode === "sdk" ? "true" : "false",
urlVariables({compiledVariables}), DEFINE_PROJECT_DIR: JSON.stringify(__dirname),
urlProcessor({replacer}), },
// cssvariables({ definePlaceholders
// preserve: (declaration) => { ),
// return declaration.value.indexOf("var(--ios-") == 0; css: {
// } postcss: {
// }), plugins: [
// the grid option creates some source fragment that causes the vite warning reporter to crash because compileVariables({ derive, compiledVariables }),
// it wants to log a warning on a line that does not exist in the source fragment. urlVariables({ compiledVariables }),
// autoprefixer({overrideBrowserslist: ["IE 11"], grid: "no-autoplace"}), urlProcessor({ replacer }),
flexbugsFixes() flexbugsFixes(),
] ],
} },
} },
};
}; };
/**
* Get the version for this build
* @param mode Vite mode for this build
* @returns string representing version
*/
function getVersion(mode) {
if (mode === "production") {
// This is an app build, so return the version from root/package.json
return appManifest.version;
} else if (mode === "sdk") {
// For the sdk build, return version from base-manifest.json
return sdkManifest.version;
} else {
// For the develop server
return "develop";
}
}
module.exports = { commonOptions, compiledVariables }; module.exports = { commonOptions, compiledVariables };

View File

@ -1,15 +1,20 @@
const injectWebManifest = require("./scripts/build-plugins/manifest"); const injectWebManifest = require("./scripts/build-plugins/manifest");
const {injectServiceWorker, createPlaceholderValues} = require("./scripts/build-plugins/service-worker"); const {injectServiceWorker, createPlaceholderValues} = require("./scripts/build-plugins/service-worker");
const {
transformServiceWorkerInDevServer,
} = require("./scripts/build-plugins/sw-dev");
const themeBuilder = require("./scripts/build-plugins/rollup-plugin-build-themes"); const themeBuilder = require("./scripts/build-plugins/rollup-plugin-build-themes");
const {defineConfig} = require('vite'); const { defineConfig } = require("vite");
const mergeOptions = require('merge-options').bind({concatArrays: true}); const mergeOptions = require("merge-options").bind({ concatArrays: true });
const {commonOptions, compiledVariables} = require("./vite.common-config.js"); const { commonOptions, compiledVariables } = require("./vite.common-config.js");
export default defineConfig(({mode}) => { export default defineConfig(({ mode }) => {
const definePlaceholders = createPlaceholderValues(mode); const definePlaceholders = createPlaceholderValues(mode);
return mergeOptions(commonOptions, { const options = commonOptions(mode);
return mergeOptions(options, {
root: "src/platform/web", root: "src/platform/web",
base: "./", base: "./",
publicDir: "./public",
build: { build: {
outDir: "../../../target", outDir: "../../../target",
minify: true, minify: true,
@ -19,18 +24,17 @@ export default defineConfig(({mode}) => {
assetFileNames: (asset) => { assetFileNames: (asset) => {
if (asset.name.includes("config.json")) { if (asset.name.includes("config.json")) {
return "[name][extname]"; return "[name][extname]";
} } else if (asset.name.match(/theme-.+\.json/)) {
else if (asset.name.match(/theme-.+\.json/)) {
return "assets/[name][extname]"; return "assets/[name][extname]";
} } else {
else {
return "assets/[name].[hash][extname]"; return "assets/[name].[hash][extname]";
} }
} },
}, },
}, },
}, },
plugins: [ plugins: [
transformServiceWorkerInDevServer(),
themeBuilder({ themeBuilder({
themeConfig: { themeConfig: {
themes: ["./src/platform/web/ui/css/themes/element"], themes: ["./src/platform/web/ui/css/themes/element"],
@ -41,17 +45,19 @@ export default defineConfig(({mode}) => {
// important this comes before service worker // important this comes before service worker
// otherwise the manifest and the icons it refers to won't be cached // otherwise the manifest and the icons it refers to won't be cached
injectWebManifest("assets/manifest.json"), injectWebManifest("assets/manifest.json"),
injectServiceWorker("./src/platform/web/sw.js", findUnhashedFileNamesFromBundle, { injectServiceWorker(
// placeholders to replace at end of build by chunk name "./src/platform/web/sw.js",
index: { findUnhashedFileNamesFromBundle,
DEFINE_GLOBAL_HASH: definePlaceholders.DEFINE_GLOBAL_HASH, {
}, // placeholders to replace at end of build by chunk name
sw: definePlaceholders, index: {
}), DEFINE_GLOBAL_HASH:
definePlaceholders.DEFINE_GLOBAL_HASH,
},
sw: definePlaceholders,
}
),
], ],
define: Object.assign({
DEFINE_PROJECT_DIR: JSON.stringify(__dirname)
}, definePlaceholders),
}); });
}); });

View File

@ -1,7 +1,8 @@
const path = require("path"); const path = require("path");
const mergeOptions = require('merge-options'); const mergeOptions = require("merge-options").bind({ concatArrays: true });
const themeBuilder = require("./scripts/build-plugins/rollup-plugin-build-themes"); const themeBuilder = require("./scripts/build-plugins/rollup-plugin-build-themes");
const {commonOptions, compiledVariables} = require("./vite.common-config.js"); const { commonOptions, compiledVariables } = require("./vite.common-config.js");
const { defineConfig } = require("vite");
// These paths will be saved without their hash so they have a consisent path // These paths will be saved without their hash so they have a consisent path
// that we can reference in our `package.json` `exports`. And so people can import // that we can reference in our `package.json` `exports`. And so people can import
@ -13,33 +14,40 @@ const pathsToExport = [
"theme-element-dark.css", "theme-element-dark.css",
]; ];
export default mergeOptions(commonOptions, { export default defineConfig(({ mode }) => {
root: "src/", const options = commonOptions(mode);
base: "./", return mergeOptions(options, {
build: { root: "src/",
outDir: "../target/asset-build/", base: "./",
rollupOptions: { build: {
output: { outDir: "../target/asset-build/",
assetFileNames: (chunkInfo) => { rollupOptions: {
// Get rid of the hash so we can consistently reference these output: {
// files in our `package.json` `exports`. And so people can assetFileNames: (chunkInfo) => {
// import them with a consistent path. // Get rid of the hash so we can consistently reference these
if(pathsToExport.includes(path.basename(chunkInfo.name))) { // files in our `package.json` `exports`. And so people can
return "assets/[name].[ext]"; // import them with a consistent path.
} if (
pathsToExport.includes(
path.basename(chunkInfo.name)
)
) {
return "assets/[name].[ext]";
}
return "assets/[name]-[hash][extname]"; return "assets/[name]-[hash][extname]";
} },
} },
}
},
plugins: [
themeBuilder({
themeConfig: {
themes: ["./src/platform/web/ui/css/themes/element"],
default: "element",
}, },
compiledVariables, },
}), plugins: [
], themeBuilder({
themeConfig: {
themes: ["./src/platform/web/ui/css/themes/element"],
default: "element",
},
compiledVariables,
}),
],
});
}); });

View File

@ -1,7 +1,12 @@
const path = require("path"); const path = require("path");
const mergeOptions = require('merge-options'); const { defineConfig } = require("vite");
const {commonOptions} = require("./vite.common-config.js"); const mergeOptions = require("merge-options").bind({ concatArrays: true });
const { commonOptions } = require("./vite.common-config.js");
const manifest = require("./package.json"); const manifest = require("./package.json");
const {
injectServiceWorker,
createPlaceholderValues,
} = require("./scripts/build-plugins/service-worker");
const externalDependencies = Object.keys(manifest.dependencies) const externalDependencies = Object.keys(manifest.dependencies)
// just in case for safety in case fake-indexeddb wouldn't be // just in case for safety in case fake-indexeddb wouldn't be
@ -9,39 +14,38 @@ const externalDependencies = Object.keys(manifest.dependencies)
.concat(Object.keys(manifest.devDependencies)) .concat(Object.keys(manifest.devDependencies))
// bundle bs58 because it uses buffer indirectly, which is a pain to bundle, // bundle bs58 because it uses buffer indirectly, which is a pain to bundle,
// so we don't annoy our library users with it. // so we don't annoy our library users with it.
.filter(d => d !== "bs58"); .filter((d) => d !== "bs58");
const moduleDir = path.join(__dirname, "node_modules");
export default mergeOptions(commonOptions, { export default defineConfig(({ mode }) => {
root: "src/", const options = commonOptions(mode);
build: { const definePlaceholders = createPlaceholderValues(mode);
lib: { return mergeOptions(options, {
entry: path.resolve(__dirname, 'src/lib.ts'), root: "src/",
formats: ["cjs", "es"], plugins: [
fileName: format => `hydrogen.${format}.js`, injectServiceWorker("./src/platform/web/sw.js", () => [], {
}, lib: {
minify: false, DEFINE_GLOBAL_HASH: definePlaceholders.DEFINE_GLOBAL_HASH,
sourcemap: false, },
outDir: "../target/lib-build", sw: definePlaceholders,
// don't bundle any dependencies, they should be imported/required }),
rollupOptions: { ],
external(id) { build: {
return externalDependencies.some(d => id === d || id.startsWith(d + "/")); lib: {
entry: path.resolve(__dirname, "src/lib.ts"),
formats: ["cjs", "es"],
fileName: (format) => `hydrogen.${format}.js`,
}, },
/* don't bundle, so we can override imports per file at build time to replace components */ minify: false,
// output: { sourcemap: false,
// manualChunks: (id) => { outDir: "../target/lib-build",
// if (id.startsWith(srcDir)) { // don't bundle any dependencies, they should be imported/required
// const idPath = id.substring(srcDir.length); rollupOptions: {
// const pathWithoutExt = idPath.substring(0, idPath.lastIndexOf(".")); external(id) {
// return pathWithoutExt; return externalDependencies.some(
// } else { (d) => id === d || id.startsWith(d + "/")
// return "index"; );
// } },
// }, },
// minifyInternalExports: false, },
// chunkFileNames: "[format]/[name].js" });
// }
}
},
}); });