花了4天时间把之前mohe平台用thinkjs2升级了下,3天改代码,1天部署。在thinkjs2.X版本中还是遇到了些大大小小的问题,这里记录下。

controller

  1. 凡是需要init的地方,都得用super.init()

    1
    2
    3
    4
    5
    6
    7
    8
    init (...arg) {
    super.init(...arg);
    }
    一般情况下,只需传参http:
    init (http) {
    super.init(http);
    this.__model = this;
    }
  2. 2.0 里推荐的文件名都小写,有大写的话会看到一个warning的。
    比如componentController中有个action名以前是componentSubmitAction,在view中我们会这样写请求,/component/componentSubmit,在1.x版本是没有问题的;
    但是在2.x版本中thinkjs会强制将请求的url都转成小写的,所以最终发送的请求就变成了/component/componentsubmit,这样就会出现找不到action的情况。
    虽然在2.0.6版本后,thinkjs支持URL 解析后的 Action 支持含有 - 字符,但是component-submitAction这样命名还是感觉怪怪的。

  3. 用await代替了promise后,之前用then.then.catch的流程可以改为

    1
    2
    3
    4
    5
    6
    try{
    //这里就是各种操作
    }catch(err){
    console.log(err);
    return this.fail('保存组件失败');
    }
  4. controller中还是可以用promise,也不是全都非得改成await的形式,还是得看具体流程。
    比如有个操作需要,先检查文件后缀名->文件重命名->上传文件->检测代码->返回成功结果。这样一个流程,就很适合用then连接起来。
    但是,需要注意的是如果需要流程进行下去,需要返回一个普通的json或变量,而不是this.success(),否则流程会被中断,直接将success返回给view了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    this.checkFile( file, fileType )
    .then(reg =>{
    console.log('--------renameFile-----');
    // 重命名文件
    return this.renameFile( reg, file );
    }).then(passedFile=>{
    console.log('--------uploadFile-----');
    // uploadFile函数里已返回this.success
    return this.uploadFile( this.UPLOAD_FILE_PATH, passedFile );
    }).then(res=>{
    console.log('----chheckCode outter---');
    // 检查代码内容
    if( fileType == 'code' ){
    console.log('----chheckCode inner---');
    return this.checkCode( this.UPLOAD_FILE_PATH, res );
    }
    return res;
    }).then(res=>{
    console.log('--------return data-----');
    this.success(res,'success');
    }).catch(err=>{
    console.log( `fileupload is err =======:${err}` );
    this.fail( 100, err, {fileName: file.originalFilename} );
    });
  5. 在promise中要像以前一样用到this,需要写在箭头函数中。
    this 作用域的问题

model

  1. 最好跟数据表名一致,不然就要在模型里配置
    (成银:如果表名中带下划线,那么实例化的地方也要改成下划线,因为实例化的时候会试图去寻找模型文件,如果找不到的话会实例化默认的模型,就不能用模型中自定义的方法了。)
    比如:有一张表component_version,那么相应的模型命名为,component_version.js,在要用到这个模型时,这样实例化this.model('component_version'),这样就可以用里面的方法了,以及select,where等等这样自带的原子方法。

    自己之前因为弄不清楚实例化模型的原理,各种尝试,还用过import模型,再new的方法,其实thinkjs中提供的this.model()方法就已经是实例化的方法,不用再new了

  2. 如果在模型中的init()方法出错了,会出现access deny,就是连不上数据库的错误。

  3. 有表别名时,countSelect()会报错。(以反馈,还未修好)
    之前在用2.0.6版本时,还遇到了当page取默认值时,limit是从1开始而不是从0开始,后来的版本修好了。(使用最新版本的代码是多么的重要啊)

其他配置

  1. 需要用到自己添加的配置文件
    比如有个文件/src/common/src/github_opts.js,需要用到其中的数据,就可以这样引入think.config('github_opts')

  2. 定义全局变量

    相应的productionjs也需要修改

代码运行模式切换

  1. 使用npm start 默认是development环境,因为start读的是package.json文件

  2. 如果需要运行在production环境,npm start production

调试

  1. 大部分时候自己是通过console.log()来进行调试,心累手累。
    如果是–es6的形式来创建的项目,最终控制台报错的行号,是在编译后的app目录文件里的。

  2. ThinkJS 项目用 WebStorm 来设置断点与调试

部署

  1. 在windows下运行的好好的代码,放到linux下,模型方法会报错,怀疑是自己代码写法有问题,babel在两种环境下的编译也会略有差异。

  2. 使用pm2 启动时,配置了www/production.js为入口文件,但是每次启动还是在寻找www/index.js
    最后是建了个软链ln -s production.js index.js

  3. 出现文件路径过长,不能成功clone的问题,主要是bable依赖
    在线上机器和本地开发机,分别先npm install;
    因为这个项目中,用到一些不能直接install的依赖,就先将本地的node_moudles/xx依赖提前push到仓库中。

  4. 删除git仓库中的文件

1
2
3
4
5
6
git rm -rf 文件夹名/
git commit -m "remove 文件夹名"
git push
// 有时,还需要物理删除文件夹
rm -rf 文件夹名/

写在最后

  1. 升级是个体力活,但是如果不追求用es6/7,只是替换一些函数用法,其实也就controller需要改的多一些。
  2. es7的await,async很好用,逻辑看起来清晰很多了。
  3. 字符串模板很好用,再也可以不用+连接了,尤其是里面有引号的时候,根本写不清楚。
  4. object.assign()也好用。
  5. 箭头函数也好用,函数简洁。
  6. let在循环中帮助很大,再也不用担心闭包中写for循环的变量引用问题了。