国产精品爱久久久久久久小说,女人扒开腿让男人桶到爽 ,亚洲欧美国产双大乳头,国产成人精品综合久久久久,国产精品制服丝袜无码,免费无码精品黄av电影,黑色丝袜无码中中文字幕,乱熟女高潮一区二区在线

    將 Gatsby 項(xiàng)目遷移到 TypeScript

    2020-5-4    seo達(dá)人

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

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


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


    遷移步驟:


    TS 配置

    配置 ESLint 支持 TS

    完善 GraphQL 類(lèi)型提示

    初始化項(xiàng)目

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

    cd gatsby-migrate-to-typescript

    yarn develop

    TS 配置

    安裝typescript

    添加typescript.json配置文件

    修改 js 文件為 tsx

    補(bǔ)全 TS 聲明定義

    安裝typescript

    yarn add -D typescript

    添加配置文件tsconfig.json

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

    {

     "compilerOptions": {

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

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

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

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

       "strict": true, // 開(kāi)啟嚴(yán)格模式

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

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

       "noUnusedLocals": true, // 報(bào)告未使用的局部變量的錯(cuò)誤

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

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

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

       "noEmit": true, // 不輸出 js,源映射或聲明之類(lèi)的文件,單純用來(lái)檢查錯(cuò)誤

       "skipLibCheck": true // 跳過(guò)聲明文件的類(lèi)型檢查,只會(huì)檢查已引用的部分

     },

     "exclude": ["./node_modules", "./public", "./.cache"], // 解析時(shí),應(yīng)該跳過(guò)的路晉

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

    }

    將index.js改成index.tsx,重新啟動(dòng)服務(wù),查看效果.


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

    補(bǔ)全 TS 聲明定義

    打開(kāi)index.tsx,VSCode 會(huì)報(bào)兩個(gè)錯(cuò)誤,一個(gè)是找不到styled-components的聲明文件,這個(gè)可以通過(guò)安裝@types/styled-components來(lái)解決.

    另外一個(gè)錯(cuò)誤綁定元素“data”隱式具有“any”類(lèi)型。,這個(gè)錯(cuò)誤是因?yàn)槲覀冊(cè)趖sconfig.json中指定了"strict": true,這會(huì)開(kāi)啟嚴(yán)格的類(lèi)型檢查,可以通過(guò)關(guān)閉這個(gè)選項(xiàng)來(lái)解決,只是我們用 TS 就是要用它的類(lèi)型檢查的,所以正確的做法是給data定義類(lèi)型.

    下面來(lái)一一修復(fù)錯(cuò)誤.


    安裝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

           }

         }

       }

     }

    `

    這時(shí)候會(huì)出現(xiàn)一個(gè)新的錯(cuò)誤,在excerpt: string處提示Parsing error: Unexpected token,這是因?yàn)?ESLint 還無(wú)法識(shí)別 TS 的語(yǔ)法,下面來(lái)配置 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 語(yǔ)法規(guī)則

       `react`,

       `filenames`,

     ],

     // ...

    }

    在.vscode/settings.json中添加配置,讓VSCode使用ESLint擴(kuò)展格式化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 類(lèi)型提示

    // 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文件,會(huì)發(fā)現(xiàn)PropTypes和query結(jié)構(gòu)非常類(lèi)似,在Gatsby運(yùn)行時(shí),會(huì)把query查詢的結(jié)果作為組件prop.data傳入組件,而PropTypes是用來(lái)約束prop存在的.所以其實(shí)PropTypes就是根據(jù)query寫(xiě)出來(lái)的.


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

    另外一個(gè)問(wèn)題是在query中編寫(xiě)GraphQL查詢時(shí),并沒(méi)有類(lèi)型約束,也沒(méi)有智能提示.


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


    GraphQL 查詢編寫(xiě)時(shí)的智能提示,以及錯(cuò)誤檢查

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

    實(shí)現(xiàn)方式:


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

    通過(guò)graphql-code-generator或者apollo生成 TS 類(lèi)型定義文件

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

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

    嘗試過(guò)以下兩個(gè)插件能解決上述問(wèn)題,可以任選其一使用


    gatsby-plugin-codegen

    gatsby-plugin-typegen

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


    注意點(diǎn):


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

    第一次生成,需要運(yùn)行Gatsby之后才能生成類(lèi)型文件

    整個(gè)項(xiàng)目?jī)?nèi)不能有相同命名的查詢,不然會(huì)因?yàn)槊钟袥_突而生成失敗

    下面是具體操作


    安裝vscode-apollo擴(kuò)展

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


    ext install apollographql.vscode-apollo

    方式一: 使用gatsby-plugin-codegen

    gatsby-plugin-codegen默認(rèn)會(huì)生成apollo.config.js和schema.json,配合vscode-apollo擴(kuò)展,可以提供GraphQL的類(lèi)型約束和智能提示.

    另外會(huì)自動(dòng)根據(jù)query中的GraphQL查詢,生成 TS 類(lèi)型,放在對(duì)應(yīng)的tsx文件同級(jí)目錄下的__generated__文件夾,使用時(shí)只需要引入即可.

    如果需要在運(yùn)行時(shí)自動(dòng)生成 TS 類(lèi)型,需要添加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,

         },

       },

     ],

    }

    重新運(yùn)行開(kāi)發(fā)服務(wù)生成類(lèi)型文件


    yarn develop

    如果出現(xiàn)以下錯(cuò)誤,一般是因?yàn)闆](méi)有為查詢命名的緣故,給查詢添加命名即可,另外配置正確的話,打開(kāi)對(duì)應(yīng)的文件,有匿名查詢,編輯器會(huì)有錯(cuò)誤提示.


    fix-anonymous-operations.png


    這個(gè)命名之后會(huì)作為生成的類(lèi)型名.


    修改index.tsx以使用生成的類(lèi)型


    gatsby-plugin-codegen插件會(huì)更具查詢生成對(duì)應(yīng)的查詢名稱(chēng)的類(lèi)型,保存在對(duì)應(yīng)tsx文件同級(jí)的__generated__目錄下.


    import { HomeQuery } from './__generated__/HomeQuery' // 引入自動(dòng)生成的類(lèi)型

    // ...


    // interface PageQuery {

    //   data: {

    //     allMarkdownRemark: {

    //       edges: Array<{

    //         node: {

    //           frontmatter: {

    //             title: string

    //           }

    //           excerpt: string

    //         }

    //       }>

    //     }

    //   }

    // }


    interface PageQuery {

     data: HomeQuery // 替換之前手寫(xiě)的類(lèi)型

    }


    // ...

    將自動(dòng)生成的文件添加到.gitignore中


    apollo.config.js,schema.json,__generated__能通過(guò)運(yùn)行時(shí)生成,所以可以添加到.gitignore中,不用提交到 git 中.當(dāng)然如果有需要也可以選擇提交到 git 中.

    # Generated types by gatsby-plugin-codegen

    __generated__

    apollo.config.js

    schema.json

    方式二: 使用gatsby-plugin-typegen

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

    根據(jù)GraphQL查詢生成gatsby-types.d.ts,生成的類(lèi)型放在命名空間GatsbyTypes下,使用時(shí)通過(guò)GatsbyTypes.HomeQueryQuery來(lái)引入,HomeQueryQuery是由對(duì)應(yīng)的命名查詢生成


    安裝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`,

       },

     },

    }

    重新運(yùn)行開(kāi)發(fā)服務(wù)生成類(lèi)型文件


    yarn develop

    修改index.tsx以使用生成的類(lèi)型


    gatsby-plugin-codegen插件會(huì)更具查詢生成對(duì)應(yīng)的查詢名稱(chēng)的類(lèi)型,保存在對(duì)應(yīng)tsx文件同級(jí)的__generated__目錄下.


    // ...


    // interface PageQuery {

    //   data: {

    //     allMarkdownRemark: {

    //       edges: Array<{

    //         node: {

    //           frontmatter: {

    //             title: string

    //           }

    //           excerpt: string

    //         }

    //       }>

    //     }

    //   }

    // }


    interface PageQuery {

     data: GatsbyTypes.HomeQueryQuery // 替換之前手寫(xiě)的類(lèi)型

    }


    // ...

    將自動(dòng)生成的文件添加到.gitignore中


    __generated__能通過(guò)運(yùn)行時(shí)生成,所以可以添加到.gitignore中,不用提交到 git 中.當(dāng)然如果有需要也可以選擇提交到 git 中.

    # Generated types by gatsby-plugin-codegen

    __generated__

    日歷

    鏈接

    個(gè)人資料

    存檔

    主站蜘蛛池模板: 小柔的裸露日记h| 欧美3p两根一起进高清免费视频 | 久久精品国产99亚洲精品| 欧美v日韩v亚洲v最新在线观看| 天天干夜夜撸| 女人性做爰100部免费| 中日韩高清无专码区2021 | 日韩免费不卡视频| 国产偷自视频区视频| 国产∨亚洲v天堂无码久久久| 亚洲成人黄色片| 浪潮av色综合久久天堂| 亚洲日本va午夜中文字幕久久| 日韩一区二区不卡| 国产一级淫片免费| 亚洲综合无码一区二区三区| 久久不卡国产精品无码| 不卡av在线免费观看| 在线观看福利片| 国产suv精品一区二人妻| 韩国伦理片在线观看| 国产精品自拍在线观看| 天天综合天天做天天综合| 久久99精国产一区二区三区四区| 秒拍福利视频| 中文字幕观看在线| 伊人久久大香线焦av色| 国产成人综合怡春院精品| 日韩69视频| 日不卡| 中文字幕av无码人妻| 亚洲动漫精品无码av天堂| 草女人视频| 免费一级黄色好看的国产| 国产午夜精品无码| 亚洲国产精品日韩av专区| 欧美日韩h| 国产区精品视频自产自拍| 女同性av片在线观看免费网站 | 在厨房拨开内裤进入毛片| 国产精品午夜剧场免费观看|