vue cli 3 项目与 electron 记录

本贴最后更新于 1899 天前,其中的信息可能已经时过境迁

最近在重构我们上学期参加比赛做的一个小软件,help teacher 主要是作业收取的一款小工具,局域网内进行作业传输,简单用 vert.x 做了一个登录注册以及数据备份与同步。为了参加比赛写的小软件,时间紧迫代码质量普遍不高,并且使用 electron-vue 进行搭建,也发现了不少问题,而那时候第一次接触 vue,也不理解其组件化思想,也不会组件抽离什么的,然后这次放假了,有老师对我们项目感兴趣,我们开始重构我们的软件,不再使用 electron-vue ,一方面因为 vue cli 3 生成的项目结构十分让我喜欢,约定大于配置也类似于 spring boot 的思想,所以我不需要太多的配置文件,一个就够,这是我非常喜欢的,但是目前 electron-vue 还不支持,而且 vue cli 3 拥有自己的图形化界面,可以更加方便的管理项目依赖以及插件;另一方面,我们以前的项目使用的 vue + element ui 进行开发,也发现很多 element 的组件在 electron-vue 中有着 bug 的存在,比如很简单的一个 MessageBox 弹框,使用的时候都会报错,然后造成整个软件其它部分的瘫痪,所以后面我们急冲冲的引入了其他的弹框组件。这次重构是对上次的一个功能上的完善,也是一个性能的优化。不过自己虽然是一个后端,自己来做前端的时候也发现一些异曲同工之处,而且因为以前使用 vert.x ,在接触 node 以后发现了很多地方的相似之处。今天这篇文章,主要是记录一下这个项目开始的重构过程,所以不会是一种教程似的画风,大多都是一些问题上的处理方法进行记录。不得不说的是,作为一个非专业的前端人员,在没有学过 webpack 、es6 语法、babel 等等一些前端方面的知识就直接上手开发,还是遇到很多问题的。

项目地址:teacher-tools

一些说明

  • 为了统一代码风格,使用 eslint,并且统一使用 vscode 进行开发
  • element 换为 iview, 同时为了方便修改 iview 主题,使用 less 替换原来的 stylus
  • 从 npm 改为使用 yarn
  • 前端数据库依旧使用 nedb(暂定)
  • 为了实时聊天,学习 socketio(暂定)

问题一: 项目整合

我们在使用 vue cli 3 初始化项目后,他是一个纯正的 web 项目,我们需要对他进行 electron 进行整合,我们寻找了很久方案,最后终于找到一款插件进行整合 —— vue-cli-plugin-electron-builder , 安装很方便,直接图形化界面搜索安装即可

搜索安装

或者命令行模式安装

vue add electron-builder

然后通过

yarn electron:serve

yarn electron:build

进行使用。不过使用新的东西随之而来的问题就是,遇到什么问题或者其它需求的时候,只能自己摸索,而且没啥基础很难受。

1. 默认入口

我们移动了插件生成的文件路径以及修改了文件名,那么如何保证他能够正确的使用并进入呢?我们卡在这问题很久,最后在 github 的 issue 上面找到答案,于是修改 vue.config.js 如下:

pluginOptions: {
  electronBuilder: {
	builderOptions: {
	  files: [
		{
		  'filter': ['**/*']
		}
	  ],
	  extraFiles: ['./extensions/'],
	  asar:  false
	},
	mainProcessFile:  'src/main/main.js',
	mainProcessWatch: ['src/main'],
	// [1.0.0-rc.4+] Provide a list of arguments that Electron will be launched with during "electron:serve",
	// which can be accessed from the main process (src/background.js).
	// Note that it is ignored when --debug flag is used with "electron:serve", as you must launch Electron yourself
	mainProcessArgs: []
  }
},

2. 打包目录

与以往不同的是,我们有多个页面,除了 electron 的,也有 web 的,需要更具不同的进行打包,所以我们查找资料,修改 pages 参数如下:

...
pages:  getPages(),
...
/**
* 根据 MODE 选择对应的 pages 进行打包
*/
function  getPages () {
  return  process.env.MODE  ===  'web'
  ? {
	client: {
	  // entry for the page
	  entry:  'src/client/main.js',
	  // the source template
	  template:  'public/index.html',
	  // output as dist/index.html
	  filename:  'index.html'
	}
  }
  : {
	app: {
	  entry:  'src/app/main.js',
	  template:  'public/index.html',
	  filename:  'app.html'
	},
	communication: {
	  entry:  'src/communication/main.js',
	  template:  'public/index.html',
	  filename:  'communication.html'
	},
	forms: {
	  entry:  'src/forms/main.js',
	  template:  'public/index.html',
	  filename:  'forms.html'
	}
  }
}

3. 全局引入

参照了官网的例子

...
chainWebpack:  config  => {
  config.resolve.alias
  .set('app@', resolve('src/app'))
  .set('_n', resolve('node_modules'))
  .set('common@', resolve('src/common/'))
  .set('communication@', resolve('src/communication/'))
  .set('form@', resolve('src/form/'))
  .set('client@', resolve('src/client/'))
  const  types  = ['vue-modules', 'vue', 'normal-modules', 'normal']
  types.forEach(type  =>  addStyleResource(config.module.rule('less').oneOf(type)))
}
...

/**
* 全局 less 引入
* @param  {*}  rule 传递规则
*/
function  addStyleResource (rule) {
  rule.use('style-resource')
	.loader('style-resources-loader')
	.options({
	  patterns: [
		path.resolve(__dirname, './src/common/theme/iview-variables.less')
	  ]
	})
}

不过对于 stylus 还有另外一种方式,不知道为啥 less 不行

css: {
  loaderOptions: {
	stylus: {
	  import: path.resolve(__dirname, './src/styles/global.styl')
	}
  }
}

问题二:vue

1. 滚动条问题

由于我们自定义了标题,没有使用默认的标题栏,然后就会有一种情况,他的滚动条会在标题右侧了

滚动条

通过 css 修改如下:

@gak-no-visible: rgba(0, 0, 0, 0);
html, body {
  overflow: hidden;
  height: 100%;
}
.gak-bg-no-visible {
  background-color: @gak-no-visible;
}
.gak-scroll {
  height: 100%;
  -webkit-overflow-scrolling: touch;
  overflow-y: auto;
  /*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
  &::-webkit-scrollbar {
	width: 8px;
	height: 4px;
	cursor: pointer;
	.gak-bg-no-visible;
  }
  /*定义滚动条轨道 内阴影+圆角*/
  &::-webkit-scrollbar-track {
	border: none;
	.gak-bg-no-visible;
  }
  /*定义滑块 内阴影+圆角*/
  &::-webkit-scrollbar-thumb{
	border-radius: 10px;
	background-color: rgba(110, 110, 110, 0.2);
  }
}

修改后如图

滚动条

2. soketio

找了很多组件,原本一开始使用的是 Vue-Socket.io,但是发现对于 vuex 他似乎已经不再支持,所以找了半天,改成使用了 vue-socket.io-extended,目前用起来十分方便。

使用方式采用外部文件扩展的方式,能够在 action 里面调用是及其方便的。

3. 打包问题

因为我们包含的 vue 页面比较多,并且有一个不是 electron 项目而是 web 项目,需要指定不同的打包路径,最后查阅资料,使用官方文档中的方法如下:

"scripts": {
  "lint": "vue-cli-service lint",
  "electron:build": "vue-cli-service electron:build",
  "electron:serve": "vue-cli-service electron:serve",
  "postinstall": "electron-builder install-app-deps",
  "test:unit": "vue-cli-service test:unit",
  "web:serve": "cross-env MODE=web vue-cli-service serve",
  "web:build": "cross-env MODE=web vue-cli-service build --dest ./extensions/dist"
},

为什么不用 -mode 模式 而是使用 cross-env MODE=web ?因为我们这里 -mode 读取不到,可能使用方式不对,所以采用以前的老办法了。

待解决的问题

  • 作业收取屏幕分享,如果单用 node 的话是完成不了的(或者我们不会),希望用 c++ 来完成,由我队友负责
  • 内存问题,上一次项目出现了一个典型情况就是内存占用比预期中的高,并且出现卡顿情况
  • 多页面情况 vuex 状态不共享
  • 开发时加载出现 首屏白屏情况,打包后不明显
  • vue devtools 不管用,多次尝试各种组件都上了还是不行(要不就是临时的),最后使用本地的,但是只有第一次运行有效,后面都是无效
  • ...很多杂七杂八的小问题

imagepng

C++ 很强

小总结

其实是非常喜欢 electron 这种的,因为他的跨平台真的太棒,我队友操作系统是 主 windows + mint(移动硬盘),我的是 主 deepin + windows(移动硬盘),正是这种跨平台性能够让我们在不同平台下进行协作开发、然后重构的时候也对目录进行修改,也更好的进行组织以及抽取多页面的公共部分,不过自己其实还是喜欢后端哈哈哈哈,自己来做前端也是因为我们学校这一届实在找不到人一起来做了,只有我们两个人,做起来时间上很是费力,然后又要学车,大多是队友一直在弄,做了很多东西,自己就晚上弄弄页面,希望开学能够看得到成果吧。

  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    261 引用 • 662 回帖 • 1 关注
  • Electron

    Electron 基于 Chromium 和 Node.js,让你可以使用 HTML、CSS 和 JavaScript 构建应用。它是一个由 GitHub 及众多贡献者组成的活跃社区共同维护的开源项目,兼容 Mac、Windows 和 Linux,它构建的应用可在这三个操作系统上面运行。

    15 引用 • 136 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...