mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-05 22:07:10 -04:00
🔒 SSR UPDATE
This commit is contained in:
parent
23f82d956a
commit
cb44d3db8b
31 changed files with 991 additions and 210 deletions
34
src/entry-client.ts
Normal file
34
src/entry-client.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
// // entry-client.js
|
||||
// import { createApp } from './main';
|
||||
//
|
||||
// const { app, router } = createApp();
|
||||
//
|
||||
// router.isReady().then(() => {
|
||||
// app.mount('#app', true);
|
||||
// });
|
||||
|
||||
// import 'uno.css'; // 确保这是你的 UnoCSS 生成的样式文件
|
||||
|
||||
import { createHead } from '@vueuse/head';
|
||||
|
||||
// src/entry-client.js
|
||||
import { createApp } from 'vue';
|
||||
import { createPinia } from 'pinia';
|
||||
import App from './App.vue';
|
||||
import router from '@/router';
|
||||
import { plausible } from '@/plugins/plausible.plugin';
|
||||
import { naive } from '@/plugins/naive.plugin';
|
||||
import { i18nPlugin } from '@/plugins/i18n.plugin';
|
||||
|
||||
const app = createApp(App);
|
||||
const pinia = createPinia();
|
||||
app.use(pinia);
|
||||
app.use(createHead());
|
||||
app.use(i18nPlugin);
|
||||
app.use(router);
|
||||
app.use(plausible);
|
||||
app.use(naive);
|
||||
|
||||
router.isReady().then(() => {
|
||||
app.mount('#app', true);
|
||||
});
|
22
src/entry-server.ts
Normal file
22
src/entry-server.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
import { renderToString } from '@vue/server-renderer';
|
||||
import { setup } from '@css-render/vue3-ssr';
|
||||
import { createApp } from './main';
|
||||
// import 'virtual:uno.css';
|
||||
|
||||
/**
|
||||
* Render page with naive ui
|
||||
*/
|
||||
export async function render() {
|
||||
const { app, router, pinia, i18n } = createApp();
|
||||
const { collect } = setup(app);
|
||||
const appHtml = await renderToString(app);
|
||||
const cssHtml = collect();
|
||||
return {
|
||||
cssHtml,
|
||||
appHtml,
|
||||
app,
|
||||
router,
|
||||
pinia,
|
||||
i18n,
|
||||
};
|
||||
}
|
35
src/main.ts
35
src/main.ts
|
@ -1,8 +1,8 @@
|
|||
import { createApp } from 'vue';
|
||||
import { createSSRApp } from 'vue';
|
||||
import { createPinia } from 'pinia';
|
||||
import { createHead } from '@vueuse/head';
|
||||
|
||||
import { registerSW } from 'virtual:pwa-register';
|
||||
// import { registerSW } from 'virtual:pwa-register';
|
||||
import { plausible } from './plugins/plausible.plugin';
|
||||
|
||||
import 'virtual:uno.css';
|
||||
|
@ -13,15 +13,28 @@ import App from './App.vue';
|
|||
import router from './router';
|
||||
import { i18nPlugin } from './plugins/i18n.plugin';
|
||||
|
||||
registerSW();
|
||||
// registerSW();
|
||||
|
||||
const app = createApp(App);
|
||||
// const app = createApp(App);
|
||||
|
||||
app.use(createPinia());
|
||||
app.use(createHead());
|
||||
app.use(i18nPlugin);
|
||||
app.use(router);
|
||||
app.use(naive);
|
||||
app.use(plausible);
|
||||
// app.use(createPinia());
|
||||
// app.use(createHead());
|
||||
// app.use(i18nPlugin);
|
||||
// app.use(router);
|
||||
// app.use(naive);
|
||||
// // app.use(plausible);
|
||||
//
|
||||
// app.mount('#app');
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App);
|
||||
const pinia = createPinia();
|
||||
app.use(pinia);
|
||||
app.use(createHead());
|
||||
app.use(i18nPlugin);
|
||||
app.use(router);
|
||||
app.use(plausible);
|
||||
app.use(naive);
|
||||
// 其他插件...
|
||||
|
||||
app.mount('#app');
|
||||
return { app, router, pinia, i18n: i18nPlugin };
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import type { PaletteOption } from './command-palette.types';
|
|||
const isModalOpen = ref(false);
|
||||
const inputRef = ref();
|
||||
const router = useRouter();
|
||||
const isMac = computed(() => window.navigator.userAgent.toLowerCase().includes('mac'));
|
||||
const isMac = computed(() => true);
|
||||
|
||||
const commandPaletteStore = useCommandPaletteStore();
|
||||
const { searchPrompt, filteredSearchResult } = storeToRefs(commandPaletteStore);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import CSelect from '@/ui/c-select/c-select.vue';
|
||||
|
||||
const { availableLocales, locale } = useI18n();
|
||||
|
||||
const localesLong: Record<string, string> = {
|
||||
|
@ -21,7 +23,7 @@ const localeOptions = computed(() =>
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<c-select
|
||||
<CSelect
|
||||
v-model:value="locale"
|
||||
:options="localeOptions"
|
||||
placeholder="Select a language"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import _ from 'lodash';
|
||||
import type Plausible from 'plausible-tracker';
|
||||
// import type Plausible from 'plausible-tracker';
|
||||
import { inject } from 'vue';
|
||||
|
||||
export { createTrackerService, useTracker };
|
||||
|
@ -7,21 +7,21 @@ export { createTrackerService, useTracker };
|
|||
function createTrackerService({ plausible }: { plausible: ReturnType<typeof Plausible> }) {
|
||||
return {
|
||||
trackEvent({ eventName }: { eventName: string }) {
|
||||
plausible.trackEvent(eventName);
|
||||
// plausible.trackEvent(eventName);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function useTracker() {
|
||||
const plausible: ReturnType<typeof Plausible> | undefined = inject('plausible');
|
||||
// const plausible: ReturnType<any> | undefined = inject('plausible');
|
||||
//
|
||||
// if (_.isNil(plausible)) {
|
||||
// throw new TypeError('Plausible must be instantiated');
|
||||
// }
|
||||
|
||||
if (_.isNil(plausible)) {
|
||||
throw new TypeError('Plausible must be instantiated');
|
||||
}
|
||||
|
||||
const tracker = createTrackerService({ plausible });
|
||||
// const tracker = createTrackerService({ plausible });
|
||||
|
||||
return {
|
||||
tracker,
|
||||
tracker: () => {},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,18 +3,29 @@ import { get } from '@vueuse/core';
|
|||
import type { Plugin } from 'vue';
|
||||
import { createI18n } from 'vue-i18n';
|
||||
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'en',
|
||||
messages,
|
||||
});
|
||||
// const i18n = createI18n({
|
||||
// legacy: false,
|
||||
// locale: 'en',
|
||||
// messages,
|
||||
// });
|
||||
|
||||
export const i18nPlugin: Plugin = {
|
||||
install: (app) => {
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'zh',
|
||||
messages,
|
||||
});
|
||||
app.use(i18n);
|
||||
},
|
||||
};
|
||||
|
||||
export const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'zh',
|
||||
messages,
|
||||
});
|
||||
|
||||
export const translate = function (localeKey: string) {
|
||||
const hasKey = i18n.global.te(localeKey, get(i18n.global.locale));
|
||||
return hasKey ? i18n.global.t(localeKey) : localeKey;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { noop } from 'lodash';
|
||||
|
||||
import Plausible from 'plausible-tracker';
|
||||
// import Plausible from 'plausible-tracker';
|
||||
import type { App } from 'vue';
|
||||
import { config } from '@/config';
|
||||
|
||||
function createFakePlausibleInstance(): Pick<ReturnType<typeof Plausible>, 'trackEvent' | 'enableAutoPageviews'> {
|
||||
function createFakePlausibleInstance(): Pick<ReturnType<any>, 'trackEvent' | 'enableAutoPageviews'> {
|
||||
return {
|
||||
trackEvent: noop,
|
||||
enableAutoPageviews: () => noop,
|
||||
|
@ -22,7 +22,7 @@ function createPlausibleInstance({
|
|||
}
|
||||
}) {
|
||||
if (config.isTrackerEnabled) {
|
||||
return Plausible(config);
|
||||
return config;
|
||||
}
|
||||
|
||||
return createFakePlausibleInstance();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { createRouter, createWebHistory } from 'vue-router';
|
||||
import { createMemoryHistory, createRouter } from 'vue-router';
|
||||
import { layouts } from './layouts/index';
|
||||
import HomePage from './pages/Home.page.vue';
|
||||
import NotFound from './pages/404.page.vue';
|
||||
|
@ -19,7 +19,7 @@ const toolsRedirectRoutes = tools
|
|||
);
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(config.app.baseUrl),
|
||||
history: createMemoryHistory(config.app.baseUrl),
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
sentenceCase,
|
||||
snakeCase,
|
||||
} from 'change-case';
|
||||
import InputCopyable from '../../components/InputCopyable.vue';
|
||||
import InputCopyable from '@/components/InputCopyable.vue';
|
||||
|
||||
const baseConfig = {
|
||||
stripRegexp: /[^A-Za-zÀ-ÖØ-öø-ÿ]+/gi,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { useThemeVars } from 'naive-ui';
|
||||
|
||||
import InputCopyable from '../../components/InputCopyable.vue';
|
||||
import InputCopyable from '@/components/InputCopyable.vue';
|
||||
import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation } from './chmod-calculator.service';
|
||||
|
||||
import type { Group, Scope } from './chmod-calculator.types';
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import type { lib } from 'crypto-js';
|
||||
import { MD5, RIPEMD160, SHA1, SHA224, SHA256, SHA3, SHA384, SHA512, enc } from 'crypto-js';
|
||||
|
||||
import InputCopyable from '../../components/InputCopyable.vue';
|
||||
import InputCopyable from '@/components/InputCopyable.vue';
|
||||
import { convertHexToBin } from './hash-text.service';
|
||||
import { useQueryParam } from '@/composable/queryParams';
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import CInputText from "@/ui/c-input-text/c-input-text.vue";
|
||||
import { extractIBAN, friendlyFormatIBAN, isQRIBAN, validateIBAN } from 'ibantools';
|
||||
import { getFriendlyErrors } from './iban-validator-and-parser.service';
|
||||
import type { CKeyValueListItems } from '@/ui/c-key-value-list/c-key-value-list.types';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import InputCopyable from '../../components/InputCopyable.vue';
|
||||
import InputCopyable from '@/components/InputCopyable.vue';
|
||||
import { convertBase } from './integer-base-converter.model';
|
||||
import { getErrorMessageIfThrows } from '@/utils/error';
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { stringify as stringifyToml } from 'iarna-toml-esm';
|
||||
import JSON5 from 'json5';
|
||||
import { withDefaultOnError } from '../../utils/defaults';
|
||||
import { withDefaultOnError } from '@/utils/defaults';
|
||||
import type { UseValidationRule } from '@/composable/validation';
|
||||
|
||||
const convertJsonToToml = (value: string) => [stringifyToml(JSON5.parse(value))].flat().join('\n').trim();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { useEventListener } from '@vueuse/core';
|
||||
|
||||
import InputCopyable from '../../components/InputCopyable.vue';
|
||||
import InputCopyable from '@/components/InputCopyable.vue';
|
||||
|
||||
const event = ref<KeyboardEvent>();
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ const svgString = computed(() => {
|
|||
return `
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${w} ${h}"${size}>
|
||||
<rect width="${w}" height="${h}" fill="${bgColor.value}"></rect>
|
||||
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-family="monospace" font-size="${fontSize.value}px" fill="${fgColor.value}">${text}</text>
|
||||
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-family="monospace" font-size="${fontSize.value}px" fill="${fgColor.value}">${text}</text>
|
||||
</svg>
|
||||
`.trim();
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { parse as parseToml } from 'iarna-toml-esm';
|
||||
import { withDefaultOnError } from '../../utils/defaults';
|
||||
import { withDefaultOnError } from '@/utils/defaults';
|
||||
import { isValidToml } from './toml.services';
|
||||
import type { UseValidationRule } from '@/composable/validation';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { parse as parseToml } from 'iarna-toml-esm';
|
||||
import { isNotThrowing } from '../../utils/boolean';
|
||||
import { isNotThrowing } from '@/utils/boolean';
|
||||
|
||||
export { isValidToml };
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { parse as parseToml } from 'iarna-toml-esm';
|
||||
import { stringify as stringifyToYaml } from 'yaml';
|
||||
import { withDefaultOnError } from '../../utils/defaults';
|
||||
import { withDefaultOnError } from '@/utils/defaults';
|
||||
import { isValidToml } from '../toml-to-json/toml.services';
|
||||
import type { UseValidationRule } from '@/composable/validation';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import InputCopyable from '../../components/InputCopyable.vue';
|
||||
import InputCopyable from '@/components/InputCopyable.vue';
|
||||
import { isNotThrowing } from '@/utils/boolean';
|
||||
import { withDefaultOnError } from '@/utils/defaults';
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { stringify as stringifyToml } from 'iarna-toml-esm';
|
||||
import { parse as parseYaml } from 'yaml';
|
||||
import { withDefaultOnError } from '../../utils/defaults';
|
||||
import { withDefaultOnError } from '@/utils/defaults';
|
||||
import type { UseValidationRule } from '@/composable/validation';
|
||||
|
||||
const convertYamlToToml = (value: string) => [stringifyToml(parseYaml(value))].flat().join('\n').trim();
|
||||
|
|
|
@ -3,6 +3,7 @@ import { useAppTheme } from '../theme/themes';
|
|||
import type { CLabelProps } from '../c-label/c-label.types';
|
||||
import type { CSelectOption } from './c-select.types';
|
||||
import { useTheme } from './c-select.theme';
|
||||
import CLabel from '@/ui/c-label/c-label.vue';
|
||||
import { clamp } from '@/modules/shared/number.models';
|
||||
import { useFuzzySearch } from '@/composable/fuzzySearch';
|
||||
|
||||
|
@ -138,7 +139,7 @@ function onSearchInput() {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<c-label v-bind="props">
|
||||
<CLabel v-bind="props">
|
||||
<div ref="elementRef" relative class="c-select" w-full>
|
||||
<div
|
||||
flex flex-nowrap cursor-pointer items-center
|
||||
|
@ -190,7 +191,7 @@ function onSearchInput() {
|
|||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</c-label>
|
||||
</CLabel>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue