使用Node.js和Express创建GraphQL服务器

這是一個關於如何使用Node.js和Express創建GraphQL服務器的簡單教程。 首先,創建一個新的Node.js項目,如果您還沒有設置一個的話: npm init --y 這個命令會創建我們使用npm所需的package.json文件。 安裝npm包express,graphql和express-graphql: npm install express graphql express-graphql 創建一個app.js文件,並開始初始化Express服務器: const express = require('express') const app = express() app.listen(3000, () => { console.log('App listening on port 3000') }) 現在我們添加express-graphql庫,它是一個中間件(middleware),我們將它應用於/graphql路由: const express = require('express') const graphqlHTTP = require('express-graphql') const app = express() app.use('/graphql', graphqlHTTP()) app.listen(3000, () => { console.log('App listening on port 3000') }) 我們需要傳遞一個對象,該對象包含了 schema 屬性,該屬性必須包含一個schema定義。 我們首先需要定義一個schema! 創建一個schema.js文件,然後在其中引入graphql庫,使用對象解構語法,我們獲取GraphQLSchema,GraphQLObjectType和GraphQLString這幾個對象: const graphql = require('graphql') const { GraphQLSchema, GraphQLObjectType, GraphQLString } = graphql 然後,我們通過初始化一個新的GraphQLSchema實例,並傳遞一個對象給它,該對象包含一個query屬性。該屬性是一個GraphQLObjectType對象的實例:...

使用Rest和Spread處理物件和陣列

學習在JavaScript中使用兩種現代技術來處理陣列和物件。 你可以使用spread運算子 ...來展開陣列、物件或字串。 讓我們從一個陣列的例子開始。給定 const a = [1, 2, 3] 你可以使用以下方式創建一個新的陣列 const b = [...a, 4, 5, 6] 你也可以使用以下方式創建一個陣列的複製 const c = [...a] 這對於物件也同樣適用。使用以下方式克隆一個物件: const newObj = { ...oldObj } 對於字串,spread運算子會創建一個包含字串中每個字符的陣列: const hey = 'hey' const arrayized = [...hey] // ['h', 'e', 'y'] 這個運算子有一些非常有用的應用。其中最重要的一個是在非常簡單的方式下將陣列用作函數參數: const f = (arg1, arg2) => {} const a = [1, 2] f(...a) (在過去,你可以使用 f.apply(null, a) 來實現這一點,但這不太好看和易讀) rest元素在處理陣列解構時非常有用: const numbers = [1, 2, 3, 4, 5] [first, second, ....

使用開發工具控制台和控制台 API

每個瀏覽器都提供了一個控制台,讓您可以與 Web 平台 API 進行交互,並通過打印由網頁中運行的 JavaScript 代碼生成的消息來查看代碼的內部結構。 控制台概述 使用控制台日誌格式化 清除控制台 計算元素的數量 記錄複雜對象 記錄不同級別的錯誤 在導航期間保留日誌 分組控制台消息 打印堆棧跟踪 計算所花費的時間 生成 CPU 配置文件 控制台概述 控制台工具欄很簡單。有一個按鈕可以清除控制台消息,您還可以在 macOS 上單擊 cmd-K ,或在 Windows 上單擊 ctrl-K 以清除控制台消息,第二個按鈕可以激活一個側邊欄,讓您可以按照文本或消息類型進行過濾,例如錯誤、警告、信息、日誌或調試消息。 您還可以選擇隱藏網絡生成的消息,只關注 JavaScript 日誌消息。 控制台不僅是您可以查看消息的地方,還是與 JavaScript 代碼和 DOM 進行交互的最佳方式,並且有許多時候還用於從頁面上獲取信息。 讓我們輸入我們的第一條消息。請注意 > ,讓我們在此處點擊並輸入 console.log('test') 控制台充當了一個 REPL(Read-Eval-Print-Loop) ,這意味著它解釋我們的 JavaScript 代碼並打印一些東西。 使用控制台日誌格式化 正如您所見,console.log('test') 在控制台中打印了 ’test’。 在您的 JavaScript 代碼中使用 console.log 可以幫助您調試,例如打印靜態字符串,但您還可以將變量作為參數傳遞給它,該變量可以是 JavaScript 原生類型(例如整數)或對象。 您可以將多個變量傳遞給 console.log ,例如: console.log('test1', 'test2') 您還可以通過傳遞變量和格式指定符來格式化漂亮的短語。 例如: console.log('我的 %s 有 %d 歲', '貓', 2) %s 將變量格式化為字符串 %d 或 %i 將變量格式化為整數 %f 將變量格式化為浮點數 %o 用於打印 DOM 元素 %O 用於打印對象表示形式 示例:...

在 Express 中處理 CORS

如何透過設定 CORS 允許跨網站請求 通常在瀏覽器中運行的 JavaScript 應用程式只能存取由同一個網域(原始網站)提供的 HTTP 資源。 從相同來源載入圖片、腳本/樣式表一直是可行的。使用 @font-face 載入網頁字型時也已經有預設的「同源政策」。而其他較不常見的事物(例如 WebGL 紋理和 Canvas API 中載入的 drawImage 資源)也是如此。 然而,對於從外部第三方伺服器發送的 XHR 和 Fetch 請求,預設會失敗。這就是除非第三方伺服器實現了一個允許建立連線以及請求資源並下載和使用的機制。 這個機制被稱為 CORS 跨來源資源共用。 需要 CORS 的一件非常重要的事情是 ES 模組,最近在現代瀏覽器中引入了。 如果您沒有在伺服器端設置允許提供第三方來源的 CORS 政策,請求將會失敗。 Fetch 範例: XHR 範例: 跨來源資源失敗的條件如下: 不同網域 不同子網域 不同埠號 不同協定 CORS 的目的是為了保護您的安全,防止惡意使用者利用您正在使用的 Web 平台。 如果您同時控制了伺服器和客戶端,您會知道雙方都是可信任的,因此有充分的理由允許資源共用。 如何做到這點呢? 答案取決於您使用的伺服器端堆棧。 瀏覽器支援 相當不錯(基本上所有,除了 IE<10): Express 範例 如果您正在使用 Node.js 和 Express 作為框架,請使用 CORS 中介軟體套件。 這裡有一個簡單的 Express Node.js 伺服器範例: const express = require('express') const app = express() app....

在 JavaScript 中使用 call() 和 apply()

了解如何在 JavaScript 中使用 call() 和 apply() 函数以及它们的区别。 call() 和 apply() 是 JavaScript 提供的两个函数,用于执行一个非常特定的任务:调用一个函数并设置其 this 值。 查看我的 “this” 指南 以了解关于这个特定变量的所有细节。 函数可以使用 this 值进行许多不同的用例。问题在于它由环境给出,并且不能从外部改变,除非使用 call() 或 apply()。 当使用这些方法时,您可以传入一个额外的对象,该对象将在调用的函数中用作 this。 这两个函数执行相同的操作,但有一个区别。在 call() 中,您可以将函数参数作为逗号分隔的参数列表传递,可以使用任意数量的参数,而在 apply() 中,您传递一个包含参数的单个数组: const car = { brand: 'Ford', model: 'Fiesta' } const drive = function(from, to, kms) { console.log(`驾驶我的汽车,一辆${this.brand} ${this.model},从 ${from} 开往 ${to},行驶 ${kms} 公里`) } drive.call(car, '米兰', '罗马', 568) drive.apply(car, ['米兰', '罗马', 568]) 请注意,当使用 箭头函数 时,this 不被绑定,因此此方法仅适用于常规函数。

在 JavaScript 中使用 let vs const

let 和 const,該選擇哪一個呢? 在 JavaScript 中,我們通常使用兩個關鍵字來聲明變量:let 和 const。 什麼時候該使用其中之一? 我總是會首選使用 const。 為什麼呢? 因為 const 保證變量的值無法被重新賦值。 在編程中,我總是認為能給我帶來最小風險的選項是最好的。 我們有大量可能引發問題的東西。 你給予某個事物的權限越大,你就需要承擔更多的責任。 而我們通常並不希望如此。 當然,這是有爭議的,對於我來說,我不希望那樣就足夠了。 如果我使用 let 來聲明變量,我就允許它可以被重新賦值: let number = 0 number = 1 在某些情況下,這是必要的。 如果我希望變量可以被重新賦值,那麼 let 是完美的選擇。 但在80%的情況下,我甚至不希望這個選項存在。我希望編譯器(在 JavaScript 的情況下是解釋器)給我一個錯誤。 這就是為什麼我在聲明變量時總是首選 const,只有在需要允許重新賦值時才切換到 let。

在 JavaScript 中使用鏈式方法調用

在 JavaScript 中,有時我們可以使用鏈式方法調用,像這樣: car.start().drive() 這樣做非常方便。 相比於這樣寫: car.start() car.drive() 我們可以將其簡化為一行。 這是可能的,只要每個方法都返回對象本身。換句話說,實現必須類似於這樣: const car = { start: function() { console.log('start') return this }, drive: function() { console.log('drive') return this } } 需要注意的是,你不能使用箭頭函數,因為箭頭函數中的 this 不會綁定到對象實例。 我喜歡始終使用箭頭函數,這是其中一種不能使用箭頭函數的情況。 當你不從方法返回一組值時,鏈式方法調用非常有用,否則你顯然需要將方法調用賦值給變量,而鏈式調用是不可能的: const result = car.start() if (result) { car.drive() }

在 JavaScript 中如何在循環中使用 await

下面是如何使用 for..of 循環來迭代一個數組並在循環內部使用 await: const fun = (prop) => { return new Promise(resolve => { setTimeout(() => resolve(`done ${prop}`), 1000); }) } const go = async () => { const list = [1, 2, 3] for (const prop of list) { console.log(prop) console.log(await fun(prop)) } console.log('done all') } go() 需要將循環放置在一個 async 函數中,然後才能使用 await,循環會停止迭代,直到等待的 Promise 解決為止。 您也可以使用 for..in 循環來迭代對象: const fun = (prop) => { return new Promise(resolve => { setTimeout(() => resolve(`done ${prop}`), 1000); }) } const go = async () => { const obj = { a: 1, b: 2, c: 3 }; for (const prop in obj) { console....

在 JavaScript 中如何生成 slug

我使用的一段代碼將字符串生成 slug 的方法 export function slugify(str) { // 去除字符串頭尾的空格 str = str.trim() // 將字符串轉換為小寫 str = str.toLowerCase() // 移除重音符號,將 ñ 替換為 n,等等 str = str.normalize('NFD').replace(/[\u0300-\u036f]/g, '') // 移除無效字符 str = str.replace(/[^a-z0-9 -]/g, '') // 將空格替換為連字符 str = str.replace(/\s+/g, '-') // 合併連續的連字符 str = str.replace(/-+/g, '-') return str }

在 JavaScript 中如何获取 CSS 属性的值

假设您想要在网页中获取 CSS 属性的值,其中该属性是使用样式表设置的。您可以如何做到这一点呢? 假设您想要在网页中获取 CSS 属性的值,其中该属性是使用样式表设置的。 元素的 style 属性不会返回它,因为它仅列出内联样式或动态设置的 CSS 属性。 而不是外部样式表中定义的属性。 那么,您该怎么做呢?可以使用 getComputedStyle(),它是一个全局函数: const element = document.querySelector('.my-element') const style = getComputedStyle(element) style.backgroundColor // RGB 值