vue项目引入ts步骤(小结)


Posted in Javascript onOctober 31, 2019

最近考虑到老项目代码的可维护性以及稳定性,决定引入ts做规范检测。因为介绍的东西比较基础,如果介绍的不对,麻烦指正。

1. 简介

TypeScript 是 JavaScript 的一个超集,主要提供了类型系统和对 ES6 的支持。网上关于ts的学习资料很多,这里不做详细介绍。可参考的学习网站:

ts.xcatliu.com/

typescript.bootcss.com/

2. 安装依赖包

cnpm i typescript ts-loader --save-dev

3. 添加tsconfig.json文件

在项目根目录下添加 tsconfig.json 文件。tsconfig.json 文件用来指定ts的编译选项。配置可参考:

https://typescript.bootcss.com/tsconfig-json.html

项目工程 tsconfig.json 文件配置如下:(仅做参考)

{
  "compilerOptions": {
    "baseUrl": ".",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "noEmitOnError": true,
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "allowJs": true,
    "noEmit": false,
    "noImplicitThis": true,
    "esModuleInterop": true,
    "sourceMap": true,
    "moduleResolution": "node"
  },
  "include": [
    "src/**/*", "types"
  ],
  "exclude": [
    "node_modules",
    "build"
  ]
}

4. webpack打包配置修改

webpack.config.js 打包文件修改,新增对.ts文件的打包配置。

4.1 入口文件后缀名由.js修改为.ts

module.exports = {
  entry: {
    app: ['@babel/polyfill', './src/main.ts']
  }
}

4.2 extensions 文件扩展名增加 .ts, .tsx 文件的支持

tsx针对react项目文件的支持,因为我们的工程基于vue开发,支持.ts文件就可以了。

module.exports = {
  resolve: {
    extensions: ['.js', '.vue', '.json', '.css', '.ts']
  }
}

4.3 loader增加对ts文件的支持

使用ts-loader来转换ts文件。

module.exports = {
  module: {
    rules: [
      {
        test: /\.ts?$/,
        loader: 'ts-loader',
        exclude: /node_modules/,
        options: {
         appendTsSuffixTo: [/\.vue$/],
        }
      }
    ]
  }
}

5. eslint 添加对ts文件的检测

5.1 安装依赖包

cnpm i @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-typescript eslint-plugin-typescript --save-dev

@typescript-eslint/parser ts文件解析器

@typescript-eslint/eslint-plugin 版本号需要与@typescript-eslint/parser的版本一致,解析器相关的配置选项

eslint-config-typescript 针对ts项目配置的eslint检测规范

5.2 .eslintrc配置文件修改

.eslintrc配置文件修改,支持对ts的文件的校验。经过多次调整,我们工程的 .eslintrc 配置文件如下:

{
  "parserOptions": {
    "parser": "@typescript-eslint/parser",
    "project": "./tsconfig.json",
    "extraFileExtensions": [".vue"],
    "ecmaVersion": 2017,
    "sourceType": "module",
    "ecmaFeatures": {
      "modules": true
    }
  },
  "env": {
   "jest": true,
   "browser": true
  },
  "settings": {
   "import/resolver": {
    "node": {
     "extensions": [".js", ".jsx", ".ts", ".tsx", ".eslintrc"]
    },
    "webpack": {
     "config": {
      "resolve": {
       "alias": {
        "src": "src"
       }
      }
     }
    }
   }
  },
  "plugins": [
    "vue",
    "babel",
    "@typescript-eslint"
  ],
  "extends": [
    "eslint:recommended",
    "plugin:vue/base",
    "typescript",
    "standard"
  ],
  "rules": {
    "func-names": 0,
    "one-var": [1, "never"],
    "prefer-const": 1,
    "no-unused-expressions": 1,
    "new-cap": 2,
    "prefer-arrow-callback": 2,
    "arrow-body-style": 0,
    "max-len": [
      1,
      {
      "code": 200,
      "ignoreStrings": true,
      "ignoreUrls": true,
      "ignoreRegExpLiterals": true
      }
    ],
    "consistent-return": "off",
    "default-case": 2,
    "prefer-rest-params": 2,
    "no-script-url": 0,
    "no-console": [
      2,
      {
      "allow": ["info", "error", "warn", "log"]
      }
    ],
    "no-duplicate-imports": 2,
    "newline-per-chained-call": 2,
    "no-underscore-dangle": 2,
    "eol-last": 2,
    "no-useless-rename": 2,
    "class-methods-use-this": 0,
    "prefer-destructuring": 0,
    "no-unused-vars": 0,
    "@typescript-eslint/no-unused-vars": 1,
    "no-plusplus": 0,
    "import/prefer-default-export": 0,
    "import/no-dynamic-require": 2,
    "@typescript-eslint/no-var-requires": 2,
    "no-use-before-define": [
      "error",
      {
      "functions": false
      }
    ],
    "@typescript-eslint/no-use-before-define": 0,
    "@typescript-eslint/explicit-function-return-type": 0,
    "@typescript-eslint/interface-name-prefix": 0,
    "no-invalid-this": 0,
    "babel/no-invalid-this": 2,
    "no-await-in-loop": "off",
    "array-callback-return": "off",
    "no-restricted-syntax": "off",
    "@typescript-eslint/no-explicit-any": 0,
    "import/no-extraneous-dependencies": 0,
    "import/no-unresolved": 0,
    "@typescript-eslint/explicit-member-accessibility": 0,
    "@typescript-eslint/no-object-literal-type-assertion": 0,
    "no-param-reassign": [
      2,
      {
      "props": false
      }
    ],
    "generator-star-spacing": "off",
    "indent": [2, 4, {
      "SwitchCase": 1
    }],
    "eqeqeq": 0,
    "no-else-return": 2,
    "arrow-parens": 0,
    "space-before-function-paren": ["error", "never"],
    "comma-dangle": [2, "never"],
    "semi": [2, "always"]
  }
 }

注意"extends": ["plugin:vue/base"], 只能选择vue/base,不能用vue/recommend。不然会有规则冲突。

6. 项目文件转换

项目配置好后,开始对老代码进行改造,来支持ts的语法检测。

6.1 增加ts声明文件目录

项目中总会依赖一些资源包,或是自己开发的一些组件,这些文件需要补充声明文件,声明文件就是将多个声明语句放在一起,这些声明文件可统一放到一个目录里。这个目录需要包含在 tsconfig.json 文件的include里。

ms工程在根目录下新建 types 目录,目前包含 vue.d.ts, request.d.ts, dialog.d.ts, base.d.ts 等文件。

6.2 全局vue.d.ts声明文件

需要在ts环境下识别vue文件,需要添加 vue.d.ts 全局声明文件,例子如下:

import VueRouter, { Route } from 'vue-router';
import RequestAxios from './request';

declare module '*.vue' {
  import Vue from 'vue';
  export default Vue;
}
declare module 'vue/types/vue' {
  interface Vue {
    $router: VueRouter;
    $route: Route;
    $request: RequestAxios;
    ....
  }
}

6.2 vue文件的改造

vue文件的改造,只改造js部分,代码大致修改如下:

import { Vue, Component, Prop, Watch } from 'vue-property-decorator';

@Component({
  components: {
    ....
  }
})
export default class MyComponent extends Vue {
  // prop
  @Prop({ default: () => {} }) readonly pageInfo !: any

  // data
  private showAnimation : boolean = true;

  // watch
  @Watch('showModuleIndex')
  onShowModuleIndexChanged(newValue: any) {
    this.$emit('input', newValue);
  }

  // computed
  get list() {
    const { page, cityList } = this;
    return page.cityList.split(',').map(
      cityId => cityList.find(c => String(c.id) === cityId)
    );
  }

  // mounted
  private mounted() :void {
    this.initEditor();
  }

  // methods
  private initEditor() :void {
    ....
  }
}
</script>

6.3 js文件的改造

将文件后缀名更改为.ts,然后加上类型就可以了。

7. 踩坑总结

大部分都是eslint校验时的报错,按照提示修复就可以了。

"vue/html-indent": [2, 4] eslint这条规则去掉

"plugin:vue/base"与"plugin:vue/recommend"的区别

...

8. 总结

项目改造过程中,大部分时间都是在查配置兼容问题,配置这块解决了,改造起来速度还是挺快的。虽然前期会有一些改造成本,但是长远来看,还是有意义的。毕竟很多代码类型上的问题在开发阶段就可以暴露,不用等到运行时才发现了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery的强大选择器小结
Dec 27 Javascript
javascript基础第一章 JavaScript与用户端
Jul 22 Javascript
Javascript面向对象扩展库代码分享
Mar 27 Javascript
js转义字符介绍
Nov 05 Javascript
js 通过cookie实现刷新不变化树形菜单
Oct 30 Javascript
js实现简单的联动菜单效果
Aug 19 Javascript
微信小程序 生命周期函数详解
May 24 Javascript
小程序开发基础之view视图容器
Aug 21 Javascript
深入浅析vue-cli@3.0 使用及配置说明
May 08 Javascript
layui点击左侧导航栏,实现不刷新整个页面,只刷新局部的方法
Sep 25 Javascript
在Vue mounted方法中使用data变量详解
Nov 05 Javascript
js验证密码强度解析
Mar 18 Javascript
微信小程序canvas分享海报功能
Oct 31 #Javascript
解决vue初始化项目时,一直卡在Project description上的问题
Oct 31 #Javascript
vue项目初始化到登录login页面的示例
Oct 31 #Javascript
vue3 源码解读之 time slicing的使用方法
Oct 31 #Javascript
vue data恢复初始化数据的实现方法
Oct 31 #Javascript
vue和iview实现Scroll 数据无限滚动功能
Oct 31 #Javascript
vue 使用鼠标滚动加载数据的例子
Oct 31 #Javascript
You might like
CodeIgniter连贯操作的底层原理分析
2016/05/17 PHP
php封装的表单验证类完整实例
2016/10/19 PHP
谈谈从phpinfo中能获取哪些值得注意的信息
2017/03/28 PHP
Laravel5.* 打印出执行的sql语句的方法
2017/07/24 PHP
PHP微信企业号开发之回调模式开启与用法示例
2017/11/25 PHP
jQuery结合Json提交数据到Webservice,并接收从Webservice返回的Json数据
2011/02/18 Javascript
js图片延迟技术一般的思路与示例
2014/03/20 Javascript
seaJs的模块定义和模块加载浅析
2014/06/06 Javascript
javascript引擎长时间独占线程造成卡顿的解决方案
2014/12/03 Javascript
jquery插件validation实现验证身份证号等
2015/06/04 Javascript
jQuery实现仿百度帖吧头部固定导航效果
2015/08/07 Javascript
配置Grunt的Task时通配符支持和动态生成文件名问题
2015/09/06 Javascript
JavaScript中利用各种循环进行遍历的方式总结
2015/11/10 Javascript
JQuery.Ajax()的data参数类型实例详解
2015/11/20 Javascript
jquery插入兄弟节点的操作方法
2016/12/07 Javascript
mac上node.js环境的安装测试
2017/07/03 Javascript
DataTables添加额外的查询参数和删除columns等无用参数实例
2017/07/04 Javascript
vue.js项目打包上线的图文教程
2017/11/16 Javascript
JavaScript继承定义与用法实践分析
2018/05/28 Javascript
[02:22]2018DOTA2亚洲邀请赛VG赛前采访
2018/04/03 DOTA
Python素数检测实例分析
2015/06/15 Python
简单实现python进度条脚本
2017/12/18 Python
Python使用遗传算法解决最大流问题
2018/01/29 Python
python中subprocess批量执行linux命令
2018/04/27 Python
Python查找第n个子串的技巧分享
2018/06/27 Python
Django实现web端tailf日志文件功能及实例详解
2019/07/28 Python
matplotlib 三维图表绘制方法简介
2020/09/20 Python
python基于win32api实现键盘输入
2020/12/09 Python
梵蒂冈和罗马卡:Omnia Card Pass
2018/02/10 全球购物
美国农场商店:Blain’s Farm & Fleet
2020/01/17 全球购物
航空大学应届生求职信
2013/11/10 职场文书
学校创先争优活动总结
2014/08/28 职场文书
成绩报告单家长评语
2014/12/30 职场文书
幼儿园元旦主持词
2015/07/06 职场文书
祝福语集锦:给妹妹结婚的祝福语
2019/12/18 职场文书
CSS 新特性 contain控制页面的重绘与重排问题
2021/04/30 HTML / CSS