Refactor build files, separating & consolidating & renaming as needed.
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
# Only the variables that start with VITE_ are seen in the application import.meta.env in Vue.
|
# Only the variables that start with VITE_ are seen in the application import.meta.env in Vue.
|
||||||
|
|
||||||
# iOS doesn't like spaces in the app title.
|
|
||||||
TIME_SAFARI_APP_TITLE="TimeSafari_Test"
|
TIME_SAFARI_APP_TITLE="TimeSafari_Test"
|
||||||
VITE_APP_SERVER=https://test.timesafari.app
|
VITE_APP_SERVER=https://test.timesafari.app
|
||||||
# This is the claim ID for actions in the BVC project, with the JWT ID on this environment (not production).
|
# This is the claim ID for actions in the BVC project.
|
||||||
VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F
|
VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F
|
||||||
VITE_DEFAULT_ENDORSER_API_SERVER=https://test-api.endorser.ch
|
VITE_DEFAULT_ENDORSER_API_SERVER=https://test-api.endorser.ch
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ Quick start:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install
|
npm install
|
||||||
npm run dev
|
NODE_ENV=dev npm run start:web
|
||||||
```
|
```
|
||||||
|
|
||||||
See [BUILDING.md](doc/BUILDING.md) for more details.
|
See [BUILDING.md](doc/BUILDING.md) for more details.
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ Install dependencies:
|
|||||||
## Web Dev Locally
|
## Web Dev Locally
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run dev
|
NODE_ENV=dev npm run start:web
|
||||||
```
|
```
|
||||||
|
|
||||||
## Web Build for Server
|
## Web Build for Server
|
||||||
@@ -31,7 +31,7 @@ Install dependencies:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
rm -rf dist
|
rm -rf dist
|
||||||
npm run build:web
|
NODE_ENV=prod npm run build:web
|
||||||
```
|
```
|
||||||
|
|
||||||
The built files will be in the `dist` directory.
|
The built files will be in the `dist` directory.
|
||||||
@@ -41,7 +41,7 @@ Install dependencies:
|
|||||||
You'll likely want to use test locations for the Endorser & image & partner servers; see "DEFAULT_ENDORSER_API_SERVER" & "DEFAULT_IMAGE_API_SERVER" & "DEFAULT_PARTNER_API_SERVER" below.
|
You'll likely want to use test locations for the Endorser & image & partner servers; see "DEFAULT_ENDORSER_API_SERVER" & "DEFAULT_IMAGE_API_SERVER" & "DEFAULT_PARTNER_API_SERVER" below.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run serve
|
NODE_ENV=dev npm run serve:web
|
||||||
```
|
```
|
||||||
|
|
||||||
### Compile and minify for test & production
|
### Compile and minify for test & production
|
||||||
@@ -52,7 +52,7 @@ Install dependencies:
|
|||||||
|
|
||||||
* Update the ClickUp tasks & CHANGELOG.md & the version in package.json, run `npm install`.
|
* Update the ClickUp tasks & CHANGELOG.md & the version in package.json, run `npm install`.
|
||||||
|
|
||||||
* Run a build to make sure package-lock version is updated, linting works, etc: `npm install && npm run build`
|
* Run a build to make sure package-lock version is updated, linting works, etc: `npm install && npm run build:web`
|
||||||
|
|
||||||
* Commit everything (since the commit hash is used the app).
|
* Commit everything (since the commit hash is used the app).
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ Install dependencies:
|
|||||||
* For test, build the app (because test server is not yet set up to build):
|
* For test, build the app (because test server is not yet set up to build):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
TIME_SAFARI_APP_TITLE="TimeSafari_Test" VITE_APP_SERVER=https://test.timesafari.app VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F VITE_DEFAULT_ENDORSER_API_SERVER=https://test-api.endorser.ch VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app VITE_DEFAULT_PARTNER_API_SERVER=https://test-partner-api.endorser.ch VITE_DEFAULT_PUSH_SERVER=https://test.timesafari.app VITE_PASSKEYS_ENABLED=true npm run build:web
|
NODE_ENV=test TIME_SAFARI_APP_TITLE="TimeSafari_Test" VITE_APP_SERVER=https://test.timesafari.app VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F VITE_DEFAULT_ENDORSER_API_SERVER=https://test-api.endorser.ch VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app VITE_DEFAULT_PARTNER_API_SERVER=https://test-partner-api.endorser.ch VITE_DEFAULT_PUSH_SERVER=https://test.timesafari.app VITE_PASSKEYS_ENABLED=true npm run build:web
|
||||||
```
|
```
|
||||||
|
|
||||||
... and transfer to the test server:
|
... and transfer to the test server:
|
||||||
@@ -205,10 +205,10 @@ docker run -d \
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# For AppImage (recommended)
|
# For AppImage (recommended)
|
||||||
npm run electron:build-linux
|
npm run build:electron-linux
|
||||||
|
|
||||||
# For .deb package
|
# For .deb package
|
||||||
npm run electron:build-linux-deb
|
npm run build:electron-linux-deb
|
||||||
```
|
```
|
||||||
|
|
||||||
3. The packaged applications will be in `dist-electron-packages/`:
|
3. The packaged applications will be in `dist-electron-packages/`:
|
||||||
@@ -220,19 +220,19 @@ docker run -d \
|
|||||||
1. Build the electron app in production mode:
|
1. Build the electron app in production mode:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run build:web
|
NODE_ENV=prod npm run build:web
|
||||||
npm run build:electron
|
npm run build:electron
|
||||||
npm run electron:build-mac
|
npm run build:electron-mac
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Package the Electron app for macOS:
|
2. Package the Electron app for macOS:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# For Intel Macs
|
# For Intel Macs
|
||||||
npm run electron:build-mac
|
npm run build:electron-mac
|
||||||
|
|
||||||
# For Universal build (Intel + Apple Silicon)
|
# For Universal build (Intel + Apple Silicon)
|
||||||
npm run electron:build-mac-universal
|
npm run build:electron-mac-universal
|
||||||
```
|
```
|
||||||
|
|
||||||
3. The packaged applications will be in `dist-electron-packages/`:
|
3. The packaged applications will be in `dist-electron-packages/`:
|
||||||
@@ -254,7 +254,7 @@ For public distribution on macOS, you need to code sign and notarize your app:
|
|||||||
|
|
||||||
2. Build with signing:
|
2. Build with signing:
|
||||||
```bash
|
```bash
|
||||||
npm run electron:build-mac
|
npm run build:electron-mac
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running the Packaged App
|
### Running the Packaged App
|
||||||
@@ -293,10 +293,10 @@ For testing the Electron build before packaging:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Build and run in development mode (includes DevTools)
|
# Build and run in development mode (includes DevTools)
|
||||||
npm run electron:dev
|
npm run build:electron
|
||||||
|
|
||||||
# Build in production mode and test
|
# Build in production mode and test
|
||||||
npm run build:electron-prod && npm run electron:start
|
npm run build:electron-prod && npm run start:electron
|
||||||
```
|
```
|
||||||
|
|
||||||
## Mobile Builds (Capacitor)
|
## Mobile Builds (Capacitor)
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ export default defineConfig({
|
|||||||
/**
|
/**
|
||||||
* This could be an array of servers, meaning we could start the Endorser server as well:
|
* This could be an array of servers, meaning we could start the Endorser server as well:
|
||||||
* {
|
* {
|
||||||
* command: "cd ../endorser-ch; NODE_ENV=test-local npm run dev",
|
* command: "cd ../endorser-ch; NODE_ENV=test-local npm run start:web",
|
||||||
* url: 'http://localhost:3000',
|
* url: 'http://localhost:3000',
|
||||||
* reuseExistingServer: !process.env.CI,
|
* reuseExistingServer: !process.env.CI,
|
||||||
* },
|
* },
|
||||||
@@ -112,7 +112,7 @@ export default defineConfig({
|
|||||||
*/
|
*/
|
||||||
webServer: {
|
webServer: {
|
||||||
command:
|
command:
|
||||||
"VITE_APP_SERVER=http://localhost:8081 VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000 VITE_DEFAULT_PARTNER_API_SERVER=http://localhost:3000 VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app VITE_PASSKEYS_ENABLED=true npm run dev -- --port=8081",
|
"VITE_APP_SERVER=http://localhost:8081 VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000 VITE_DEFAULT_PARTNER_API_SERVER=http://localhost:3000 VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app VITE_PASSKEYS_ENABLED=true npm run start:web -- --port=8081",
|
||||||
url: "http://localhost:8081",
|
url: "http://localhost:8081",
|
||||||
reuseExistingServer: !process.env.CI,
|
reuseExistingServer: !process.env.CI,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export default defineConfig({
|
|||||||
/* Run your local dev server before starting the tests */
|
/* Run your local dev server before starting the tests */
|
||||||
// webServer: {
|
// webServer: {
|
||||||
// command:
|
// command:
|
||||||
// "VITE_PASSKEYS_ENABLED=true VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000 npm run dev",
|
// "VITE_PASSKEYS_ENABLED=true VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000 npm run start:web",
|
||||||
// url: "http://localhost:8080",
|
// url: "http://localhost:8080",
|
||||||
// reuseExistingServer: !process.env.CI,
|
// reuseExistingServer: !process.env.CI,
|
||||||
// },
|
// },
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ backup and database export, with platform-specific download instructions. * *
|
|||||||
v-if="platformCapabilities.isMobile && !platformCapabilities.isIOS"
|
v-if="platformCapabilities.isMobile && !platformCapabilities.isIOS"
|
||||||
class="list-disc list-outside ml-4"
|
class="list-disc list-outside ml-4"
|
||||||
>
|
>
|
||||||
On Android: You will be prompted to choose a location to save your
|
On Android: You will be prompted to choose an app for sharing your
|
||||||
backup file.
|
backup file. To save on your phone, you will need a file manager app.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
import * as path from "path";
|
|
||||||
import { promises as fs } from "fs";
|
|
||||||
import { fileURLToPath } from "url";
|
|
||||||
|
|
||||||
export async function loadAppConfig() {
|
|
||||||
const packageJson = await loadPackageJson();
|
|
||||||
const appName = process.env.TIME_SAFARI_APP_TITLE || packageJson.name;
|
|
||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
||||||
|
|
||||||
return {
|
|
||||||
pwaConfig: {
|
|
||||||
manifest: {
|
|
||||||
name: appName,
|
|
||||||
short_name: appName,
|
|
||||||
icons: [
|
|
||||||
{
|
|
||||||
src: "./img/icons/android-chrome-192x192.png",
|
|
||||||
sizes: "192x192",
|
|
||||||
type: "image/png",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: "./img/icons/android-chrome-512x512.png",
|
|
||||||
sizes: "512x512",
|
|
||||||
type: "image/png",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: "./img/icons/android-chrome-maskable-192x192.png",
|
|
||||||
sizes: "192x192",
|
|
||||||
type: "image/png",
|
|
||||||
purpose: "maskable",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: "./img/icons/android-chrome-maskable-512x512.png",
|
|
||||||
sizes: "512x512",
|
|
||||||
type: "image/png",
|
|
||||||
purpose: "maskable",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
aliasConfig: {
|
|
||||||
"@": path.resolve(path.dirname(__dirname), "src"),
|
|
||||||
buffer: path.resolve(path.dirname(__dirname), "node_modules", "buffer"),
|
|
||||||
"dexie-export-import/dist/import":
|
|
||||||
"dexie-export-import/dist/import/index.js",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadPackageJson() {
|
|
||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
||||||
const packageJsonPath = path.resolve(path.dirname(__dirname), "package.json");
|
|
||||||
const packageJsonData = await fs.readFile(packageJsonPath, "utf-8");
|
|
||||||
return JSON.parse(packageJsonData);
|
|
||||||
}
|
|
||||||
@@ -45,71 +45,73 @@ interface PWAConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface AppConfig {
|
interface AppConfig {
|
||||||
pwaConfig: PWAConfig;
|
|
||||||
aliasConfig: {
|
aliasConfig: {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadAppConfig(): Promise<AppConfig> {
|
export async function loadAppConfig(): Promise<AppConfig> {
|
||||||
const packageJson = await loadPackageJson();
|
|
||||||
const appName = process.env.TIME_SAFARI_APP_TITLE || packageJson.name;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pwaConfig: {
|
|
||||||
registerType: "autoUpdate",
|
|
||||||
strategies: "injectManifest",
|
|
||||||
srcDir: ".",
|
|
||||||
filename: "sw_scripts-combined.js",
|
|
||||||
manifest: {
|
|
||||||
name: appName,
|
|
||||||
short_name: appName,
|
|
||||||
theme_color: "#4a90e2",
|
|
||||||
background_color: "#ffffff",
|
|
||||||
icons: [
|
|
||||||
{
|
|
||||||
src: "./img/icons/android-chrome-192x192.png",
|
|
||||||
sizes: "192x192",
|
|
||||||
type: "image/png",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: "./img/icons/android-chrome-512x512.png",
|
|
||||||
sizes: "512x512",
|
|
||||||
type: "image/png",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: "./img/icons/android-chrome-maskable-192x192.png",
|
|
||||||
sizes: "192x192",
|
|
||||||
type: "image/png",
|
|
||||||
purpose: "maskable",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: "./img/icons/android-chrome-maskable-512x512.png",
|
|
||||||
sizes: "512x512",
|
|
||||||
type: "image/png",
|
|
||||||
purpose: "maskable",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
share_target: {
|
|
||||||
action: "/share-target",
|
|
||||||
method: "POST",
|
|
||||||
enctype: "multipart/form-data",
|
|
||||||
params: {
|
|
||||||
files: [
|
|
||||||
{
|
|
||||||
name: "photo",
|
|
||||||
accept: ["image/*"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
aliasConfig: {
|
aliasConfig: {
|
||||||
"@": path.resolve(__dirname, "src"),
|
"@": path.resolve(__dirname, "src"),
|
||||||
buffer: path.resolve(__dirname, "node_modules", "buffer"),
|
buffer: path.resolve(__dirname, "node_modules", "buffer"),
|
||||||
"dexie-export-import/dist/import":
|
"dexie-export-import/dist/import":
|
||||||
"dexie-export-import/dist/import/index.js",
|
"dexie-export-import/dist/import/index.js",
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadPwaConfig(): Promise<PWAConfig> {
|
||||||
|
const packageJson = await loadPackageJson();
|
||||||
|
const appName = process.env.TIME_SAFARI_APP_TITLE || packageJson.name;
|
||||||
|
|
||||||
|
return {
|
||||||
|
registerType: "autoUpdate",
|
||||||
|
strategies: "injectManifest",
|
||||||
|
srcDir: ".",
|
||||||
|
filename: "sw_scripts-combined.js",
|
||||||
|
manifest: {
|
||||||
|
name: appName,
|
||||||
|
short_name: appName,
|
||||||
|
theme_color: "#4a90e2",
|
||||||
|
background_color: "#ffffff",
|
||||||
|
icons: [
|
||||||
|
{
|
||||||
|
src: "./img/icons/android-chrome-192x192.png",
|
||||||
|
sizes: "192x192",
|
||||||
|
type: "image/png",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: "./img/icons/android-chrome-512x512.png",
|
||||||
|
sizes: "512x512",
|
||||||
|
type: "image/png",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: "./img/icons/android-chrome-maskable-192x192.png",
|
||||||
|
sizes: "192x192",
|
||||||
|
type: "image/png",
|
||||||
|
purpose: "maskable",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: "./img/icons/android-chrome-maskable-512x512.png",
|
||||||
|
sizes: "512x512",
|
||||||
|
type: "image/png",
|
||||||
|
purpose: "maskable",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
share_target: {
|
||||||
|
action: "/share-target",
|
||||||
|
method: "POST",
|
||||||
|
enctype: "multipart/form-data",
|
||||||
|
params: {
|
||||||
|
files: [
|
||||||
|
{
|
||||||
|
name: "photo",
|
||||||
|
accept: ["image/*"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { defineConfig, UserConfig, Plugin } from "vite";
|
import { defineConfig, UserConfig, Plugin } from "vite";
|
||||||
import vue from "@vitejs/plugin-vue";
|
import vue from "@vitejs/plugin-vue";
|
||||||
import dotenv from "dotenv";
|
import dotenv from "dotenv";
|
||||||
import { loadAppConfig } from "./vite.config.utils.mts";
|
import { loadAppConfig } from "./vite.config.common-utils.mts";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
@@ -9,7 +9,11 @@ export type BuildMode = 'web' | 'electron' | 'capacitor' | 'pywebview';
|
|||||||
export type BuildEnv = 'dev' | 'test' | 'prod';
|
export type BuildEnv = 'dev' | 'test' | 'prod';
|
||||||
|
|
||||||
// Load environment variables
|
// Load environment variables
|
||||||
if (process.env.NODE_ENV === 'dev' || process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'prod') {
|
if (
|
||||||
|
process.env.NODE_ENV === 'dev'
|
||||||
|
|| process.env.NODE_ENV === 'test'
|
||||||
|
|| process.env.NODE_ENV === 'prod'
|
||||||
|
) {
|
||||||
console.log(`NODE_ENV=${process.env.NODE_ENV}`);
|
console.log(`NODE_ENV=${process.env.NODE_ENV}`);
|
||||||
} else {
|
} else {
|
||||||
console.error("NODE_ENV is not set. Invoke with NODE_ENV=dev|test|prod");
|
console.error("NODE_ENV is not set. Invoke with NODE_ENV=dev|test|prod");
|
||||||
@@ -30,13 +34,11 @@ export async function createBuildConfig(mode: BuildMode): Promise<UserConfig> {
|
|||||||
|
|
||||||
// Explicitly set platform and disable PWA for Electron
|
// Explicitly set platform and disable PWA for Electron
|
||||||
process.env.VITE_PLATFORM = mode;
|
process.env.VITE_PLATFORM = mode;
|
||||||
process.env.VITE_PWA_ENABLED = isElectron ? 'false' : 'true';
|
process.env.VITE_PWA_ENABLED = (isElectron || isPyWebView || isCapacitor)
|
||||||
|
? 'false'
|
||||||
|
: 'true';
|
||||||
process.env.VITE_DISABLE_PWA = isElectron ? 'true' : 'false';
|
process.env.VITE_DISABLE_PWA = isElectron ? 'true' : 'false';
|
||||||
|
|
||||||
if (isElectron || isPyWebView || isCapacitor) {
|
|
||||||
process.env.VITE_PWA_ENABLED = 'false';
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
base: isElectron || isPyWebView ? "./" : "/",
|
base: isElectron || isPyWebView ? "./" : "/",
|
||||||
plugins: [vue()],
|
plugins: [vue()],
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
import { defineConfig, mergeConfig } from "vite";
|
import { defineConfig, mergeConfig } from "vite";
|
||||||
import { VitePWA } from "vite-plugin-pwa";
|
import { VitePWA } from "vite-plugin-pwa";
|
||||||
import { createBuildConfig } from "./vite.config.common.mts";
|
import { createBuildConfig } from "./vite.config.common.mts";
|
||||||
import { loadAppConfig } from "./vite.config.utils.mts";
|
import { loadPwaConfig } from "./vite.config.common-utils.mts";
|
||||||
|
|
||||||
export default defineConfig(async () => {
|
export default defineConfig(async () => {
|
||||||
const baseConfig = await createBuildConfig('web');
|
const baseConfig = await createBuildConfig('web');
|
||||||
const appConfig = await loadAppConfig();
|
const pwaConfig = await loadPwaConfig();
|
||||||
|
|
||||||
return mergeConfig(baseConfig, {
|
return mergeConfig(baseConfig, {
|
||||||
plugins: [
|
plugins: [
|
||||||
VitePWA({
|
VitePWA({
|
||||||
registerType: 'autoUpdate',
|
registerType: 'autoUpdate',
|
||||||
manifest: appConfig.pwaConfig?.manifest,
|
manifest: pwaConfig.manifest,
|
||||||
devOptions: {
|
devOptions: {
|
||||||
enabled: false
|
enabled: false
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user