本来是想放弃的,后来歪打正着,成功运行。最后搞一个ts类型的启动器,不想再懵了。

vue-ts-electron-starter

想看看原项目electron-vue有没有这个打算,没有的话自己fork个分支出来。这个将就。

这次搞这个项目目的就很明显了,想做一个Hexo博客的编辑器(没错就是我这个博客的核心)。Hexo的话,属于页面生成器类的博客系统。直接一套生成静态页面,然后随意访问。因为一整套静态页面故还是有人喜欢直接干一套SPA上去,体验也好。

其实搞这个,我去年就想搞了。可是去年的话,明显前端的技术都不扎实更别说搞了,当时的想法是写一个Mac App(我swift应该还行,随便写写问题不大。不过可能现在的话问题就大了)。不过就一直拖拖拖,导致swift3.0都有苗头了我还是没想写。而且关于如何操作terminal命令,还是个问题。

这次心就大了。搞了再说,搞一半不行了就让他荒了。以后想起来再搞,再搞的时候技术肯定又上涨。如果这波做成了,开源,我不管有没有人用,总有人喜欢用。

讲在前面

在这之前我用的是CodeFalling / blog-admin。这是一个Emacs的插件,当然spacemacs也能弄来用一下。这是一个在github很活跃的大神写的(我经常看到,同时也是hexojs成员),也是很出名的Emacs教徒。不过据说他现在用的是webstorm + vim插件了…

当然今天不想吹Emacs,而且工作上我也不敢用Emacs,原因不说。

其实就是一直想做一个方便用一点的。在emacs之前我都是开一个terminal+一个编辑器来做的。在emacs之前是用typoravscode做的。总这样不好吧太麻烦了。而且这东西又算刚需…所以算了,还是尝试一下吧,顺便把electronvuex给学清楚了,而且顺便练一下TypeScript

所以这次打算的技术选型是:

  • TypeScript
  • electron
  • vue
  • vuex

electron + vue环境的话,直接使用SimulatedGREG/electron-vue,这样electronvuewebpack就都完成了。如果针对TypeScript的话webpack应该要小改一下。

为什么使用TypeScript

TypeScript是微软开发的语言,由于师出同门所以跟C#的语法是极其像的,不过由于是JavaScript的超类,所以还会考虑到ES的语法。所以很早的时候ES6还没流行起来的时候,TypeScript已经开始使用像ES6一样的语法,并提供编译把TS的代码编译成ES5的代码,在没有es6babel的世界,需要用JS来创造更强大的程序无疑是福音。

一开始看到的时候,我觉得JS也就那样了,还能怎样…到后来去接触的原因,是因为它的语法跟我先接触的swift很像,我觉得可能能通过TS学好swift或者说通过对swift的理解去学TS,反正都能编译成JS的嘛。

再后来就遇到了游戏,接触Unity3D的时候,最热门最成熟的语言是C#,而我当时是个软黑。转而让我发现了Egret,Egret竟然把TS作为开发语言,我就想要不把TS也弄清楚了,以后如果接触C#可能也不会太难。可是经过几轮跌爬滚打之后,我竟然放弃了…对这就是我小时候的不懂事…大学快毕业的时候几乎每天就在后悔,为什么当时不好好学TS,而在ES6789流行开的时代里,语法完整功能完善的TS优势也没有那么大了。现在浏览器都能直接用ES7了…

但是现在说没优势都是骗人的…如果你只是单纯用JS写的话,一如果出现类型错误,不好控制。二在万物都是函数的世界中,可能如果要实现一些其他功能,可能会考虑不周。即使能考虑到了,写上去。也会造成很大的工作量。但是TS编译器都替我们想好和做好了,为什么不去用?

所以,如果是应用开发的话,为什么不考虑应用级别的开发语言呢?我是这么想的。

如果是web,但是要强大的框架比如vue,reactjs,我会选择用JS。如果是需要更强大的能力和稳定、可控的app,我肯定是选择TS。

干!填坑!

两点核心

  • webpack需要配置对TypeScript的编译。
  • 从入口到组件都使用TypeScript

因为我也是误打误撞突然可以正常运行,所以我是开一个新的项目进行接下来的工作。 (结果发现并不是误打误撞,而是本来就是正确的,那么为什么会错误…)

首先npm安装typescript, ts-loader, vue-class-component,这三个都很重要。typescript提供的是语言支持,也可以说是提供内部编译,当然如果说你本身就全局装过了,那么你直接link就行了

1
2
3
4
5
npm i -S typescript ts-loader vue-class-component

# or
npm i -S ts-loader vue-class-component
npm link typescript

然后是webpack.renderer.config.js,不出意外的话在25:3入口,26:58js改成ts,下面的rule添加对ts的支持

1
2
3
4
5
6
7
8
{
test: /\.ts$/,
loader: 'ts-loader',
exclude: /node_modules|vue\/src/,
options: {
appendTsSuffixTo: [/\.vue$/]
}
}

如果有需要tslint的话(说实话我还不会用…而且我觉得ts约束本来就很厉害了),需要安装

1
npm i -S tslint tslint-loader

老位置

1
2
3
4
5
6
7
8
{
test: /\.(ts)$/,
enforce: 'pre',
exclude: /node_modules/,
use: {
loader: 'tslint-loader'
}
}

第二,就是把关于vue部分的入口改成main.ts。这样接近完成。

第三,最重要的,typescript能不能用就靠这个了,jsconfig.json

1
tsc --init	#通过tsc初始化得到

至于怎么配置,vue官方也给了一个推荐配置,vue-class-component也给了一个。

但不管怎样,建议把allowjs打开了,可以调用js文件。

开始填坑

  • 入口必须是.ts

这点说起来很坑,TS的话,只要有allowjs就可以调用JS文件,运行是没问题的。但是反过来就不行了,毕竟超类能认,但JS根本不知道TS是个什么鬼,所以无法编译

1
2
3
4
Module build failed: Error: Could not find file: '...*.ts'

# 或者
Module build failed: Error: Could not find file: '...*.vue'

所以必须是TS入口

  • 建议关于script部分分开写。

当然是可以直接在.vue写你的逻辑的,不过为了防止typescript有小脾气,或者关于类型推断,总的来说就是为了编译少点麻烦吧,我觉得还是分开写是最保险的。当然在组件内写也不是不可以。

  • vue-class-component核心

如果用了TS的话,那么漂亮的组件代码肯定就是class了,通过修饰@component声明该位置是一个组件,然后开始写组件代码,继承自vue,然后就可以像写一个程序类一样去写这部分组件。看起来是相当漂亮的。举个例子,在通过electron-vue创建出来的工程中,对实例组件LandingPage.vue进行改写

1
2
3
4
5
6
7
8
9
10
11
@Component({
name: 'landing-page',
components: {
SystemInformation
}
})
export default class LandingPage extends Vue {
open (link) {
(this as any).$electron.shell.openExternal(link)
}
}

漂亮,清晰。(当然复杂一点,就复杂了!)

  • 关于对Vue进行扩展

在添加axios的时候我遇到了问题:无法扩展Vue,原因好像是无法推断vue 的类型。这个问题的话,我还得去研究一下。