mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-17 04:07:51 +01:00
This commit basically reverts 1b63b2dccf.
Using service worker for this by default is a bad idea because:
1. It takes some time for the service worker to be installed and ready
which slows down first launch significantly
2. Service worker is not as reliable when updating from version to
version
We can, however, use it as a fallback i.e for devices that don't yet
support shared worker.
279 lines
8.0 KiB
TypeScript
279 lines
8.0 KiB
TypeScript
/*
|
|
This file is part of the Notesnook project (https://notesnook.com/)
|
|
|
|
Copyright (C) 2023 Streetwriters (Private) Limited
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import { Plugin, PluginOption, ResolvedConfig, defineConfig } from "vite";
|
|
import react from "@vitejs/plugin-react-swc";
|
|
import svgrPlugin from "vite-plugin-svgr";
|
|
import envCompatible from "vite-plugin-env-compatible";
|
|
import { VitePWA } from "vite-plugin-pwa";
|
|
import autoprefixer from "autoprefixer";
|
|
import { WEB_MANIFEST } from "./web-manifest";
|
|
import { execSync } from "child_process";
|
|
import { version } from "./package.json";
|
|
import { visualizer } from "rollup-plugin-visualizer";
|
|
import { OutputPlugin } from "rollup";
|
|
import path from "path";
|
|
|
|
const gitHash = (() => {
|
|
try {
|
|
return execSync("git rev-parse --short HEAD").toString().trim();
|
|
} catch (e) {
|
|
return process.env.GIT_HASH || "gitless";
|
|
}
|
|
})();
|
|
// const appVersion = version.replaceAll(".", "").replace("-beta", "");
|
|
const isBeta = version.includes("-beta");
|
|
const isTesting =
|
|
process.env.TEST === "true" || process.env.NODE_ENV === "development";
|
|
const isDesktop = process.env.PLATFORM === "desktop";
|
|
const isThemeBuilder = process.env.THEME_BUILDER === "true";
|
|
const isAnalyzing = process.env.ANALYZING === "true";
|
|
|
|
export default defineConfig({
|
|
envPrefix: "NN_",
|
|
root: "src/",
|
|
publicDir: isThemeBuilder ? path.join(__dirname, "public") : "../public",
|
|
build: {
|
|
target: isDesktop ? "esnext" : "modules",
|
|
outDir: "../build",
|
|
minify: "esbuild",
|
|
cssMinify: true,
|
|
emptyOutDir: true,
|
|
sourcemap: !isDesktop,
|
|
rollupOptions: {
|
|
output: {
|
|
plugins: [emitEditorStyles()],
|
|
assetFileNames: "assets/[name]-[hash:12][extname]",
|
|
chunkFileNames: "assets/[name]-[hash:12].js",
|
|
manualChunks: (id: string) => {
|
|
if (
|
|
(id.includes("/editor/languages/") ||
|
|
id.includes("/html/languages/") ||
|
|
id.includes("/refractor/lang/")) &&
|
|
path.basename(id) !== "index.js"
|
|
)
|
|
return `code-lang-${path.basename(id, "js")}`;
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
define: {
|
|
APP_TITLE: `"${isThemeBuilder ? "Notesnook Theme Builder" : "Notesnook"}"`,
|
|
GIT_HASH: `"${gitHash}"`,
|
|
APP_VERSION: `"${version}"`,
|
|
PUBLIC_URL: `"${process.env.PUBLIC_URL || ""}"`,
|
|
IS_DESKTOP_APP: isDesktop,
|
|
PLATFORM: `"${process.env.PLATFORM}"`,
|
|
IS_TESTING: process.env.TEST === "true",
|
|
IS_BETA: isBeta,
|
|
IS_THEME_BUILDER: isThemeBuilder
|
|
},
|
|
logLevel: process.env.NODE_ENV === "production" ? "warn" : "info",
|
|
resolve: {
|
|
dedupe: [
|
|
"react",
|
|
"react-dom",
|
|
"@mdi/js",
|
|
"@mdi/react",
|
|
"@emotion/react",
|
|
"katex",
|
|
"react-modal",
|
|
"dayjs",
|
|
"@streetwriters/kysely"
|
|
],
|
|
|
|
alias: [
|
|
{
|
|
find: /\/desktop-bridge$/gm,
|
|
replacement: isDesktop
|
|
? "/desktop-bridge/index.desktop"
|
|
: "/desktop-bridge/index"
|
|
},
|
|
{
|
|
find: /\/sqlite$/gm,
|
|
replacement: isDesktop ? "/sqlite/index.desktop" : "/sqlite/index"
|
|
}
|
|
]
|
|
},
|
|
server: {
|
|
port: 3000
|
|
},
|
|
worker: {
|
|
format: "es",
|
|
rollupOptions: {
|
|
output: {
|
|
assetFileNames: "assets/[name]-[hash:12][extname]",
|
|
chunkFileNames: "assets/[name]-[hash:12].js",
|
|
inlineDynamicImports: true
|
|
}
|
|
}
|
|
},
|
|
css: {
|
|
postcss: {
|
|
plugins: [autoprefixer()]
|
|
}
|
|
},
|
|
plugins: [
|
|
...(isAnalyzing
|
|
? [
|
|
visualizer({
|
|
gzipSize: true,
|
|
brotliSize: true,
|
|
open: true
|
|
}) as PluginOption
|
|
]
|
|
: []),
|
|
...((isThemeBuilder || isDesktop) && process.env.NODE_ENV === "production"
|
|
? []
|
|
: [
|
|
VitePWA({
|
|
strategies: "injectManifest",
|
|
minify: true,
|
|
manifest: WEB_MANIFEST,
|
|
injectRegister: null,
|
|
srcDir: "",
|
|
filename: "service-worker.ts",
|
|
mode: "production",
|
|
workbox: { mode: "production" },
|
|
injectManifest: {
|
|
globPatterns: ["**/*.{js,css,html,wasm}", "**/Inter-*.woff2"],
|
|
globIgnores: [
|
|
"**/node_modules/**/*",
|
|
"**/code-lang-*.js",
|
|
"pdf.worker.min.js"
|
|
]
|
|
}
|
|
})
|
|
]),
|
|
react({
|
|
plugins: isTesting
|
|
? undefined
|
|
: [
|
|
[
|
|
"@swc/plugin-react-remove-properties",
|
|
{
|
|
properties: ["^data-test-id$"]
|
|
}
|
|
]
|
|
]
|
|
}),
|
|
envCompatible({
|
|
prefix: "NN_",
|
|
mountedPath: "process.env"
|
|
}),
|
|
svgrPlugin({
|
|
svgrOptions: {
|
|
icon: true,
|
|
namedExport: "ReactComponent"
|
|
// ...svgr options (https://react-svgr.com/docs/options/)
|
|
}
|
|
}),
|
|
...(isDesktop
|
|
? []
|
|
: [
|
|
prefetchPlugin({
|
|
excludeFn: (assetName) =>
|
|
assetName.includes("wa-sqlite-async") ||
|
|
!assetName.includes("wa-sqlite")
|
|
})
|
|
])
|
|
]
|
|
});
|
|
|
|
function emitEditorStyles(): OutputPlugin {
|
|
return {
|
|
name: "rollup-plugin-emit-editor-styles",
|
|
generateBundle(options, bundle) {
|
|
for (const file in bundle) {
|
|
const chunk = bundle[file];
|
|
if (
|
|
chunk.type === "asset" &&
|
|
chunk.fileName.endsWith(".css") &&
|
|
typeof chunk.source === "string" &&
|
|
(chunk.source.includes("KaTeX_Fraktur-Bold-") ||
|
|
chunk.source.includes("Hack typeface"))
|
|
) {
|
|
this.emitFile({
|
|
type: "asset",
|
|
fileName: "assets/editor-styles.css",
|
|
name: "editor-styles.css",
|
|
source: chunk.source
|
|
});
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
function prefetchPlugin(options?: {
|
|
excludeFn?: (assetName: string) => boolean;
|
|
}): Plugin {
|
|
let config: ResolvedConfig;
|
|
return {
|
|
name: "vite-plugin-bundle-prefetch",
|
|
apply: "build",
|
|
configResolved(resolvedConfig: ResolvedConfig) {
|
|
// store the resolved config
|
|
config = resolvedConfig;
|
|
},
|
|
transformIndexHtml(
|
|
html: string,
|
|
ctx: {
|
|
path: string;
|
|
filename: string;
|
|
bundle?: import("rollup").OutputBundle;
|
|
chunk?: import("rollup").OutputChunk;
|
|
}
|
|
) {
|
|
const bundles = Object.keys(ctx.bundle ?? {});
|
|
const isLegacy = bundles.some((bundle) => bundle.includes("legacy"));
|
|
if (isLegacy) {
|
|
//legacy build won't add prefetch
|
|
return html;
|
|
}
|
|
// remove map files
|
|
let modernBundles = bundles.filter(
|
|
(bundle) => bundle.endsWith(".map") === false
|
|
);
|
|
const excludeFn = options?.excludeFn;
|
|
if (excludeFn) {
|
|
modernBundles = modernBundles.filter((bundle) => !excludeFn(bundle));
|
|
}
|
|
// Remove existing files and concatenate them into link tags
|
|
const prefechBundlesString = modernBundles
|
|
.filter((bundle) => html.includes(bundle) === false)
|
|
.map((bundle) => `<link rel="prefetch" href="${config.base}${bundle}">`)
|
|
.join("\n");
|
|
|
|
// Use regular expression to get the content within <head> </head>
|
|
const headContent = html.match(/<head>([\s\S]*)<\/head>/)?.[1] ?? "";
|
|
// Insert the content of prefetch into the head
|
|
const newHeadContent = `${headContent}${prefechBundlesString}`;
|
|
// Replace the original head
|
|
html = html.replace(
|
|
/<head>([\s\S]*)<\/head>/,
|
|
`<head>${newHeadContent}</head>`
|
|
);
|
|
|
|
return html;
|
|
}
|
|
};
|
|
}
|