堆栈: Electron + vite + vue
我有续集框架的问题。我的模型看起来像:
Operation.init({
itemId: {
type: DataTypes.STRING
},
startDate: {
type: DataTypes.DATE,
},
endDate: {
type: DataTypes.DATE,
},
code: {
type: DataTypes.STRING
}
}, {
sequelize,
modelName: 'Operation',
timestamps: false
})
当我尝试在渲染器进程中创建操作对象时,我可以看到错误:
Uncaught (in promise) TypeError: moment.isMoment is not a function
at DATE2._stringify (data-types.js:472:17)
at DATE2.stringify (data-types.js:24:19)
at DATE2.bindParam (data-types.js:32:35)
at MSSQLQueryGenerator.format (query-generator.js:1147:29)
at MSSQLQueryGenerator.insertQuery (query-generator.js:193:30)
at MSSqlQueryInterface.insert (query-interface.js:790:37)
at OperationVisualControl.save (model.js:4154:73)
at async OperationVisualControl.create (model.js:2305:12)
vite.config.ts
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import Vue from '@vitejs/plugin-vue'
import VueDevTools from 'vite-plugin-vue-devtools'
import Vuetify, { transformAssetUrls } from 'vite-plugin-vuetify'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import VueRouter from 'unplugin-vue-router/vite'
import Layouts from 'vite-plugin-vue-meta-layouts'
import { VueRouterAutoImports } from 'unplugin-vue-router'
import Modify from '@kingyue/rollup-plugin-modify'
import * as mdicons from '@mdi/js'
import Electron from 'vite-plugin-electron'
import { notBundle } from 'vite-plugin-electron/plugin'
import { nodePolyfills } from 'vite-plugin-node-polyfills'
const mdi: Record<string, string> = {}
Object.keys(mdicons).forEach((key) => {
const value = (mdicons as Record<string, string>)[key]
mdi[
key.replace(
/[A-Z]+(?![a-z])|[A-Z0-9]/g,
($, ofs) => (ofs ? '-' : '') + $.toLowerCase()
)
] = value
})
// https://vitejs.dev/config/
export default defineConfig({
build: { target: 'esnext', chunkSizeWarningLimit: 5000 },
server: {
port: 3000
},
plugins: [
nodePolyfills(),
Modify({
exclude: ['node_modules/**'],
find: /\b(?<![/\w])(mdi-[\w-]+)\b(?!\.)/,
replace: (match: string) => {
if (mdi[match]) {
return mdi[match]
} else {
console.warn('[plugin-modify] No matched svg icon for ' + match)
return match
}
},
sourcemap: false,
}),
VueDevTools(),
VueRouter({ importMode: 'sync', dts: './src/typed-router.d.ts' }),
Vue({ template: { transformAssetUrls } }),
Layouts(),
Vuetify({ autoImport: true }),
Components({ dts: './src/components.d.ts', types: [] }),
AutoImport({
imports: [
'vue',
'pinia',
VueRouterAutoImports,
{
vuetify: [
'useTheme',
'useRtl',
'useLocale',
'useDisplay',
'useLayout',
],
},
],
dts: 'src/auto-imports.d.ts',
dirs: ['src/stores'],
}),
Electron([
{
entry: 'electron/main.ts',
vite: {
plugins: [notBundle(/* NotBundleOptions */)],
},
}
]),
],
css: {
devSourcemap: true,
},
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
},
}
})
tsconfig.json
{
"files": [],
"references": [
{
"path": "./tsconfig.node.json"
},
{
"path": "./tsconfig.app.json"
}
]
}
tsconfig.node.json
{
"extends": "./tsconfig.app.json",
"include": ["vite.config.*", "electron/**/*",],
"compilerOptions": {
"composite": true,
"types": ["node"]
}
}
tsconfig.app.json
{
"extends": "@vue/tsconfig/tsconfig.json",
"include": ["src/**/*", "src/**/*.vue"],
"exclude": ["src/**/__tests__/*"],
"compilerOptions": {
"composite": true,
"moduleResolution": "node",
"lib": ["ESNext", "DOM", "DOM.Iterable"],
"types": [],
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
package.json
"scripts": {
"dev": "vite",
"build": "vite build && electron-builder",
"preview": "vite preview",
"typecheck": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"format": "prettier --write src/"
},
"dependencies": {
"@electron/remote": "^2.0.10",
"@mdi/js": "^7.3.67",
"@vueuse/core": "^10.6.0",
"moment": "^2.30.1",
"pinia": "^2.1.7",
"pinia-plugin-persistedstate": "^3.2.0",
"prompt-sync": "^4.2.0",
"sequelize": "^6.37.1",
"tedious": "^16.6.1",
"vite-plugin-commonjs": "^0.10.1",
"vite-plugin-commonjs-externals": "^0.1.4",
"vue": "^3.3.8",
"vue-router": "^4.2.5",
"vuetify": "^3.4.0"
},
"devDependencies": {
"@kingyue/rollup-plugin-modify": "^4.1.0",
"@originjs/vite-plugin-commonjs": "^1.0.3",
"@rushstack/eslint-patch": "^1.5.1",
"@types/jsdom": "^21.1.5",
"@types/node": "^20.10.6",
"@vitejs/plugin-vue": "^4.4.1",
"@vue/eslint-config-prettier": "^8.0.0",
"@vue/eslint-config-typescript": "^12.0.0",
"@vue/tsconfig": "^0.4.0",
"electron": "^27.0.4",
"electron-builder": "^24.6.4",
"eslint": "^8.53.0",
"eslint-plugin-vue": "^9.18.1",
"jsdom": "^22.1.0",
"pg-hstore": "^2.3.4",
"prettier": "^3.0.3",
"typescript": "^5.2.2",
"unplugin-auto-import": "^0.16.7",
"unplugin-vue-components": "^0.25.2",
"unplugin-vue-router": "^0.7.0",
"vite": "^4.5.0",
"vite-plugin-electron": "^0.15.4",
"vite-plugin-node-polyfills": "^0.19.0",
"vite-plugin-vue-devtools": "1.0.0-rc.5",
"vite-plugin-vue-meta-layouts": "^0.3.1",
"vite-plugin-vuetify": "^1.0.2",
"vue-tsc": "^1.8.22"
}
我尝试了多个 vite.config 选项,但没有任何效果。
最后我解决了这个问题。我添加到 vite.config.ts:
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
'moment': path.resolve(__dirname, './node_modules/moment/moment.js'),
"buffer": path.resolve(__dirname, './node_modules/buffer')
},
}