Vue Cli 3.0 建立TypeScript專案

Hwg發表於2019-07-08

一、Vue CLI安裝

使用的是vue cli 3.0版本

npm install -g @vue/cli
複製程式碼

檢測是否安裝

vue --version
複製程式碼

安裝全域性擴充套件

npm install -g @vue/cli-service-global

複製程式碼

執行單個.vue檔案

vue serve Hello.vue
複製程式碼

二、建立專案

  1. 建立一個專案
vue create hello-world
複製程式碼
  1. 安裝router、vuex
vue add router
vue add vuex
複製程式碼
  1. 安裝eslint
vue add @vue/eslint
複製程式碼

eslint相關文件:eslint.cn/docs/user-g… 4. 安裝typescript

vue add @vue/typescript
複製程式碼

三、Vue.config.js配置說明

const path = require('path');

function resolve(dir) {
    return path.join(__dirname, dir)
}

module.exports = {

    // 把開發伺服器假設在根路徑
    publicPath: process.env.NODE_ENV === 'production' ? './' : '/',

    // 生成檔案的目錄名稱
    outputDir: "dist",

    //用於放置生成的靜態資源 (js、css、img、fonts) 的;(專案打包之後,靜態資源會放在這個資料夾下)
    assetsDir: "static",

    // 預設情況下,生成的靜態資源在它們的檔名中包含了 hash 以便更好的控制快取。
    filenameHashing: true,

    // 不需要生產環境的 source map,可以將其設定為 false 以加速生產環境構建,map就是為了方便列印錯誤位置。
    productionSourceMap: false,

    // 設定單頁面與多頁面
    // 多頁面情況下,每個“page”應該有一個對應的 JavaScript 入口檔案。其值應該是一個物件,物件的 key 是入口的名字,value 是:
    // 一個指定了 entry, template, filename, title 和 chunks 的物件 (除了 entry 之外都是可選的);
    // 或一個指定其 entry 的字串。
    // 具體情況看官網 https://cli.vuejs.org/zh/config/#pages
    // pages: {
    //     index: {
    //         // page 的入口
    //         entry: 'src/main.ts',
    //         // 模板來源
    //         template: 'public/index.html',
    //         // 在 dist/index.html 的輸出
    //         filename: 'index.html',
    //         title: 'Vui庫',
    //         // 提取出來的通用 chunk 和 vendor chunk。
    //         chunks: ['chunk-vendors', 'chunk-common', 'index']
    //     }
    // },

    //預設情況下,只有以檔案結尾的檔案*.module.[ext]才會被視為CSS模組。將此設定為true允許您.module放入檔名並將所有*.(css|scss|sass|less|styl(us)?)檔案視為CSS模組。
    //extract true在生產中,false在開發中,是否將元件中的CSS提取到獨立的CSS檔案中(而不是在JavaScript中內聯並動態注入,在開發模式下禁用提取CSS,因為它與CSS熱重新載入不相容
    //sourceMap是否為CSS啟用源對映。將此設定為true可能會影響構建效能
    //將選項傳遞給與CSS相關的載入器
    css: {
        modules: false,
        //extract: true, //設為true的話熱更新會出問題
        sourceMap: false,
        loaderOptions: {
            css: {
                // options here will be passed to css-loader
            },
            postcss: {
                // options here will be passed to postcss-loader
            }
        }
    },

    // 是否使用包含執行時編譯器的 Vue 構建版本。設定為 true 後你就可以在 Vue 元件中使用 template 選項了,但是這會讓你的應用額外增加 10kb 左右。
    // 具體資訊看官網 https://cn.vuejs.org/v2/guide/installation.html#執行時+編譯器vs.只包含執行時
    runtimeCompiler: false,

    // 開啟eslint
    // 設定為 true 時,eslint-loader 會將 lint 錯誤輸出為編譯警告。預設情況下,警告僅僅會被輸出到命令列,且不會使得編譯失敗。
    // 設定為 error 時,這會強制 eslint-loader 將 lint 錯誤輸出為編譯錯誤,同時也意味著 lint 錯誤將會導致編譯失敗。
    lintOnSave: 'error',

    devServer: {
    	// 與devServer.quiet啟用,那麼除了該初始啟動資訊將被寫入到控制檯。這也意味著webpack中的錯誤或警告不可見。
        // quiet: true,
        
        // 通過設定讓瀏覽器 overlay 同時顯示警告和錯誤 在 devServe 配置項中  ==>
        overlay: {
            warnings: true,
            errors: true
        }
    },

    configureWebpack: {
        name: '基於Vue的前端ui庫',
        resolve: {
            extensions: ['.js', '.ts', '.tsx', '.json'],
            alias: {
                '@': resolve('src')
            }
        }
    },

    chainWebpack: config => {

        // set svg-sprite-loader
        config.module
            .rule('svg')
            .exclude.add(resolve('src/icons'))
            .end();

        config.module
            .rule('icons')
            .test(/\.svg$/)
            .include.add(resolve('src/icons'))
            .end()
            .use('svg-sprite-loader')
            .loader('svg-sprite-loader')
            .options({
                symbolId: 'icon-[name]'
            })
            .end();

        // set preserveWhitespace
        config.module
            .rule('vue')
            .use('vue-loader')
            .loader('vue-loader')
            .tap(options => {
                options.compilerOptions.preserveWhitespace = true
                return options
            })
            .end();

        config
        
        	// https://webpack.js.org/configuration/devtool/#development
            .when(process.env.NODE_ENV === 'development',
                config => config.devtool('cheap-source-map')
            );

        config
            .when(process.env.NODE_ENV !== 'development',
                config => {
                    config
                        .plugin('ScriptExtHtmlWebpackPlugin')
                        .after('html')
                        .use('script-ext-html-webpack-plugin', [{
                            // `runtime` must same as runtimeChunk name. default is `runtime`
                            inline: /runtime\..*\.js$/
                        }])
                        .end();
                    config
                        .optimization.splitChunks({
                        chunks: 'all',
                        cacheGroups: {
                            libs: {
                                name: 'chunk-libs',
                                test: /[\\/]node_modules[\\/]/,
                                priority: 10,
                                chunks: 'initial' // only package third parties that are initially dependent
                            },
                            commons: {
                                name: 'chunk-commons',
                                test: resolve('src/components'), // can customize your rules
                                minChunks: 3, //  minimum common number
                                priority: 5,
                                reuseExistingChunk: true
                            }
                        }
                    });
                    config.optimization.runtimeChunk('single')
                }
            );

        //在單獨的程式中,執行打字型別檢查器的webpack外掛
        config.plugin('fork-ts-checker').tap(([options]) => {
            return [{
                //以下幾項都是推薦配置,async false使其可以在頁面上顯示
                async: false,
                tslint: true,
                vue: true
            }]
        })
    }
};

複製程式碼

更多配置請檢視:cli.vuejs.org/zh/config/#…

四、TSlint配置

  1. 安裝tslint
<!--全域性-->
npm install -g tslint

<!--當前專案-->
npm install -D tslint
複製程式碼

初始化或自己建立tslint.json檔案:

tslint --init
複製程式碼

根據自己需要配置:

{
  "defaultSeverity": "warning",
  // 推薦的規則
  "extends": [
    "tslint:recommended"
  ],
  "linterOptions": {
    "exclude": [
      "node_modules/**"
    ]
  },
  "rules": {
    "prefer-const" : false,

    "interface-name" : [true, "never-prefix"],
    //禁用 console
    "no-console": [false, "log", "error"],

    //設定成員物件的訪問許可權(public,private,protect)
    "member-access": false,
    // 禁止自動檢測末尾行必須使用逗號,always總是檢測,never從不檢測,ignore忽略檢測
    "trailing-comma": [
      true,
      {
        "singleline": "never",
        "multiline": {
          "objects": "ignore",
          "arrays": "ignore",
          "functions": "never",
          "typeLiterals": "ignore"
        }
      }
    ],
    //檢查物件文字中鍵的排序。
    //使用預設的字母順序時,可以使用其他空行將物件屬性組合在一起,同時按字母順序保持每個組中的元素。
    "object-literal-sort-keys": false,
    // 禁止給類的建構函式的引數新增修飾符
    "no-parameter-properties": false,
    // 禁止使用 debugger
    "no-debugger": false,
    // 禁止行尾有空格
    "no-trailing-whitespace": false,
    // 禁止無用的表示式
    "no-unused-expression": true,
    // 定義過的變數必須使用
    "no-unused-variable": false,
    // 變數必須先定義後使用
    "no-use-before-declare": true,
    // 禁止使用 var
    "no-var-keyword": true,
    // 必須使用 === 或 !==,禁止使用 == 或 !=,與 null 比較時除外
    "triple-equals": true,
    // 指定類成員的排序規則
    "member-ordering": false,
    // 禁止將 this 賦值給其他變數,除非是解構賦值
    "no-this-assignment": [
      false,
      {
        "allowed-names": [
          "^self$",
          "^that$"
        ],
        "allow-destructuring": true
      }
    ],
    // 必須使用箭頭函式,除非是單獨的函式宣告或是命名函式
    "only-arrow-functions": [
      true,
      "allow-declarations",
      "allow-named-functions"
    ],
    // 禁止出現空程式碼塊,允許 catch 是空程式碼塊
    "no-empty": [
      true,
      "allow-empty-catch"
    ],
    // 禁止無用的型別斷言
    "no-unnecessary-type-assertion": true,
    // 使用 return; 而不是 return undefined;
    "return-undefined": true,
    // 禁止對 array 使用 for in 迴圈
    "no-for-in-array": true,
    "comment-format": [
      true,
      "check-space"
    ],
    // 單行註釋格式化規則
    // 定義函式時如果用到了覆寫,則必須將覆寫的函式寫到一起
    "adjacent-overload-signatures": true,
    // 禁止對函式的引數重新賦值
    "no-parameter-reassignment": true,
    // if 後面必須有 {,除非是單行 if
    "curly": [
      true,
      "ignore-same-line"
    ],
    // for in 內部必須有 hasOwnProperty
    "forin": true,
    // 禁止在分支條件判斷中有賦值操作
    "no-conditional-assignment": true,
    // 禁止使用 new 來生成 String, Number 或 Boolean
    "no-construct": true,
    // 禁止 super 在一個建構函式中出現兩次
    "no-duplicate-super": true,
    // 禁止在 switch 語句中出現重複測試表示式的 case
    "no-duplicate-switch-case": true,
    // 禁止出現重複的變數定義或函式引數名
    "no-duplicate-variable": [
      true,
      "check-parameters"
    ],
    // 禁止使用 eval
    "no-eval": true,
    // 禁止對物件字面量進行型別斷言(斷言成 any 是允許的)
    "no-object-literal-type-assertion": true,
    // 禁止沒必要的 return await
    "no-return-await": true,
    // 禁止在陣列中出現連續的逗號,如 let foo = [,,]
    "no-sparse-arrays": true,
    // 禁止 throw 字串,必須 throw 一個 Error 物件
    "no-string-throw": true,
    // switch 的 case 必須 returnbreak
    "no-switch-case-fall-through": true,
    // 使用例項的方法時,必須 bind 到例項上
    "no-unbound-method": [
      true,
      "ignore-static"
    ],
    // 使用 { ...foo, bar: 1 } 代替 Object.assign({}, foo, { bar: 1 })
    // 前者的型別檢查更完善
    "prefer-object-spread": true,
    // parseInt 必須傳入第二個引數
    "radix": true,
    // 必須使用 isNaN(foo) 而不是 foo === NaN
    "use-isnan": true,
    // 可維護性
    // 這些規則可以增加程式碼的可維護性
    // 禁止函式的迴圈複雜度超過 20,https://en.wikipedia.org/wiki/Cyclomatic_complexity
    "cyclomatic-complexity": [
      true,
      20
    ],
    // 禁止使用廢棄(被標識了 @deprecated)的 API
    "deprecation": true,
    // 一個縮排必須用四個空格替代
    "indent": [
      true,
      "spaces",
      4
    ],
    //import名稱排序要求按照字母從小到大排序
    "ordered-imports": false,
    // 禁止出現重複的 import
    "no-duplicate-imports": true,
    // 禁止一個檔案中出現多個相同的 namespace
    "no-mergeable-namespace": true,
    // 檔案型別必須時 utf-8
    "encoding": true,
    // import 語句中,關鍵字之間的間距必須是一個空格
    "import-spacing": true,
    // 介面可以 implement extend 和 merge
    "interface-over-type-literal": true,
    // new 後面只必須有一個空格
    "new-parens": true,
    // 型別斷言必須使用 as Type,禁止使用 <Type>
    // <Type> 容易被理解為 jsx
    "no-angle-bracket-type-assertion": true,
    // 禁止連續超過三行空行
    "no-consecutive-blank-lines": [
      true,
      3
    ],
    // 禁止使用特殊空白符(比如全形空格)
    "no-irregular-whitespace": true,
    // 禁止使用 JSDoc,因為 TypeScirpt 已經包含了大部分功能
    "no-redundant-jsdoc": true,
    // 禁止使用三斜槓引入型別定義檔案
    "no-reference-import": true,
    // 禁止變數定義時賦值為 undefined
    "no-unnecessary-initializer": true,
    // 小數必須以 0. 開頭,禁止以 . 開頭,並且不能以 0 結尾
    "number-literal-format": true,
    // 必須使用 a = {b} 而不是 a = {b: b}
    "object-literal-shorthand": true,
    // 變數申明必須每行一個,for 迴圈的初始條件中除外
    "one-variable-per-declaration": [
      true,
      "ignore-for-loop"
    ],
    // if 後的 { 禁止換行
    "one-line": true,
    // 必須使用單引號,jsx 中必須使用雙引號
    "quotemark": [
      true,
      "single",
      "jsx-double",
      "avoid-template",
      "avoid-escape"
    ],
    // 行尾必須有分號
    "semicolon": [
      true,
      "always",
      "ignore-interfaces"
    ],
    // 函式名前必須有空格
    "space-before-function-paren": [
      true,
      "asyncArrow"
    ],
    // 括號內首尾禁止有空格
    "space-within-parens": [
      true,
      0
    ],
    // 禁止 finally 內出現 return, continue, break, throw 等
    // finally 會比 catch 先執行
    "no-unsafe-finally": true
  }
}

複製程式碼

具體相關tslint規則:palantir.github.io/tslint/rule…

五、typescript語法

1. 定義型別變數

  • String
let name: string  = '張三';
複製程式碼
  • Number
let num: number  = 123456;
複製程式碼
  • Boolean
let isOpen: boolean = false;
複製程式碼
  • 陣列[]
let arr: number[] = [1,2,3];
let arr: Array<number> = [1, 2, 3];
複製程式碼
  • Any - 任何型別
let arr: any = 1;

複製程式碼
  • Void - 無任何型別
function warnUser(): void {
    console.log("This is my warning message");
}
let unusable: void = undefined;
複製程式碼

2. 函式

傳參型別

// 定義元件傳參型別
interface ToastOption {
    message: string;
    position?: string;
    duration?: number;
}

let instance: any;
const Toast = (options: ToastOption) => {
	instance = new ToastInstance({
        data: options
    });
    instance.visible = true;
    instance.$mount();
    document.body.appendChild(instance.$el);
};
複製程式碼

返回值型別

// 將陣列轉成物件
function formatObj(arr: number[], key: string):any {
    let obj = {};
    if (arr instanceof Array !== true || !key) return;
    for (let item of arr) {
        obj[item[key]] = item;
    }
    return obj;
}
複製程式碼

六、vue-property-decorator使用

文件:github.com/kaorun343/v…

相關文章