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:
undergroundwires
2023-08-23 23:12:56 +02:00
parent 6e40edd3f8
commit 736590558b
52 changed files with 1870 additions and 2286 deletions

View File

@@ -0,0 +1,3 @@
# presentation
See [`presentation.md`](./../../docs/presentation.md)

View File

@@ -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;

View File

@@ -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;

View 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/";

View File

@@ -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';

View File

@@ -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;
}

View File

@@ -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: '';

View File

@@ -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

View File

@@ -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),

View 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>

View File

@@ -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');

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View 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>

View File

@@ -0,0 +1,2 @@
User-agent: *
Disallow: