国产黄色免费网站_久久天天做天天爱综合色_精品国产一区久久久_成人黄色激情网站_久久成人在线视频_美女一区二区在线观看_亚洲精品免费一区亚洲精品免费精品一区 _91精品国产综合久久精品麻豆

將 Gatsby 項目遷移到 TypeScript

2020-5-4    seo達人

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

整體差不多已經完成遷移,剩下將 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 版本,可以根據需要設置

   "module": "esnext", // 編譯生成的目標模塊系統

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

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

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

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

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

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

   "noUnusedParameters": true, // 報告有關函數中未使用參數的錯誤

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

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

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

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

 },

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

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

}

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


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

補全 TS 聲明定義

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

另外一個錯誤綁定元素“data”隱式具有“any”類型。,這個錯誤是因為我們在tsconfig.json中指定了"strict": true,這會開啟嚴格的類型檢查,可以通過關閉這個選項來解決,只是我們用 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

       }

     }

   }

 }

`

這時候會出現一個新的錯誤,在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 沖突的規則

   `plugin:prettier/recommended`,

 ],

 plugins: [

   `@typescript-eslint`, // 處理 TS 語法規則

   `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文件,會發現PropTypes和query結構非常類似,在Gatsby運行時,會把query查詢的結果作為組件prop.data傳入組件,而PropTypes是用來約束prop存在的.所以其實PropTypes就是根據query寫出來的.


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

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


總結以下需要完善的體驗包括:


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

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

實現方式:


通過生成架構文件,配合Apollo GraphQL for VS Code插件,實現智能提示,以及錯誤檢查

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

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

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

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


gatsby-plugin-codegen

gatsby-plugin-typegen

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


注意點:


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

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

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

下面是具體操作


安裝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的類型約束和智能提示.

另外會自動根據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,

     },

   },

 ],

}

重新運行開發服務生成類型文件


yarn develop

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


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配合手動創建的apollo.config.js提供GraphQL的類型約束和智能提示.

根據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`,

   },

 },

}

重新運行開發服務生成類型文件


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__

日歷

鏈接

個人資料

藍藍設計的小編 http://www.newchinaweekly.com

存檔

手机亚洲第一页| 日韩午夜激情av| 制服丝袜av成人在线看| 亚洲视频在线观看| 欧美怡春院一区二区三区| 99热最新在线| 日本免费a视频| 亚洲一区二区图片| 久久免费看少妇高潮v片特黄| 久草视频一区二区| 性感美女视频一二三| 人人爱人人爽| 国产露出视频在线观看| 写真福利精品福利在线观看| julia中文字幕一区二区99在线| 2023国产精品久久久精品双| 日韩一区精品视频| 中文av字幕一区| 日韩欧美综合一区| 97久久精品国产| 亚洲不卡一卡2卡三卡4卡5卡精品| 无人在线观看的免费高清视频| 亚洲av成人无码久久精品| 中文字幕观看在线| 天海翼视频在线观看| 国产在线观看黄| 欧美久久一区二区三区| 国产精品美女久久久| 国产精品久久看| 日韩电视剧免费观看网站| 国产高清在线不卡| 青青草国产免费| 天天鲁一鲁摸一摸爽一爽| 女人18毛片一区二区三区| 免费福利影院| 51一区二区三区| 国产日本精品| 亚洲宅男天堂在线观看无病毒| 亚洲香蕉伊综合在人在线视看| 亚洲自拍欧美色图| 亚洲精品性视频| 69亚洲精品久久久蜜桃小说| 美女被羞羞网站| а√在线天堂官网| 亚洲国产婷婷| 欧美日韩国产精品一区二区三区四区 | av成人免费网站| 中文天堂网在线www| jizzjizz在线观看| 999国产精品| 亚洲天天做日日做天天谢日日欢| 国产亚洲欧美aaaa| 亚洲精品一品区二品区三品区| 亚洲天堂成人av| 亚洲一道本在线| av大片在线| 亚洲日产国产精品| 91九色最新地址| 国产欧美最新羞羞视频在线观看| 动漫av免费观看| 97精品人妻一区二区三区| 最新中文字幕在线视频| 欧美色资源站| 国产精品视频你懂的| 久久99青青精品免费观看| 国产二级片在线观看| 狠狠狠狠狠狠狠| 一级在线视频| 欧美3p在线观看| 亚洲欧美日韩综合aⅴ视频| 色综合视频网站| 99蜜桃臀久久久欧美精品网站| 国产精品51麻豆cm传媒| 日本黄在线观看| 婷婷综合在线| 在线欧美一区二区| 国产乱码一区| 放荡的美妇在线播放| 成人午夜剧场免费观看完整版| www.豆豆成人网.com| 欧美国产一区二区| 51精品国产黑色丝袜高跟鞋| 欧美激情国内自拍| 欧美一级手机免费观看片| 欧美成a人片在线观看久| 成人做爰69片免费看网站| 尤物九九久久国产精品的特点| 少妇av一区二区三区无码| a级片在线免费看| 成人av影院在线观看| 九九九久久久精品| 一本色道久久88亚洲综合88 | 丰满人妻一区二区三区免费| 污污的网站在线免费观看| 免费不卡在线视频| 色偷偷88888欧美精品久久久| 日韩视频第二页| √天堂中文www官网| 成人福利片在线| 中文字幕欧美国产| 国产精品一区二区性色av| 日本欧美一区二区三区不卡视频| 高潮白浆视频| 欧美日韩99| 日韩av一区二区在线| 99999精品视频| 国产精品视频第一区二区三区| 久久午夜影院| 色婷婷久久久综合中文字幕| 免费看成人片| 亚洲综合五月天婷婷丁香| cao在线视频| 国产精品天干天干在线综合| 成人有码在线播放| 日韩久久精品视频| 在线观看av免费| 久久久www成人免费无遮挡大片| 国产精品久久久久9999| 性欧美videos| av网站网址在线观看| 91偷拍与自偷拍精品| 成人高清视频观看www| 日本特黄特色aaa大片免费| 精品176二区| 94色蜜桃网一区二区三区| 成人精品视频99在线观看免费| 日本午夜精品理论片a级app发布| 黄在线免费看| 欧美激情一区二区在线| 精品国产一区二区三区四区vr| 亚洲一级在线播放| 国产精品中文| 欧美丰满少妇xxxxx高潮对白| 日韩中文字幕三区| jizz.www| 蜜臀99久久精品久久久久久软件| 97色在线视频| 91精品国产乱码在线观看| 精品捆绑调教一区二区三区| 一区二区视频在线看| 一区二区视频国产| 国产欧美日韩专区| 欧美激情第二页| 久久99视频精品| 久久久久久久久久一区二区三区| 678在线观看视频| 欧美日韩一区二区三区| 国产91对白刺激露脸在线观看| jizzjizzjizz亚洲| 国产一区二区在线看| 91视频网页| 亚洲爱爱天堂| 中文字幕一区二区av | 私密视频在线观看| 国家队第一季免费高清在线观看| 久久精品亚洲麻豆av一区二区| 日本精品国语自产拍在线观看| 欧美最猛性xxxx免费| 亚洲二区精品| 国产精品普通话| 丁香六月天婷婷| 一区二区影视| 国产97在线观看| 国产三级自拍视频| 欧美1级片网站| 97免费中文视频在线观看| 欧美在线视频精品| 国产一区二区亚洲| 久久久久成人精品| 亚洲在线观看av| 水蜜桃精品av一区二区| 国内伊人久久久久久网站视频| 成人免费一级片| 人人狠狠综合久久亚洲婷婷| 久久免费国产视频| 亚洲一区精品在线观看| 黑丝美女一区二区| 久久人人爽国产| 成人av一区二区三区在线观看| 亚洲精品午夜av福利久久蜜桃| 日韩女优人人人人射在线视频| 亚洲毛片欧洲毛片国产一品色| 在线一区免费| 91网站免费观看| 日韩在线导航| 91啦中文成人| 国产成人亚洲综合a∨婷婷| 欧美连裤袜在线视频| 口述被爽到呻吟高潮自述| 成人av网站在线观看| 午夜欧美性电影| 精产国产伦理一二三区| 亚洲天堂av老司机| 久久久久久久高清| ririsao久久精品一区| 欧美tk—视频vk| 国产精品日日夜夜| 精品美女视频| 92看片淫黄大片欧美看国产片| 天堂在线免费观看|