refactor(frontend): vue cli v4 -> vite (#1000)

This commit is contained in:
Kristaps Fabians Geikins
2022-10-05 15:59:11 +03:00
committed by GitHub
parent f5468c2b33
commit 2fef8b7de3
29 changed files with 1054 additions and 8216 deletions
+2 -1
View File
@@ -2,6 +2,7 @@
packages/server/.env
packages/server/dist
packages/frontend/dist
packages/frontend/profiler
packages/viewer/dist
packages/objectloader/dist
*.env
@@ -49,4 +50,4 @@ packages/server/.vscode/*.log
# ST workspace files
./speckle.sublime-project
./speckle.sublime-workspace
./speckle.sublime-workspace
+1 -2
View File
@@ -43,8 +43,7 @@
"tslib": "^2.3.1",
"core-js": "3.22.4",
"graphql": "^15",
"typescript": "^4.5.4",
"vue-loader": "^15.10.0"
"typescript": "^4.5.4"
},
"config": {
"commitizen": {
@@ -1,68 +0,0 @@
const TARGET = 'es2019'
function prepareJs(jsRule, api) {
// Delete babel related loaders
jsRule.uses.delete('thread-loader').delete('babel-loader')
// Add caching config
jsRule
.use('cache-loader')
.loader('cache-loader')
.options(
api.genCacheConfig('js-esbuild-loader', {
target: TARGET,
esbuildLoaderVersion: require('esbuild-loader/package.json').version
})
)
// Add new esbuild loader
jsRule.use('esbuild-loader').loader('esbuild-loader').options({
target: TARGET
})
}
function prepareTs(tsRule, api) {
// Delete related loaders
tsRule.uses.delete('ts-loader').delete('babel-loader')
// Add caching config
tsRule
.use('cache-loader')
.loader('cache-loader')
.options(
api.genCacheConfig('ts-esbuild-loader', {
target: TARGET,
esbuildLoaderVersion: require('esbuild-loader/package.json').version
})
)
// Add new esbuild loader
tsRule.use('esbuild-loader').loader('esbuild-loader').options({
target: TARGET,
loader: 'tsx'
})
}
/**
* Dev builds use esbuild instead of babel for improved speed
* @param {import('@vue/cli-service/lib/PluginAPI')} api
**/
function plugin(api) {
const isProdBuild = process.env.NODE_ENV === 'production'
const isDevBuild = !isProdBuild
if (!isDevBuild) return
api.chainWebpack((config) => {
const jsRule = config.module.rule('js').test(/\.m?jsx?$/)
prepareJs(jsRule, api)
const tsRule = config.module.rule('ts').test(/\.ts$/)
prepareTs(tsRule, api)
// No TSX support currently, we can look into it if needed
config.module.rules.delete('tsx')
})
}
module.exports = plugin
@@ -1,27 +0,0 @@
const TARGET = 'es2019'
/**
* GQL file support (previously this was managed by the vue apollo cli plugin)
* @param {import('@vue/cli-service/lib/PluginAPI')} api
**/
function plugin(api) {
api.chainWebpack((config) => {
const gqlRule = config.module.rule('gql').test(/\.(gql|graphql)$/)
// add caching
gqlRule
.use('cache-loader')
.loader('cache-loader')
.options(
api.genCacheConfig('gql-cache-loader', {
target: TARGET,
graphqltagVersion: require('graphql-tag/package.json').version
})
)
// add gql loader
gqlRule.use('gql-loader').loader('graphql-tag/loader')
})
}
module.exports = plugin
@@ -1,7 +1,6 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!-- <base href="/appname/"> -->
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta
@@ -10,11 +9,11 @@
/>
<meta property="og:title" content="Speckle" />
<meta property="og:description" content="" />
<meta property="og:image" content="https://speckle.xyz/og_image.png" />
<meta property="og:url" content="<%= BASE_URL %>" />
<meta property="og:image" content="/og_image.png" />
<meta property="og:url" content="/" />
<meta name="twitter:card" content="summary_large_image" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<title><%= htmlWebpackPlugin.options.title %></title>
<link rel="icon" href="/favicon.ico" />
<title>Speckle</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
@@ -135,9 +134,9 @@
font-size: 10px;
"
>
<img src="<%= BASE_URL %>logo.svg" style="max-width: 50px" class="tada" />
<img src="/logo.svg" style="max-width: 50px" class="tada" />
</div>
</div>
<!-- built files will be auto injected -->
<script type="module" src="./src/main/app.js"></script>
</body>
</html>
@@ -71,29 +71,29 @@ server {
location / {
root /usr/share/nginx/html;
index app.html;
try_files $uri $uri/ /app.html;
add_header Cache-Control "no-store, no-cache, must-revalidate";
index index.html;
try_files $uri $uri/ /index.html;
add_header Cache-Control "no-store, no-cache, must-revalidate";
}
location ~* ^/(favicon.ico|logo.svg) {
location ~* ^/(favicon.ico|logo.svg|loadingImage.png|og_image.png) {
root /usr/share/nginx/html;
index app.html;
try_files $uri $uri/ /app.html;
index index.html;
try_files $uri $uri/ /index.html;
expires 1d;
}
location ~* ^/(js/.*|fonts/.*|(css/.*)|(img/.*)) {
location ~* ^/(js/.*|fonts/.*|(css/.*)|(img/.*)|(assets/.*)) {
root /usr/share/nginx/html;
index app.html;
try_files $uri $uri/ /app.html;
index index.html;
try_files $uri $uri/ /index.html;
expires 1y;
}
location ~ ^/streams/.* {
default_type text/html;
content_by_lua_block {
local f = assert(io.open('/usr/share/nginx/html/app.html', "rb"))
local f = assert(io.open('/usr/share/nginx/html/index.html', "rb"))
local content = f:read("*all")
f:close()
local http_host = ngx.var.http_host
+15 -35
View File
@@ -3,16 +3,13 @@
"version": "2.5.4",
"private": true,
"scripts": {
"serve": "ws -p 8080 -d dist -r '/([a-zA-Z0-9-_/]*)(\\?.*)? -> /app.html' ",
"build": "vue-cli-service build --mode production --silent",
"lint": "eslint . --ext .js,.ts,.vue,.tsx,.jsx",
"dev": "vite",
"build": "vite build",
"serve": "vite preview --port 8080",
"profile": "vite-bundle-visualizer --output profiler/stats.html",
"lint:eslint": "eslint . --ext .js,.ts,.vue,.tsx,.jsx",
"lint:ts": "vue-tsc --noEmit",
"build:dev": "vue-cli-service build --mode development --silent",
"build:dev:profile": "yarn build:dev -- --profile",
"build:profile": "yarn build -- --profile",
"dev": "vue-cli-service serve --mode development",
"inspect": "vue-cli-service inspect --mode production",
"inspect:dev": "vue-cli-service inspect --mode development",
"lint": "yarn lint:eslint && yarn lint:ts",
"gqlgen": "graphql-codegen --config codegen.yml"
},
"dependencies": {
@@ -44,6 +41,7 @@
"graphql": "^15.0.0",
"graphql-tag": "^2.12.6",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"numeral": "^2.0.6",
"portal-vue": "^2.1.7",
"regenerator-runtime": "^0.13.9",
@@ -79,41 +77,23 @@
"@types/node": "^17.0.43",
"@typescript-eslint/eslint-plugin": "^5.21.0",
"@typescript-eslint/parser": "^5.21.0",
"@vue/cli": "^4.5.19",
"@vue/cli-plugin-babel": "~4.3.1",
"@vue/cli-plugin-router": "~4.3.1",
"@vue/cli-plugin-typescript": "~4.5.19",
"@vue/cli-service": "~4.3.1",
"@vue/eslint-config-typescript": "^11.0.0",
"babel-eslint": "^10.1.0",
"@vitejs/plugin-vue2": "^1.1.2",
"@vue/eslint-config-typescript": "^11.0.1",
"babel-plugin-lodash": "^3.3.4",
"duplicate-dependencies-webpack-plugin": "^1.0.2",
"esbuild-loader": "^2.18.0",
"eslint": "^8.11.0",
"eslint-config-prettier": "^8.5.0",
"eslint-loader": "^4.0.2",
"eslint-plugin-vue": "^9.2.0",
"local-web-server": "^5.2.0",
"lodash-webpack-plugin": "^0.11.6",
"prettier": "^2.5.1",
"sass": "~1.32.6",
"sass-loader": "^8.0.0",
"speed-measure-webpack-plugin": "^1.5.0",
"type-fest": "^2.13.1",
"typescript": "~4.1.5",
"vue-cli-plugin-vuetify": "^2.5.1",
"vue-tsc": "^0.40.13",
"vuetify-loader": "^1.9.1",
"webpack": "^4.46.0",
"webpack-bundle-analyzer": "^4.5.0"
"typescript": "~4.5.5",
"unplugin-vue-components": "^0.22.4",
"vite": "^3.1.0",
"vite-bundle-visualizer": "^0.4.1",
"vite-plugin-simple-gql": "^0.5.0",
"vue-tsc": "^0.40.13"
},
"engines": {
"node": "^16.0.0"
},
"vuePlugins": {
"service": [
"./build-config/esbuildPlugin.js",
"./build-config/gqlPlugin.js"
]
}
}
+2 -3
View File
@@ -12,9 +12,8 @@ import { formatNumber } from '@/plugins/formatNumber'
// Accepts 'max' parameter to set it's formatting while being animated
Vue.filter('prettynum', formatNumber)
// process.env.NODE_ENV is injected by Webpack
const enableDevMode =
!!process.env.FORCE_VUE_DEVTOOLS || process.env.NODE_ENV === 'development'
// env vars injected by Vite
const enableDevMode = !!import.meta.env.FORCE_VUE_DEVTOOLS || !!import.meta.env.DEV
Vue.config.productionTip = enableDevMode
Vue.config.devtools = enableDevMode
+3 -3
View File
@@ -20,7 +20,7 @@ import {
incomingOverwritesExistingMergeFunction
} from '@/main/lib/core/helpers/apolloSetupHelper'
import { merge } from 'lodash'
import { statePolicies as commitObjectViewerStatePolicies } from '@/main/lib/viewer/commit-object-viewer/stateManager'
import { statePolicies as commitObjectViewerStatePolicies } from '@/main/lib/viewer/commit-object-viewer/stateManagerCore'
// Name of the localStorage item
const AUTH_TOKEN = LocalStorageKeys.AuthToken
@@ -29,7 +29,7 @@ const httpEndpoint = `${window.location.origin}/graphql`
// WS endpoint
const wsEndpoint = `${window.location.origin.replace('http', 'ws')}/graphql`
// app version
const appVersion = process.env.SPECKLE_SERVER_VERSION || 'unknown'
const appVersion = import.meta.env.SPECKLE_SERVER_VERSION || 'unknown'
function hasAuthToken() {
return !!AppLocalStorage.get(AUTH_TOKEN)
@@ -201,7 +201,7 @@ function createApolloClient() {
link,
cache,
ssrForceFetchDelay: 100,
connectToDevTools: process.env.NODE_ENV !== 'production',
connectToDevTools: import.meta.env.DEV,
name: 'web',
version: appVersion
})
+1 -1
View File
@@ -1,4 +1,4 @@
<template lang="html">
<template>
<router-view></router-view>
</template>
<script>
+1 -3
View File
@@ -35,9 +35,7 @@ Vue.use(PerfectScrollbar)
// Async ApexChart load
Vue.component('ApexChart', async () => {
const VueApexCharts = await import(
/* webpackChunkName: "vue-apexcharts" */ 'vue-apexcharts'
)
const VueApexCharts = await import('vue-apexcharts')
Vue.use(VueApexCharts)
return VueApexCharts
@@ -1,4 +1,4 @@
<template lang="html">
<template>
<div style="height: 100vh; position: relative" class="speckle-viewer transparent">
<div
id="rendererparent"
@@ -48,7 +48,7 @@
</template>
<script setup lang="ts">
import { computed, PropType, ref } from 'vue'
import { Get } from 'type-fest'
import type { Get } from 'type-fest'
import {
StreamRole,
StreamWithCollaboratorsQuery,
@@ -86,7 +86,7 @@
<v-card>
<v-card-title>Choose a new profile picture</v-card-title>
<v-card-text class="pl-10 pr-0 mt-5">
<v-image-input
<vuetify-image-input
v-model="imageData"
:image-quality="0.85"
:image-height="256"
@@ -113,7 +113,7 @@ import { AppLocalStorage } from '@/utils/localStorage'
export default {
components: {
VImageInput: () => import('vuetify-image-input/a-la-carte'),
VuetifyImageInput: () => import('vuetify-image-input/a-la-carte'),
UserAvatarIcon: () => import('@/main/components/common/UserAvatarIcon'),
SectionCard: () => import('@/main/components/common/SectionCard'),
UserEditDialog: () => import('@/main/dialogs/UserEditDialog')
@@ -87,12 +87,17 @@ import {
unIsolateObjects,
useCommitObjectViewerParams
} from '@/main/lib/viewer/commit-object-viewer/stateManager'
import { Ripple } from 'vuetify/lib/directives'
export default {
components: {
SourceAppAvatar: () => import('@/main/components/common/SourceAppAvatar'),
UserAvatar: () => import('@/main/components/common/UserAvatar'),
ObjectProperties: () => import('@/main/components/viewer/ObjectProperties')
},
directives: {
Ripple
},
props: {
resource: {
type: Object,
@@ -65,10 +65,15 @@ import {
showObjects,
useCommitObjectViewerParams
} from '@/main/lib/viewer/commit-object-viewer/stateManager'
import { Ripple } from 'vuetify/lib/directives'
export default {
components: {
ObjectProperties: () => import('@/main/components/viewer/ObjectProperties')
},
directives: {
Ripple
},
props: {
resource: {
type: Object,
@@ -9,7 +9,7 @@ import { MaybeFalsy, Nullable, vueWithMixins } from '@/helpers/typeHelpers'
import { convertThrowIntoFetchResult } from '@/main/lib/common/apollo/helpers/apolloOperationHelper'
import { StreamEvents } from '@/main/lib/core/helpers/eventHubHelper'
import { IsLoggedInMixin } from '@/main/lib/core/mixins/isLoggedInMixin'
import { Get } from 'type-fest'
import type { Get } from 'type-fest'
import { PropType } from 'vue'
export type StreamInviteType = NonNullable<Get<StreamInviteQuery, 'streamInvite'>>
@@ -1,20 +1,21 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
// NOTE: any disabling temporary, most of the filtering stuff will go away
import { GetReactiveVarType, Nullable } from '@/helpers/typeHelpers'
import { Nullable } from '@/helpers/typeHelpers'
import { setupNewViewerInjection } from '@/main/lib/viewer/core/composables/viewer'
import { makeVar, TypePolicies } from '@apollo/client/cache'
import {
DefaultViewerParams,
Viewer,
SelectionEvent,
PropertyInfo,
FilteringState,
NumericPropertyInfo
} from '@speckle/viewer'
import emojis from '@/main/store/emojis'
import { cloneDeep } from 'lodash'
import { computed, ComputedRef, inject, InjectionKey, provide, Ref } from 'vue'
import {
commitObjectViewerState,
StateType
} from '@/main/lib/viewer/commit-object-viewer/stateManagerCore'
const ViewerStreamIdKey: InjectionKey<Ref<string>> = Symbol(
'COMMIT_OBJECT_VIEWER_STREAMID'
@@ -40,29 +41,6 @@ type GlobalViewerData = {
*/
let globalViewerData: Nullable<GlobalViewerData> = null
/**
* Queryable Apollo Client state
*/
const commitObjectViewerState = makeVar({
viewerBusy: false,
selectedCommentMetaData: null as Nullable<{
id: number
selectionLocation: Record<string, unknown>
}>,
addingComment: false,
preventCommentCollapse: false,
commentReactions: ['❤️', '✏️', '🔥', '⚠️'],
emojis,
// New viewer & filter vars
currentFilterState: null as Nullable<FilteringState>,
selectedObjects: [] as UnknownObject[],
objectProperties: [] as PropertyInfo[],
localFilterPropKey: null as Nullable<string>,
sectionBox: false
})
export type StateType = GetReactiveVarType<typeof commitObjectViewerState>
export type LocalFilterState = {
hiddenIds?: string[]
isolatedIds?: string[]
@@ -72,22 +50,6 @@ export type LocalFilterState = {
sectionBox?: number[]
}
/**
* Merge (through _.merge) these with the rest of your Apollo Client `typePolicies` to set up
* commit object viewer state management
*/
export const statePolicies: TypePolicies = {
Query: {
fields: {
commitObjectViewerState: {
read() {
return commitObjectViewerState()
}
}
}
}
}
/**
* Get current global Commit Object Viewer instance or create one
*/
@@ -0,0 +1,55 @@
import { GetReactiveVarType, Nullable } from '@/helpers/typeHelpers'
import { makeVar, TypePolicies } from '@apollo/client/cache'
import type { PropertyInfo, FilteringState } from '@speckle/viewer'
import emojis from '@/main/store/emojis'
/**
* Actual state from state manager. Extracted here to ensure that we don't bundle the full viewer & three.js
* on every page just to initialize the state.
*
* BE VERY CAREFUL AND KEEP THIS MODULE LIGHTWEIGHT. IMPORTING TYPES FROM VIEWER/THREE IS FINE AS LONG
* AS YOU USE `import type {...}`.
*/
type UnknownObject = Record<string, unknown>
/**
* Queryable Apollo Client state.
*
* Do not use directly! Use GQL queries to read and stateManager.ts mutators to mutate.
*/
export const commitObjectViewerState = makeVar({
viewerBusy: false,
selectedCommentMetaData: null as Nullable<{
id: number
selectionLocation: Record<string, unknown>
}>,
addingComment: false,
preventCommentCollapse: false,
commentReactions: ['❤️', '✏️', '🔥', '⚠️'],
emojis,
// New viewer & filter vars
currentFilterState: null as Nullable<FilteringState>,
selectedObjects: [] as UnknownObject[],
objectProperties: [] as PropertyInfo[],
localFilterPropKey: null as Nullable<string>,
sectionBox: false
})
export type StateType = GetReactiveVarType<typeof commitObjectViewerState>
/**
* Merge (through _.merge) these with the rest of your Apollo Client `typePolicies` to set up
* commit object viewer state management
*/
export const statePolicies: TypePolicies = {
Query: {
fields: {
commitObjectViewerState: {
read() {
return commitObjectViewerState()
}
}
}
}
}
@@ -1,4 +1,4 @@
<template lang="html">
<template>
<v-container v-if="$apollo.loading" fluid>
<v-skeleton-loader type="article"></v-skeleton-loader>
</v-container>
@@ -271,7 +271,7 @@ import {
StreamCommitQueryQuery,
StreamObjectNoDataQuery
} from '@/graphql/generated/graphql'
import { Get } from 'type-fest'
import type { Get } from 'type-fest'
import { has } from 'lodash'
import { Nullable } from '@/helpers/typeHelpers'
import { getCamArray } from '@/main/lib/viewer/core/helpers/cameraHelper'
@@ -0,0 +1,88 @@
// generated by unplugin-vue-components
// We suggest you to commit this file into source control
// Read more: https://github.com/vuejs/core/pull/3399
import '@vue/runtime-core'
export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
VAlert: typeof import('vuetify/lib')['VAlert']
VApp: typeof import('vuetify/lib')['VApp']
VAppBar: typeof import('vuetify/lib')['VAppBar']
VAppBarNavIcon: typeof import('vuetify/lib')['VAppBarNavIcon']
VAutocomplete: typeof import('vuetify/lib')['VAutocomplete']
VAvatar: typeof import('vuetify/lib')['VAvatar']
VBadge: typeof import('vuetify/lib')['VBadge']
VBtn: typeof import('vuetify/lib')['VBtn']
VBtnToggle: typeof import('vuetify/lib')['VBtnToggle']
VCard: typeof import('vuetify/lib')['VCard']
VCardActions: typeof import('vuetify/lib')['VCardActions']
VCardSubtitle: typeof import('vuetify/lib')['VCardSubtitle']
VCardText: typeof import('vuetify/lib')['VCardText']
VCardTitle: typeof import('vuetify/lib')['VCardTitle']
VCheckbox: typeof import('vuetify/lib')['VCheckbox']
VChip: typeof import('vuetify/lib')['VChip']
VCol: typeof import('vuetify/lib')['VCol']
VCombobox: typeof import('vuetify/lib')['VCombobox']
VContainer: typeof import('vuetify/lib')['VContainer']
VDialog: typeof import('vuetify/lib')['VDialog']
VDivider: typeof import('vuetify/lib')['VDivider']
VExpandTransition: typeof import('vuetify/lib')['VExpandTransition']
VExpansionPanel: typeof import('vuetify/lib')['VExpansionPanel']
VExpansionPanelContent: typeof import('vuetify/lib')['VExpansionPanelContent']
VExpansionPanelHeader: typeof import('vuetify/lib')['VExpansionPanelHeader']
VExpansionPanels: typeof import('vuetify/lib')['VExpansionPanels']
VFadeTransition: typeof import('vuetify/lib')['VFadeTransition']
VForm: typeof import('vuetify/lib')['VForm']
VHover: typeof import('vuetify/lib')['VHover']
VIcon: typeof import('vuetify/lib')['VIcon']
VImg: typeof import('vuetify/lib')['VImg']
VItem: typeof import('vuetify/lib')['VItem']
VItemGroup: typeof import('vuetify/lib')['VItemGroup']
VList: typeof import('vuetify/lib')['VList']
VListGroup: typeof import('vuetify/lib')['VListGroup']
VListItem: typeof import('vuetify/lib')['VListItem']
VListItemAction: typeof import('vuetify/lib')['VListItemAction']
VListItemAvatar: typeof import('vuetify/lib')['VListItemAvatar']
VListItemContent: typeof import('vuetify/lib')['VListItemContent']
VListItemGroup: typeof import('vuetify/lib')['VListItemGroup']
VListItemIcon: typeof import('vuetify/lib')['VListItemIcon']
VListItemSubtitle: typeof import('vuetify/lib')['VListItemSubtitle']
VListItemTitle: typeof import('vuetify/lib')['VListItemTitle']
VMain: typeof import('vuetify/lib')['VMain']
VMenu: typeof import('vuetify/lib')['VMenu']
VNavigationDrawer: typeof import('vuetify/lib')['VNavigationDrawer']
VOverlay: typeof import('vuetify/lib')['VOverlay']
VPagination: typeof import('vuetify/lib')['VPagination']
VProgressCircular: typeof import('vuetify/lib')['VProgressCircular']
VProgressLinear: typeof import('vuetify/lib')['VProgressLinear']
VRow: typeof import('vuetify/lib')['VRow']
VScrollXTransition: typeof import('vuetify/lib')['VScrollXTransition']
VScrollYTransition: typeof import('vuetify/lib')['VScrollYTransition']
VSelect: typeof import('vuetify/lib')['VSelect']
VSheet: typeof import('vuetify/lib')['VSheet']
VSimpleTable: typeof import('vuetify/lib')['VSimpleTable']
VSkeletonLoader: typeof import('vuetify/lib')['VSkeletonLoader']
VSlider: typeof import('vuetify/lib')['VSlider']
VSlideXTransition: typeof import('vuetify/lib')['VSlideXTransition']
VSlideYTransition: typeof import('vuetify/lib')['VSlideYTransition']
VSnackbar: typeof import('vuetify/lib')['VSnackbar']
VSpacer: typeof import('vuetify/lib')['VSpacer']
VSubheader: typeof import('vuetify/lib')['VSubheader']
VSwitch: typeof import('vuetify/lib')['VSwitch']
VTextarea: typeof import('vuetify/lib')['VTextarea']
VTextField: typeof import('vuetify/lib')['VTextField']
VThemeProvider: typeof import('vuetify/lib')['VThemeProvider']
VTimeline: typeof import('vuetify/lib')['VTimeline']
VTimelineItem: typeof import('vuetify/lib')['VTimelineItem']
VToolbar: typeof import('vuetify/lib')['VToolbar']
VToolbarItems: typeof import('vuetify/lib')['VToolbarItems']
VToolbarTitle: typeof import('vuetify/lib')['VToolbarTitle']
VTooltip: typeof import('vuetify/lib')['VTooltip']
VWindow: typeof import('vuetify/lib')['VWindow']
VWindowItem: typeof import('vuetify/lib')['VWindowItem']
}
}
+2 -1
View File
@@ -24,7 +24,8 @@
"@types/node",
"@types/mixpanel-browser",
"vuetify",
"@types/dompurify"
"@types/dompurify",
"vite/client"
]
},
"vueCompilerOptions": {
+63
View File
@@ -0,0 +1,63 @@
import path from 'path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue2'
import Components from 'unplugin-vue-components/vite'
import { VuetifyResolver } from 'unplugin-vue-components/resolvers'
import gql from 'vite-plugin-simple-gql'
const port = '8080'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue({
template: {
transformAssetUrls: {
// defaults
video: ['src', 'poster'],
source: ['src'],
img: ['src'],
image: ['xlink:href', 'href'],
use: ['xlink:href', 'href'],
// support for vuetify components
'v-img': ['src']
}
}
}),
Components({
resolvers: [VuetifyResolver()],
dts: './src/type-augmentations/unplugin-components.d.ts'
}),
gql()
],
server: {
port,
hmr: {
port
}
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
// redirects lodash to lodash-es in prod build, for a reduced & tree-shaked bundle
lodash: 'lodash-es'
},
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
},
css: {
// https://vitejs.dev/config/#css-preprocessoroptions
preprocessorOptions: {
sass: {
additionalData: [
// vuetify variable overrides
'@import "@/sass/variables.scss"',
''
].join('\n')
}
}
},
optimizeDeps: {
include: ['vuetify', 'vuetify/lib']
}
})
-64
View File
@@ -1,64 +0,0 @@
/* eslint-env node */
const webpack = require('webpack')
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin')
const { DuplicateReporterPlugin } = require('duplicate-dependencies-webpack-plugin')
const isProdBuild = process.env.NODE_ENV === 'production'
const shouldEnableProfiling = (process.argv || []).includes('--profile')
/** @type {import('@vue/cli-service').ProjectOptions} */
const config = {
chainWebpack: (config) => {
// Adding profiling plugins, if flag set
if (shouldEnableProfiling) {
config.plugin('webpack-profiling').use(webpack.debug.ProfilingPlugin)
config.plugin('speed-measure').use(SpeedMeasurePlugin)
config.plugin('bundle-analyzer').use(BundleAnalyzerPlugin)
}
config.plugin('duplicate-detection').use(DuplicateReporterPlugin)
config.plugin('lodash-optimization').use(LodashModuleReplacementPlugin)
// Add plugin for injecting env vars
config
.plugin('speckle-env-vars')
.use(webpack.EnvironmentPlugin, [
{ SPECKLE_SERVER_VERSION: 'unknown', FORCE_VUE_DEVTOOLS: false }
])
// Setting source map according to build env
config.devtool(isProdBuild ? false : 'eval-source-map')
// Enable .mjs support
config.module
.rule('mjs-support')
.test(/\.mjs$/)
.type('javascript/auto')
.include.add(/node_modules/)
.end()
},
productionSourceMap: false,
pages: {
app: {
entry: 'src/main/app.js',
title: 'Speckle',
template: 'public/app.html',
filename: 'app.html'
}
},
devServer: {
host: 'localhost',
proxy: 'http://localhost:3000',
historyApiFallback: {
rewrites: [
{ from: /^\/$/, to: '/app.html' },
{ from: /./, to: '/app.html' }
]
}
// progress: false // Disables progress bar in dev server build
}
}
module.exports = config
+6 -1
View File
@@ -177,11 +177,16 @@ export async function startHttp(app: Express, customPortOverride?: number) {
if (process.env.NODE_ENV === 'development') {
const { createProxyMiddleware } = await import('http-proxy-middleware')
// even tho it has default values, it fixes http-proxy setting `Connection: close` on each request
// slowing everything down
const defaultAgent = new http.Agent()
const frontendProxy = createProxyMiddleware({
target: `http://${frontendHost}:${frontendPort}`,
changeOrigin: true,
ws: false,
logLevel: 'silent'
logLevel: 'silent',
agent: defaultAgent
})
app.use('/', frontendProxy)
@@ -1 +1,9 @@
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly FORCE_VUE_DEVTOOLS: boolean
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
+12 -10
View File
@@ -10,18 +10,23 @@ import { DEFAULT_EXTENSIONS } from '@babel/core'
const isProd = process.env.NODE_ENV === 'production'
const sourcemap = isProd ? false : 'inline'
/** @returns {import('rollup').RollupOptions} */
const config = (file, format, firstOne = false) => ({
/** @type {import('rollup').RollupOptions} */
const config = {
input: 'src/index.ts',
output: [
{
file,
format,
file: 'dist/speckleviewer.esm.js',
format: 'esm',
sourcemap
},
{
file: 'dist/speckleviewer.js',
format: 'cjs',
sourcemap
}
],
plugins: [
...(isProd && firstOne ? [clean({ targets: 'dist/*' })] : []),
clean({ targets: 'dist/*' }),
rebasePlugin({ keepName: true }),
copyPlugin({
targets: [{ src: './always-bundled-assets/**/*', dest: 'dist/assets' }]
@@ -39,9 +44,6 @@ const config = (file, format, firstOne = false) => ({
],
// Externalizing all deps, we don't want to bundle them in cause this is a library
external: Object.keys(pkg.dependencies || {}).map((d) => new RegExp(`^${d}(\\/.*)?$`))
})
}
export default [
config('dist/speckleviewer.esm.js', 'esm', true),
config('dist/speckleviewer.js', 'cjs')
]
export default config
+757 -7930
View File
File diff suppressed because it is too large Load Diff