Migrate web builds from Vue CLI to Vite
This commit changes the web application's build, transpilation and minification process from Vue CLI to Vite. This shift paves the way for a full migration to Vite as the primary build tool (#230). Configuration changes: - `.vscode/extensions.json`: Update recommended plugins, replacing unmaintained ones with official recommendations. - Legacy browser support: - Use `@vitejs/plugin-legacy` to transpile for older browsers. - Remove `core-js` dependency and `babel.config.cjs` configuration as they're now handled by the legacy plugin. - Delete `@babel/preset-typescript` and `@babel/preset-typescript` dependencies as legacy plugin handles babel dependencies by default. - Add `terser` dependency that's used by the legacy plugin for minification, as per Vite's official documentation. - `tsconfig.json`: - Remove obsolete `webpack-env` types. - Add `"resolveJsonModule": true` to be able to read JSON files in right way. - Use correct casing as configuration values. - Simplify `lib` to align with Vite and Vue starter configuration. - Add `"skipLibCheck": true` as `npm run build` now runs `tsc` which fails on inconsistent typings inside `node_modules` due to npm's weak dependency resoultion. - PostCSS: - Add `autoprefixer` as dependency, no longer installed by Vue CLI. - Epxlicitly added `postcss` as dependency to anticipate potential peer dependency changes. - Remove related `@vue/cli` dependencies. - Remove `sass-loader` as Vite has native CSS preprocessing support. - Run integration tests with `jsdom` environment so `window` object can be used. Client-side changes: - Abstract build tool specific environment variable population. Environment variables were previously populated by Vue CLI and now by Vite but not having an abstraction caused issues. This abstraction solves build errors and allows easier future migrations and testing. - Change Vue CLI-specific `~@` aliases to `@` to be able to compile with Vite. - Update types in LiquorTree to satisfy `tsc`. - Remove Vue CLI-specific workaround from `src/presentation/main.ts`. Restructuring: - Move `public/` to `presentation/` to align with the layered structure, which was not possible with Vue CLI. - Move `index.html` to web root instead of having it inside `public/` to align with official recommended structure. - Move logic shared by both integration and unit tests to `tests/shared`. - Move logo creation script to `scripts/` and its npm command to include `build` to align with rest of the structure.
This commit is contained in:
3
src/presentation/README.md
Normal file
3
src/presentation/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# presentation
|
||||
|
||||
See [`presentation.md`](./../../docs/presentation.md)
|
||||
@@ -1,17 +1,19 @@
|
||||
// https://google-webfonts-helper.herokuapp.com/fonts
|
||||
|
||||
@use "@/presentation/assets/styles/vite-path" as *;
|
||||
|
||||
/* slabo-27px-regular - latin-ext_latin */
|
||||
@font-face {
|
||||
font-family: 'Slabo 27px';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url('~@/presentation/assets/fonts/slabo-27px-v6-latin-ext_latin-regular.eot'); /* IE9 Compat Modes */
|
||||
src: url('#{$base-assets-path}/fonts/slabo-27px-v6-latin-ext_latin-regular.eot'); /* IE9 Compat Modes */
|
||||
src: local('Slabo 27px'), local('Slabo27px-Regular'),
|
||||
url('~@/presentation/assets/fonts/slabo-27px-v6-latin-ext_latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
||||
url('~@/presentation/assets/fonts/slabo-27px-v6-latin-ext_latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
|
||||
url('~@/presentation/assets/fonts/slabo-27px-v6-latin-ext_latin-regular.woff') format('woff'), /* Modern Browsers */
|
||||
url('~@/presentation/assets/fonts/slabo-27px-v6-latin-ext_latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
|
||||
url('~@/presentation/assets/fonts/slabo-27px-v6-latin-ext_latin-regular.svg#Slabo27px') format('svg'); /* Legacy iOS */
|
||||
url('#{$base-assets-path}/fonts/slabo-27px-v6-latin-ext_latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
||||
url('#{$base-assets-path}/fonts/slabo-27px-v6-latin-ext_latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
|
||||
url('#{$base-assets-path}/fonts/slabo-27px-v6-latin-ext_latin-regular.woff') format('woff'), /* Modern Browsers */
|
||||
url('#{$base-assets-path}/fonts/slabo-27px-v6-latin-ext_latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
|
||||
url('#{$base-assets-path}/fonts/slabo-27px-v6-latin-ext_latin-regular.svg#Slabo27px') format('svg'); /* Legacy iOS */
|
||||
}
|
||||
|
||||
/* yesteryear-regular - latin */
|
||||
@@ -19,13 +21,13 @@
|
||||
font-family: 'Yesteryear';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url('~@/presentation/assets/fonts/yesteryear-v8-latin-regular.eot'); /* IE9 Compat Modes */
|
||||
src: url('#{$base-assets-path}/fonts/yesteryear-v8-latin-regular.eot'); /* IE9 Compat Modes */
|
||||
src: local('Yesteryear'), local('Yesteryear-Regular'),
|
||||
url('~@/presentation/assets/fonts/yesteryear-v8-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
||||
url('~@/presentation/assets/fonts/yesteryear-v8-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
|
||||
url('~@/presentation/assets/fonts/yesteryear-v8-latin-regular.woff') format('woff'), /* Modern Browsers */
|
||||
url('~@/presentation/assets/fonts/yesteryear-v8-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
|
||||
url('~@/presentation/assets/fonts/yesteryear-v8-latin-regular.svg#Yesteryear') format('svg'); /* Legacy iOS */
|
||||
url('#{$base-assets-path}/fonts/yesteryear-v8-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
||||
url('#{$base-assets-path}/fonts/yesteryear-v8-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
|
||||
url('#{$base-assets-path}/fonts/yesteryear-v8-latin-regular.woff') format('woff'), /* Modern Browsers */
|
||||
url('#{$base-assets-path}/fonts/yesteryear-v8-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
|
||||
url('#{$base-assets-path}/fonts/yesteryear-v8-latin-regular.svg#Yesteryear') format('svg'); /* Legacy iOS */
|
||||
}
|
||||
|
||||
$font-normal : 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
@use "@/presentation/assets/styles/colors" as *;
|
||||
@use "@/presentation/assets/styles/fonts" as *;
|
||||
@use "@/presentation/assets/styles/mixins" as *;
|
||||
@use "@/presentation/assets/styles/vite-path" as *;
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
|
||||
4
src/presentation/assets/styles/_vite-path.scss
Normal file
4
src/presentation/assets/styles/_vite-path.scss
Normal file
@@ -0,0 +1,4 @@
|
||||
// Define paths specific to Vite's resolution system.
|
||||
// Vite uses the "@" symbol to resolve its aliases for styles.
|
||||
|
||||
$base-assets-path: "@/presentation/assets/";
|
||||
@@ -1,8 +1,8 @@
|
||||
import ace from 'ace-builds';
|
||||
|
||||
/*
|
||||
Following is here because `import 'ace-builds/webpack-resolver';` does not work with webpack 5.
|
||||
Related issue: https://github.com/ajaxorg/ace-builds/issues/211, PR: https://github.com/ajaxorg/ace-builds/pull/221
|
||||
Following is here because `import 'ace-builds/esm-resolver' imports all unused functionality
|
||||
when built with Vite (`npm run build`).
|
||||
*/
|
||||
|
||||
import 'ace-builds/src-noconflict/theme-github';
|
||||
|
||||
@@ -69,6 +69,8 @@ declare module 'liquor-tree' {
|
||||
matcher(query: string, node: ILiquorTreeExistingNode): boolean;
|
||||
}
|
||||
|
||||
const LiquorTree: PluginObject<Vue>;
|
||||
interface LiquorTreeVueComponent extends PluginObject<Vue> {
|
||||
install(Vue: VueConstructor<Vue>, options?: unknown);
|
||||
}
|
||||
export default LiquorTree;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ $text-size: 0.75em; // Lower looks bad on Firefox
|
||||
Use mask element instead of content/background-image etc.
|
||||
This way we can apply current font color to it to match the theme
|
||||
*/
|
||||
mask: url(~@/presentation/assets/icons/external-link.svg) no-repeat 50% 50%;
|
||||
mask: url(@/presentation/assets/icons/external-link.svg) no-repeat 50% 50%;
|
||||
mask-size: cover;
|
||||
content: '';
|
||||
|
||||
|
||||
@@ -8,9 +8,11 @@
|
||||
@node:unchecked="nodeSelected($event)"
|
||||
ref="liquorTree"
|
||||
>
|
||||
<span class="tree-text" slot-scope="{ node }">
|
||||
<NodeContent :data="convertExistingToNode(node)" />
|
||||
</span>
|
||||
<template v-slot:default="{ node }">
|
||||
<span class="tree-text">
|
||||
<NodeContent :data="convertExistingToNode(node)" />
|
||||
</span>
|
||||
</template>
|
||||
</LiquorTree>
|
||||
</span>
|
||||
<span v-else>Nooo 😢</span>
|
||||
@@ -192,4 +194,3 @@ async function tryUntilDefined<T>(
|
||||
return value;
|
||||
}
|
||||
</script>
|
||||
./Node/INodeContent
|
||||
|
||||
@@ -7,6 +7,7 @@ import fetch from 'cross-fetch';
|
||||
import { ProjectInformation } from '@/domain/ProjectInformation';
|
||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||
import { Version } from '@/domain/Version';
|
||||
import { ViteAppMetadata } from '@/infrastructure/Metadata/Vite/ViteAppMetadata';
|
||||
import { parseProjectInformation } from '@/application/Parser/ProjectInformationParser';
|
||||
import { UpdateProgressBar } from './UpdateProgressBar';
|
||||
|
||||
@@ -28,7 +29,7 @@ export async function handleManualUpdate(info: UpdateInfo) {
|
||||
}
|
||||
|
||||
function getTargetProject(targetVersion: string) {
|
||||
const existingProject = parseProjectInformation(process.env);
|
||||
const existingProject = parseProjectInformation(new ViteAppMetadata());
|
||||
const targetProject = new ProjectInformation(
|
||||
existingProject.name,
|
||||
new Version(targetVersion),
|
||||
|
||||
38
src/presentation/index.html
Normal file
38
src/presentation/index.html
Normal file
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>Privacy is sexy 🍑🍆 - Enforce privacy & security on Windows, macOS and Linux</title>
|
||||
<meta name="robots" content="index,follow" />
|
||||
<meta name="description"
|
||||
content="Web tool to generate scripts for enforcing privacy & security best-practices such as stopping data collection of Windows and different softwares on it." />
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>
|
||||
<style>
|
||||
#javascriptDisabled {
|
||||
background: #eceef1;
|
||||
margin: 5rem auto;
|
||||
max-width: 800px;
|
||||
font-size: 7px;
|
||||
padding: 3rem;
|
||||
border: 1px solid#333a45;
|
||||
font-size: 1.5rem;
|
||||
line-height: 150%;
|
||||
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
|
||||
}
|
||||
</style>
|
||||
<div id="javascriptDisabled">
|
||||
<h1>Problem loading page</h1>
|
||||
<p>The page does not work without JavaScript enabled. Please enable it to use privacy.sexy. There's no shady stuff
|
||||
as 100% of the website is open source.</p>
|
||||
</div>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,16 +1,10 @@
|
||||
import Vue from 'vue';
|
||||
import { buildContext } from '@/application/Context/ApplicationContextFactory';
|
||||
import App from './components/App.vue';
|
||||
import { ApplicationBootstrapper } from './bootstrapping/ApplicationBootstrapper';
|
||||
|
||||
buildContext().then(() => {
|
||||
// hack workaround to solve running tests through
|
||||
// Vue CLI throws 'Top-level-await is only supported in EcmaScript Modules'
|
||||
// once migrated to vite, remove buildContext() call from here and use top-level-await
|
||||
new ApplicationBootstrapper()
|
||||
.bootstrap(Vue);
|
||||
new ApplicationBootstrapper()
|
||||
.bootstrap(Vue);
|
||||
|
||||
new Vue({
|
||||
render: (h) => h(App),
|
||||
}).$mount('#app');
|
||||
});
|
||||
new Vue({
|
||||
render: (h) => h(App),
|
||||
}).$mount('#app');
|
||||
|
||||
BIN
src/presentation/public/favicon.ico
Normal file
BIN
src/presentation/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 353 KiB |
BIN
src/presentation/public/icon.png
Normal file
BIN
src/presentation/public/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
23
src/presentation/public/index.html
Normal file
23
src/presentation/public/index.html
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
<body>
|
||||
<noscript>
|
||||
<style>
|
||||
#javascriptDisabled {
|
||||
background:#eceef1;
|
||||
margin: 5rem auto;
|
||||
max-width: 800px;
|
||||
font-size: 7px;
|
||||
padding: 3rem;
|
||||
border: 1px solid#333a45;
|
||||
font-size: 1.5rem;
|
||||
line-height: 150%;
|
||||
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
|
||||
}
|
||||
</style>
|
||||
<div id="javascriptDisabled">
|
||||
<h1>Problem loading page</h1>
|
||||
<p>The page does not work without JavaScript enabled. Please enable it to use privacy.sexy. There's no shady stuff as 100% of the website is open source.</p>
|
||||
</div>
|
||||
</noscript>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
2
src/presentation/public/robots.txt
Normal file
2
src/presentation/public/robots.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Disallow:
|
||||
Reference in New Issue
Block a user