mirror of
https://github.com/vector-im/hydrogen-web.git
synced 2024-12-22 11:05:03 +01:00
Make service worker work with sdk
This commit is contained in:
parent
3967d26f9d
commit
8f7d94eb75
@ -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(
|
||||||
|
(map, fileName) => {
|
||||||
const chunkOrAsset = bundle[fileName];
|
const chunkOrAsset = bundle[fileName];
|
||||||
if (!chunkOrAsset) {
|
if (!chunkOrAsset) {
|
||||||
throw new Error("could not get content for uncached asset or chunk " + fileName);
|
throw new Error(
|
||||||
|
"could not get content for uncached asset or chunk " +
|
||||||
|
fileName
|
||||||
|
);
|
||||||
}
|
}
|
||||||
map[fileName] = chunkOrAsset.source || chunkOrAsset.code;
|
map[fileName] = chunkOrAsset.source || chunkOrAsset.code;
|
||||||
return map;
|
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(
|
||||||
|
([fileName, content]) => {
|
||||||
return `${fileName}-${contentHash(Buffer.from(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();
|
||||||
@ -67,27 +95,36 @@ 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") ||
|
||||||
|
name?.endsWith(".html") ||
|
||||||
// the index and vendor chunks don't have an extension in `name`, so check extension on `fileName`
|
// 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));
|
(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 = [];
|
||||||
|
|
||||||
|
if (mode === "production") {
|
||||||
for (const asset of assets) {
|
for (const asset of assets) {
|
||||||
const {name, fileName} = asset;
|
const { name, fileName } = asset;
|
||||||
// the service worker should not be cached at all,
|
// the service worker should not be cached at all,
|
||||||
// it's how updates happen
|
// it's how updates happen
|
||||||
if (fileName === swName) {
|
if (fileName === swName) {
|
||||||
@ -100,26 +137,44 @@ function getCacheFileNamePlaceholderValues(swName, unhashedFilenames, assets) {
|
|||||||
hashedCachedOnRequestAssets.push(fileName);
|
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 };
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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) => {
|
||||||
|
const definePlaceholders = createPlaceholderValues(mode);
|
||||||
|
return {
|
||||||
logLevel: "warn",
|
logLevel: "warn",
|
||||||
publicDir: false,
|
publicDir: false,
|
||||||
server: {
|
server: {
|
||||||
hmr: false
|
hmr: false,
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
// these should only be imported by the base-x package in any runtime code
|
// these should only be imported by the base-x package in any runtime code
|
||||||
// and works in the browser with a Uint8Array shim,
|
// and works in the browser with a Uint8Array shim,
|
||||||
// rather than including a ton of polyfill code
|
// rather than including a ton of polyfill code
|
||||||
"safe-buffer": "./scripts/package-overrides/safe-buffer/index.js",
|
"safe-buffer":
|
||||||
"buffer": "./scripts/package-overrides/buffer/index.js",
|
"./scripts/package-overrides/safe-buffer/index.js",
|
||||||
}
|
buffer: "./scripts/package-overrides/buffer/index.js",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
emptyOutDir: true,
|
emptyOutDir: true,
|
||||||
assetsInlineLimit: 0,
|
assetsInlineLimit: 0,
|
||||||
polyfillModulePreload: false,
|
polyfillModulePreload: false,
|
||||||
},
|
},
|
||||||
assetsInclude: ['**/config.json'],
|
assetsInclude: ["**/config.json"],
|
||||||
define: {
|
define: Object.assign(
|
||||||
DEFINE_VERSION: JSON.stringify(version),
|
{
|
||||||
|
DEFINE_VERSION: `"${getVersion(mode)}"`,
|
||||||
DEFINE_GLOBAL_HASH: JSON.stringify(null),
|
DEFINE_GLOBAL_HASH: JSON.stringify(null),
|
||||||
|
DEFINE_IS_SDK: mode === "sdk" ? "true" : "false",
|
||||||
|
DEFINE_PROJECT_DIR: JSON.stringify(__dirname),
|
||||||
},
|
},
|
||||||
|
definePlaceholders
|
||||||
|
),
|
||||||
css: {
|
css: {
|
||||||
postcss: {
|
postcss: {
|
||||||
plugins: [
|
plugins: [
|
||||||
compileVariables({derive, compiledVariables}),
|
compileVariables({ derive, compiledVariables }),
|
||||||
urlVariables({compiledVariables}),
|
urlVariables({ compiledVariables }),
|
||||||
urlProcessor({replacer}),
|
urlProcessor({ replacer }),
|
||||||
// cssvariables({
|
flexbugsFixes(),
|
||||||
// preserve: (declaration) => {
|
],
|
||||||
// return declaration.value.indexOf("var(--ios-") == 0;
|
},
|
||||||
// }
|
},
|
||||||
// }),
|
};
|
||||||
// the grid option creates some source fragment that causes the vite warning reporter to crash because
|
|
||||||
// it wants to log a warning on a line that does not exist in the source fragment.
|
|
||||||
// autoprefixer({overrideBrowserslist: ["IE 11"], grid: "no-autoplace"}),
|
|
||||||
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 };
|
||||||
|
@ -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(
|
||||||
|
"./src/platform/web/sw.js",
|
||||||
|
findUnhashedFileNamesFromBundle,
|
||||||
|
{
|
||||||
// placeholders to replace at end of build by chunk name
|
// placeholders to replace at end of build by chunk name
|
||||||
index: {
|
index: {
|
||||||
DEFINE_GLOBAL_HASH: definePlaceholders.DEFINE_GLOBAL_HASH,
|
DEFINE_GLOBAL_HASH:
|
||||||
|
definePlaceholders.DEFINE_GLOBAL_HASH,
|
||||||
},
|
},
|
||||||
sw: definePlaceholders,
|
sw: definePlaceholders,
|
||||||
}),
|
}
|
||||||
|
),
|
||||||
],
|
],
|
||||||
define: Object.assign({
|
|
||||||
DEFINE_PROJECT_DIR: JSON.stringify(__dirname)
|
|
||||||
}, definePlaceholders),
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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,7 +14,9 @@ const pathsToExport = [
|
|||||||
"theme-element-dark.css",
|
"theme-element-dark.css",
|
||||||
];
|
];
|
||||||
|
|
||||||
export default mergeOptions(commonOptions, {
|
export default defineConfig(({ mode }) => {
|
||||||
|
const options = commonOptions(mode);
|
||||||
|
return mergeOptions(options, {
|
||||||
root: "src/",
|
root: "src/",
|
||||||
base: "./",
|
base: "./",
|
||||||
build: {
|
build: {
|
||||||
@ -24,14 +27,18 @@ export default mergeOptions(commonOptions, {
|
|||||||
// Get rid of the hash so we can consistently reference these
|
// Get rid of the hash so we can consistently reference these
|
||||||
// files in our `package.json` `exports`. And so people can
|
// files in our `package.json` `exports`. And so people can
|
||||||
// import them with a consistent path.
|
// import them with a consistent path.
|
||||||
if(pathsToExport.includes(path.basename(chunkInfo.name))) {
|
if (
|
||||||
|
pathsToExport.includes(
|
||||||
|
path.basename(chunkInfo.name)
|
||||||
|
)
|
||||||
|
) {
|
||||||
return "assets/[name].[ext]";
|
return "assets/[name].[ext]";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "assets/[name]-[hash][extname]";
|
return "assets/[name]-[hash][extname]";
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
themeBuilder({
|
themeBuilder({
|
||||||
@ -42,4 +49,5 @@ export default mergeOptions(commonOptions, {
|
|||||||
compiledVariables,
|
compiledVariables,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -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,16 +14,26 @@ 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 }) => {
|
||||||
|
const options = commonOptions(mode);
|
||||||
|
const definePlaceholders = createPlaceholderValues(mode);
|
||||||
|
return mergeOptions(options, {
|
||||||
root: "src/",
|
root: "src/",
|
||||||
|
plugins: [
|
||||||
|
injectServiceWorker("./src/platform/web/sw.js", () => [], {
|
||||||
|
lib: {
|
||||||
|
DEFINE_GLOBAL_HASH: definePlaceholders.DEFINE_GLOBAL_HASH,
|
||||||
|
},
|
||||||
|
sw: definePlaceholders,
|
||||||
|
}),
|
||||||
|
],
|
||||||
build: {
|
build: {
|
||||||
lib: {
|
lib: {
|
||||||
entry: path.resolve(__dirname, 'src/lib.ts'),
|
entry: path.resolve(__dirname, "src/lib.ts"),
|
||||||
formats: ["cjs", "es"],
|
formats: ["cjs", "es"],
|
||||||
fileName: format => `hydrogen.${format}.js`,
|
fileName: (format) => `hydrogen.${format}.js`,
|
||||||
},
|
},
|
||||||
minify: false,
|
minify: false,
|
||||||
sourcemap: false,
|
sourcemap: false,
|
||||||
@ -26,22 +41,11 @@ export default mergeOptions(commonOptions, {
|
|||||||
// don't bundle any dependencies, they should be imported/required
|
// don't bundle any dependencies, they should be imported/required
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
external(id) {
|
external(id) {
|
||||||
return externalDependencies.some(d => id === d || id.startsWith(d + "/"));
|
return externalDependencies.some(
|
||||||
|
(d) => id === d || id.startsWith(d + "/")
|
||||||
|
);
|
||||||
},
|
},
|
||||||
/* don't bundle, so we can override imports per file at build time to replace components */
|
|
||||||
// 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";
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// minifyInternalExports: false,
|
|
||||||
// chunkFileNames: "[format]/[name].js"
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user