JavaScript

超轻量级php框架startmvc

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

更新时间:2020-09-20 04:48:01 作者:startmvc
最近考虑到老项目代码的可维护性以及稳定性,决定引入ts做规范检测。因为介绍的东西比

最近考虑到老项目代码的可维护性以及稳定性,决定引入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. 总结

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

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

vue项目引入ts vue引入ts