<thead id="kdfuf"><font id="kdfuf"></font></thead>
<samp id="kdfuf"></samp>
    <nav id="kdfuf"><strong id="kdfuf"></strong></nav>
      中文字幕无码一区二区三区在线,久久精品人人做人人爽,国产一级内射无挡观看,十八禁在线黄色网站,日韩欧美国产另类久久久精品 ,少妇人妻偷人精品一区二区,久久午夜视频,亚洲春色AⅤ无码专区

      將 Gatsby 項目遷移到 TypeScript

      2020-5-4    seo達人

      之前花了些時間將gatsby-theme-gitbook遷移到 Typescript,以獲得在 VSCode 中更好的編程體驗.

      整體差不多已經(jīng)完成遷移,剩下將 Gatsby 的 API 文件也遷移到 TS,這里可以看到 gatsby#21995 官方也在將核心代碼庫遷移到 Typescript,準備等待官方將核心代碼庫遷移完成,在遷移 API 文件.


      這篇文章用XYShaoKang/gatsby-project-config,演示如何將 gatsby 遷移到 TypeScript,希望能幫到同樣想要在 Gatsby 中使用 TS 的同學.


      遷移步驟:


      TS 配置

      配置 ESLint 支持 TS

      完善 GraphQL 類型提示

      初始化項目

      gatsby new gatsby-migrate-to-typescript XYShaoKang/gatsby-project-config

      cd gatsby-migrate-to-typescript

      yarn develop

      TS 配置

      安裝typescript

      添加typescript.json配置文件

      修改 js 文件為 tsx

      補全 TS 聲明定義

      安裝typescript

      yarn add -D typescript

      添加配置文件tsconfig.json

      // https://www.typescriptlang.org/v2/docs/handbook/tsconfig-json.html

      {

       "compilerOptions": {

         "target": "esnext", // 編譯生成的目標 es 版本,可以根據(jù)需要設(shè)置

         "module": "esnext", // 編譯生成的目標模塊系統(tǒng)

         "lib": ["dom", "es2015", "es2017"], // 配置需要包含的運行環(huán)境的類型定義

         "jsx": "react", // 配置 .tsx 文件的輸出模式

         "strict": true, // 開啟嚴格模式

         "esModuleInterop": true, // 兼容 CommonJS 和 ES Module

         "moduleResolution": "node", // 配置模塊的解析規(guī)則,支持 node 模塊解析規(guī)則

         "noUnusedLocals": true, // 報告未使用的局部變量的錯誤

         "noUnusedParameters": true, // 報告有關(guān)函數(shù)中未使用參數(shù)的錯誤

         "experimentalDecorators": true, // 啟用裝飾器

         "emitDecoratorMetadata": true, // 支持裝飾器上生成元數(shù)據(jù),用來進行反射之類的操作

         "noEmit": true, // 不輸出 js,源映射或聲明之類的文件,單純用來檢查錯誤

         "skipLibCheck": true // 跳過聲明文件的類型檢查,只會檢查已引用的部分

       },

       "exclude": ["./node_modules", "./public", "./.cache"], // 解析時,應該跳過的路晉

       "include": ["src"] // 定義包含的路徑,定義在其中的聲明文件都會被解析進 vscode 的智能提示

      }

      將index.js改成index.tsx,重新啟動服務,查看效果.


      其實 Gatsby 內(nèi)置了支持 TS,不用其他配置,只要把index.js改成index.tsx就可以直接運行.添加 TS 依賴是為了顯示管理 TS,而tsconfig.json也是這個目的,當我們有需要新的特性以及自定義配置時,可以手動添加.

      補全 TS 聲明定義

      打開index.tsx,VSCode 會報兩個錯誤,一個是找不到styled-components的聲明文件,這個可以通過安裝@types/styled-components來解決.

      另外一個錯誤綁定元素“data”隱式具有“any”類型。,這個錯誤是因為我們在tsconfig.json中指定了"strict": true,這會開啟嚴格的類型檢查,可以通過關(guān)閉這個選項來解決,只是我們用 TS 就是要用它的類型檢查的,所以正確的做法是給data定義類型.

      下面來一一修復錯誤.


      安裝styled-components的聲明文件


      yarn add -D @types/styled-components

      修改index.tsx


      import React, { FC } from 'react'

      import styled from 'styled-components'

      import { graphql } from 'gatsby'

      import { HomeQuery } from './__generated__/HomeQuery'


      const Title = styled.h1`

       font-size: 1.5em;

       margin: 0;

       padding: 0.5em 0;

       color: palevioletred;

       background: papayawhip;

      `


      const Content = styled.div`

       margin-top: 0.5em;

      `


      interface PageQuery {

       data: {

         allMarkdownRemark: {

           edges: Array<{

             node: {

               frontmatter: {

                 title: string

               }

               excerpt: string

             }

           }>

         }

       }

      }


      const Home: FC<PageQuery> = ({ data }) => {

       const node = data.allMarkdownRemark.edges[0].node


       const title = node.frontmatter?.title

       const excerpt = node.excerpt


       return (

         <>

           <Title>{title}</Title>

           <Content>{excerpt}</Content>

         </>

       )

      }


      export default Home


      export const query = graphql`

       query HomeQuery {

         allMarkdownRemark {

           edges {

             node {

               frontmatter {

                 title

               }

               excerpt

             }

           }

         }

       }

      `

      這時候會出現(xiàn)一個新的錯誤,在excerpt: string處提示Parsing error: Unexpected token,這是因為 ESLint 還無法識別 TS 的語法,下面來配置 ESLint 支持 TS.


      配置 ESLint 支持 TypeScript

      安裝依賴


      yarn add -D @typescript-eslint/parser @typescript-eslint/eslint-plugin

      配置.eslintrc.js


      module.exports = {

       parser: `@typescript-eslint/parser`, // 將解析器從`babel-eslint`替換成`@typescript-eslint/parser`,用以解析 TS 代碼

       extends: [

         `google`,

         `eslint:recommended`,

         `plugin:@typescript-eslint/recommended`, // 使用 @typescript-eslint/eslint-plugin 推薦配置

         `plugin:react/recommended`,

         `prettier/@typescript-eslint`, // 禁用 @typescript-eslint/eslint-plugin 中與 prettier 沖突的規(guī)則

         `plugin:prettier/recommended`,

       ],

       plugins: [

         `@typescript-eslint`, // 處理 TS 語法規(guī)則

         `react`,

         `filenames`,

       ],

       // ...

      }

      在.vscode/settings.json中添加配置,讓VSCode使用ESLint擴展格式化ts和tsx文件


      // .vscode/settings.json

      {

       "eslint.format.enable": true,

       "[javascript]": {

         "editor.defaultFormatter": "dbaeumer.vscode-eslint"

       },

       "[javascriptreact]": {

         "editor.defaultFormatter": "dbaeumer.vscode-eslint"

       },

       "[typescript]": {

         "editor.defaultFormatter": "dbaeumer.vscode-eslint"

       },

       "[typescriptreact]": {

         "editor.defaultFormatter": "dbaeumer.vscode-eslint"

       }

      }

      完善 GraphQL 類型提示

      // index.tsx

      import React, { FC } from 'react'

      // ...

      interface PageQuery {

       data: {

         allMarkdownRemark: {

           edges: Array<{

             node: {

               frontmatter: {

                 title: string

               }

               excerpt: string

             }

           }>

         }

       }

      }


      const Home: FC<PageQuery> = ({ data }) => {

       // ...

      }


      export default Home


      export const query = graphql`

       query HomeQuery {

         allMarkdownRemark {

           edges {

             node {

               frontmatter {

                 title

               }

               excerpt

             }

           }

         }

       }

      `

      我們看看index.tsx文件,會發(fā)現(xiàn)PropTypes和query結(jié)構(gòu)非常類似,在Gatsby運行時,會把query查詢的結(jié)果作為組件prop.data傳入組件,而PropTypes是用來約束prop存在的.所以其實PropTypes就是根據(jù)query寫出來的.


      如果有依據(jù)query自動生成PropTypes的功能就太棒了.

      另外一個問題是在query中編寫GraphQL查詢時,并沒有類型約束,也沒有智能提示.


      總結(jié)以下需要完善的體驗包括:


      GraphQL 查詢編寫時的智能提示,以及錯誤檢查

      能夠從 GraphQL 查詢生成對應的 TypeScript 類型.這樣能保證類型的唯一事實來源,并消除 TS 中冗余的類型聲明.畢竟如果經(jīng)常需要手動更新兩處類型,會更容易出錯,而且也并不能保證手動定義類型的正確性.

      實現(xiàn)方式:


      通過生成架構(gòu)文件,配合Apollo GraphQL for VS Code插件,實現(xiàn)智能提示,以及錯誤檢查

      通過graphql-code-generator或者apollo生成 TS 類型定義文件

      如果自己去配置的話,是挺耗費時間的,需要去了解graphql-code-generator的使用,以及Apollo的架構(gòu)等知識.

      不過好在社區(qū)中已經(jīng)有對應的 Gatsby 插件集成了上述工具可以直接使用,能讓我們不用去深究對應知識的情況下,達到優(yōu)化 GraphQL 編程的體驗.

      嘗試過以下兩個插件能解決上述問題,可以任選其一使用


      gatsby-plugin-codegen

      gatsby-plugin-typegen

      另外還有一款插件gatsby-plugin-graphql-codegen也可以生成 TS 類型,不過配置略麻煩,并且上述兩個插件都可以滿足我現(xiàn)在的需求,所以沒有去嘗試,感興趣的可以嘗試一下.


      注意點:


      Apollo不支持匿名查詢,需要使用命名查詢

      第一次生成,需要運行Gatsby之后才能生成類型文件

      整個項目內(nèi)不能有相同命名的查詢,不然會因為名字有沖突而生成失敗

      下面是具體操作


      安裝vscode-apollo擴展

      在 VSCode 中按 Ctrl + P ( MAC 下: Cmd + P) 輸入以下命令,按回車安裝


      ext install apollographql.vscode-apollo

      方式一: 使用gatsby-plugin-codegen

      gatsby-plugin-codegen默認會生成apollo.config.js和schema.json,配合vscode-apollo擴展,可以提供GraphQL的類型約束和智能提示.

      另外會自動根據(jù)query中的GraphQL查詢,生成 TS 類型,放在對應的tsx文件同級目錄下的__generated__文件夾,使用時只需要引入即可.

      如果需要在運行時自動生成 TS 類型,需要添加watch: true配置.


      安裝gatsby-plugin-codegen


      yarn add gatsby-plugin-codegen

      配置gatsby-config.js


      // gatsby-config.js

      module.exports = {

       plugins: [

         // ...

         {

           resolve: `gatsby-plugin-codegen`,

           options: {

             watch: true,

           },

         },

       ],

      }

      重新運行開發(fā)服務生成類型文件


      yarn develop

      如果出現(xiàn)以下錯誤,一般是因為沒有為查詢命名的緣故,給查詢添加命名即可,另外配置正確的話,打開對應的文件,有匿名查詢,編輯器會有錯誤提示.


      fix-anonymous-operations.png


      這個命名之后會作為生成的類型名.


      修改index.tsx以使用生成的類型


      gatsby-plugin-codegen插件會更具查詢生成對應的查詢名稱的類型,保存在對應tsx文件同級的__generated__目錄下.


      import { HomeQuery } from './__generated__/HomeQuery' // 引入自動生成的類型

      // ...


      // interface PageQuery {

      //   data: {

      //     allMarkdownRemark: {

      //       edges: Array<{

      //         node: {

      //           frontmatter: {

      //             title: string

      //           }

      //           excerpt: string

      //         }

      //       }>

      //     }

      //   }

      // }


      interface PageQuery {

       data: HomeQuery // 替換之前手寫的類型

      }


      // ...

      將自動生成的文件添加到.gitignore中


      apollo.config.js,schema.json,__generated__能通過運行時生成,所以可以添加到.gitignore中,不用提交到 git 中.當然如果有需要也可以選擇提交到 git 中.

      # Generated types by gatsby-plugin-codegen

      __generated__

      apollo.config.js

      schema.json

      方式二: 使用gatsby-plugin-typegen

      gatsby-plugin-typegen通過配置生成gatsby-schema.graphql和gatsby-plugin-documents.graphql配合手動創(chuàng)建的apollo.config.js提供GraphQL的類型約束和智能提示.

      根據(jù)GraphQL查詢生成gatsby-types.d.ts,生成的類型放在命名空間GatsbyTypes下,使用時通過GatsbyTypes.HomeQueryQuery來引入,HomeQueryQuery是由對應的命名查詢生成


      安裝gatsby-plugin-typegen


      yarn add gatsby-plugin-typegen

      配置


      // gatsby-config.js

      module.exports = {

       plugins: [

         // ...

         {

           resolve: `gatsby-plugin-typegen`,

           options: {

             outputPath: `src/__generated__/gatsby-types.d.ts`,

             emitSchema: {

               'src/__generated__/gatsby-schema.graphql': true,

             },

             emitPluginDocuments: {

               'src/__generated__/gatsby-plugin-documents.graphql': true,

             },

           },

         },

       ],

      }

      //apollo.config.js

      module.exports = {

       client: {

         tagName: `graphql`,

         includes: [

           `./src/**/*.{ts,tsx}`,

           `./src/__generated__/gatsby-plugin-documents.graphql`,

         ],

         service: {

           name: `GatsbyJS`,

           localSchemaFile: `./src/__generated__/gatsby-schema.graphql`,

         },

       },

      }

      重新運行開發(fā)服務生成類型文件


      yarn develop

      修改index.tsx以使用生成的類型


      gatsby-plugin-codegen插件會更具查詢生成對應的查詢名稱的類型,保存在對應tsx文件同級的__generated__目錄下.


      // ...


      // interface PageQuery {

      //   data: {

      //     allMarkdownRemark: {

      //       edges: Array<{

      //         node: {

      //           frontmatter: {

      //             title: string

      //           }

      //           excerpt: string

      //         }

      //       }>

      //     }

      //   }

      // }


      interface PageQuery {

       data: GatsbyTypes.HomeQueryQuery // 替換之前手寫的類型

      }


      // ...

      將自動生成的文件添加到.gitignore中


      __generated__能通過運行時生成,所以可以添加到.gitignore中,不用提交到 git 中.當然如果有需要也可以選擇提交到 git 中.

      # Generated types by gatsby-plugin-codegen

      __generated__

      日歷

      鏈接

      個人資料

      藍藍設(shè)計的小編 http://www.tuitetiyu.cn

      存檔

      主站蜘蛛池模板: 欧美精品成人a在线观看| 免费a级黄毛片| 亚洲精品无码AV天天爽播放| 凌源市| 柳河县| 色婷婷久久综合中文久久一| 91麻豆国产高清产精品第一页| 1024国产精品永远免费| 97精品一区二区三区在线播放| 久久tv免费国产高清| 中文字幕99国产精品| 97人人澡人人爽91综合色区| 夜夜疯东京热中文字幕一区| 久久综合九九综合欧美98| 民勤县| 国产精品yy9299| 融水| 关岭| 欧洲熟妇色XXXX欧美老妇老头多毛| 首之国产AV医生和护士小芳 | 中文字幕一区二区三区日韩精品| 女人亚洲自慰喷潮爱看AV| 国产无码视频在线| 亚洲自拍偷拍视频| 老熟妇乱子伦牲交视频欧美| 和田市| 日本黄一区二区| 国产—级a片无码| 热re99久久精品国产99热| 丰满少妇内射一区| 免费毛a在线观看视频| 草草浮力影院| 久久精品亚洲AV无码2区| 久久久中文久久久无码| 亚洲精品1区二区3区| 日韩高清亚洲日韩精品一区二区| 国产毛片A级久久久无码| 成 人 色 网 站免费观看| 日本秋霞免费午夜场| 国产精品网址在线观看你懂的| 国内精品伊人久久久久|