深入理解TypeScript-1

這一章主要總結(jié)TypeScript的用法和項(xiàng)目常用配置

編譯上下文

用來給文件分組,告訴 TypeScript 哪些文件是有效的,哪些是無效的。定義這種邏輯分組,一個(gè)比較好的方式是使用 tsconfig.json 文件。

常用配置一覽

    {
      "compilerOptions": {

        /* 基本選項(xiàng) */
        "target": "es5",                       // 指定 ECMAScript 目標(biāo)版本: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'
        "module": "commonjs",                  // 指定使用模塊: 'commonjs', 'amd', 'system', 'umd' or 'es2015'
        "lib": [],                             // 指定要包含在編譯中的庫文件
        "allowJs": true,                       // 允許編譯 javascript 文件
        "checkJs": true,                       // 報(bào)告 javascript 文件中的錯(cuò)誤
        "jsx": "preserve",                     // 指定 jsx 代碼的生成: 'preserve', 'react-native', or 'react'
        "declaration": true,                   // 生成相應(yīng)的 '.d.ts' 文件
        "sourceMap": true,                     // 生成相應(yīng)的 '.map' 文件
        "outFile": "./",                       // 將輸出文件合并為一個(gè)文件
        "outDir": "./",                        // 指定輸出目錄
        "rootDir": "./",                       // 用來控制輸出目錄結(jié)構(gòu) --outDir.
        "removeComments": true,                // 刪除編譯后的所有的注釋
        "noEmit": true,                        // 不生成輸出文件
        "importHelpers": true,                 // 從 tslib 導(dǎo)入輔助工具函數(shù)
        "isolatedModules": true,               // 將每個(gè)文件做為單獨(dú)的模塊 (與 'ts.transpileModule' 類似).

        /* 嚴(yán)格的類型檢查選項(xiàng) */
        "strict": true,                        // 啟用所有嚴(yán)格類型檢查選項(xiàng)
        "noImplicitAny": true,                 // 在表達(dá)式和聲明上有隱含的 any類型時(shí)報(bào)錯(cuò)
        "strictNullChecks": true,              // 啟用嚴(yán)格的 null 檢查
        "noImplicitThis": true,                // 當(dāng) this 表達(dá)式值為 any 類型的時(shí)候,生成一個(gè)錯(cuò)誤
        "alwaysStrict": true,                  // 以嚴(yán)格模式檢查每個(gè)模塊,并在每個(gè)文件里加入 'use strict'

        /* 額外的檢查 */
        "noUnusedLocals": true,                // 有未使用的變量時(shí),拋出錯(cuò)誤
        "noUnusedParameters": true,            // 有未使用的參數(shù)時(shí),拋出錯(cuò)誤
        "noImplicitReturns": true,             // 并不是所有函數(shù)里的代碼都有返回值時(shí),拋出錯(cuò)誤
        "noFallthroughCasesInSwitch": true,    // 報(bào)告 switch 語句的 fallthrough 錯(cuò)誤。(即,不允許 switch 的 case 語句貫穿)

        /* 模塊解析選項(xiàng) */
        "moduleResolution": "node",            // 選擇模塊解析策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)
        "baseUrl": "./",                       // 用于解析非相對模塊名稱的基目錄
        "paths": {},                           // 模塊名到基于 baseUrl 的路徑映射的列表
        "rootDirs": [],                        // 根文件夾列表,其組合內(nèi)容表示項(xiàng)目運(yùn)行時(shí)的結(jié)構(gòu)內(nèi)容
        "typeRoots": [],                       // 包含類型聲明的文件列表
        "types": [],                           // 需要包含的類型聲明文件名列表
        "allowSyntheticDefaultImports": true,  // 允許從沒有設(shè)置默認(rèn)導(dǎo)出的模塊中默認(rèn)導(dǎo)入。

        /* Source Map Options */
        "sourceRoot": "./",                    // 指定調(diào)試器應(yīng)該找到 TypeScript 文件而不是源文件的位置
        "mapRoot": "./",                       // 指定調(diào)試器應(yīng)該找到映射文件而不是生成文件的位置
        "inlineSourceMap": true,               // 生成單個(gè) soucemaps 文件,而不是將 sourcemaps 生成不同的文件
        "inlineSources": true,                 // 將代碼與 sourcemaps 生成到一個(gè)文件中,要求同時(shí)設(shè)置了 --inlineSourceMap 或 --sourceMap 屬性

        /* 其他選項(xiàng) */
        "experimentalDecorators": true,        // 啟用裝飾器
        "emitDecoratorMetadata": true          // 為裝飾器提供元數(shù)據(jù)的支持
      }
    }

TypeScript 編譯

好的 IDE 支持對 TypeScript 的即時(shí)編譯。但是,如果你想在使用 tsconfig.json 時(shí)從命令行手動(dòng)運(yùn)行 TypeScript 編譯器,你可以通過以下方式:

  • 運(yùn)行 tsc,它會(huì)在當(dāng)前目錄或者是父級目錄尋找 tsconfig.json 文件。
  • 運(yùn)行 tsc -p ./path-to-project-directory 。當(dāng)然,這個(gè)路徑可以是絕對路徑,也可以是相對于當(dāng)前目錄的相對路徑。

你甚至可以使用 tsc -w 來啟用 TypeScript 編譯器的觀測模式,在檢測到文件改動(dòng)之后,它將重新編譯。

聲明空間

在 TypeScript 里存在兩種聲明空間:類型聲明空間變量聲明空間。我將會(huì)在下文中和大家討論這兩個(gè)概念。

類型聲明空間

類型聲明空間包含用來當(dāng)做類型注解的內(nèi)容,例如以下的一些類型聲明:

    class Foo {};
    interface Bar {};
    type Bas = {};

你可以將 Foo, Bar, Bas 做為類型注解使用,例如:

    let foo: Foo;
    let bar: Bar;
    let bas: Bas;

注意,盡管你定義了 interface Bar,你并不能夠?qū)⑺鰹橐粋€(gè)變量使用,因?yàn)樗鼪]有定義在變量聲明空間中:

    interface Bar {}
    const bar = Bar; // Error: "cannot find name 'Bar'"

提示 cannot find name 'Bar' 的原因是名稱 Bar 并未定義在變量聲明空間。這將帶領(lǐng)我們進(jìn)入下一個(gè)主題 "變量聲明空間"。

變量聲明空間

變量聲明空間包含可用作變量的內(nèi)容,在上文中 Class Foo 提供了一個(gè)類型 Foo 到類型聲明空間,此外它同樣提供了一個(gè)變量 Foo 到變量聲明空間,如下所示:

    class Foo {}
    const someVar = Foo;
    const someOtherVar = 123;

這很棒,尤其是當(dāng)你想把一個(gè)類來當(dāng)做變量傳遞時(shí)。

WARNING

我們并不能使用一些像 interface 定義的內(nèi)容,來當(dāng)做變量使用。

與此相似,一些像你用 var 聲明的變量,也僅能在變量聲明空間使用,不能用作類型注解。

    const foo = 123;
    let bar: foo; // ERROR: "cannot find name 'foo'"

提示 cannot find name 的原因是,名稱 foo 沒有定義在類型聲明空間里。

模塊

全局模塊

默認(rèn)情況下,當(dāng)你開始在一個(gè)新的 TypeScript 文件中寫下代碼時(shí),它處于全局命名空間中。如在 foo.ts 里的以下代碼:

    const foo = 123;

如果你在相同的項(xiàng)目里創(chuàng)建了一個(gè)新的文件 bar.ts,TypeScript 類型系統(tǒng)將會(huì)允許你使用變量 foo,就好像它在全局可用一樣:

    const bar = foo; // allowed

毋庸置疑,使用全局變量空間是危險(xiǎn)的,因?yàn)樗鼤?huì)與文件內(nèi)的代碼命名沖突。我們推薦使用下文中將要提到的文件模塊。

文件模塊

它也被稱為外部模塊。如果在你的 TypeScript 文件的根級別位置含有 import 或者 export,它會(huì)在這個(gè)文件中創(chuàng)建一個(gè)本地的作用域。因此,我們需要把上文 foo.ts 改成如下方式(注意 export 用法):

    export const foo = 123;

在全局命名空間里,我們不再有 foo,這可以通過創(chuàng)建一個(gè)新文件 bar.ts 來證明:

    const bar = foo; // ERROR: "cannot find name 'foo'"

如果你想在 bar.ts 里使用來自 foo.ts 的內(nèi)容,你必須顯式導(dǎo)入它,更新 bar.ts 如下所示:

    import { foo } from './foo';
    const bar = foo; // allow

bar.ts 文件里使用 import,不但允許你使用從其他文件導(dǎo)入的內(nèi)容,而且它會(huì)將此文件 bar.ts 標(biāo)記為一個(gè)模塊,文件內(nèi)定義的聲明也不會(huì)污染全局命名空間。

文件模塊詳情

文件模塊擁有強(qiáng)大的能力和可用性。在這里,我們來討論它的能力以及一些用法。

澄清:commonjs, amd, es modules, others

首先,我們需要澄清這些模塊系統(tǒng)的不一致性。我將會(huì)提供給你我當(dāng)前的建議,以及消除一些顧慮。

你可以根據(jù)不同的 module 選項(xiàng)來把 TypeScript 編譯成不同的 JavaScript 模塊類型,這有一些你可以忽略的:

  • AMD:不要使用它,它僅能在瀏覽器工作;
  • SystemJS:這是一個(gè)好的實(shí)驗(yàn),已經(jīng)被 ES 模塊替代;
  • ES 模塊:它并沒有準(zhǔn)備好。

使用 module: commonjs 選項(xiàng)來替代這些模式,這會(huì)是一個(gè)好的主意。

怎么書寫 TypeScript 模塊,這也是一件讓人困惑的事。在今天我們應(yīng)該這么做:

  • import foo = require('foo') 例如: import/require 使用 ES 模塊語法。

這很酷,接下來,讓我們看看 ES 模塊語法。

TIP

使用 module: commonjs 選項(xiàng)以及使用 ES 模塊語法導(dǎo)入導(dǎo)出其他模塊。

ES 模塊語法

  • 使用 export 關(guān)鍵字導(dǎo)出一個(gè)變量(或者類型):
    // foo.ts
    export const someVar = 123;
    export type someType = { foo: string;
    };
  • export 的寫法除了上面這樣,還有另外一種:
    // foo.ts
    const someVar = 123;
    type someType = { type: string;
    };
    export { someVar, someType };
  • 你也可以重命名變量導(dǎo)出:
    // foo.ts
    const someVar = 123;
    export { someVar as aDifferentName };
  • 使用 import 關(guān)鍵字導(dǎo)入一個(gè)變量或者是一個(gè)類型:
    // bar.ts
    import { someVar, someType } from './foo';
  • 重命名導(dǎo)入變量或者類型:
    // bar.ts
    import { someVar as aDifferentName } from './foo';
  • 除了指定加載某個(gè)輸出值,還可以使用整體加載,即用星號(*)指定一個(gè)對象,所有輸出值都加載在這個(gè)對象上面:
    // bar.ts
    import * as foo from './foo';
    // 你可以使用 `foo.someVar` 和 `foo.someType` 以及其他任何從 `foo` 導(dǎo)出的變量或者類型
  • 僅導(dǎo)入模塊:
    import 'core-js'; // 一個(gè)普通的 polyfill 庫
  • 從其他模塊導(dǎo)入后整體導(dǎo)出:
    export * from './foo';
  • 從其他模塊導(dǎo)入后,部分導(dǎo)出:
    export { someVar } from './foo';
  • 通過重命名,部分導(dǎo)出從另一個(gè)模塊導(dǎo)入的項(xiàng)目:
    export { someVar as aDifferentName } from './foo';

默認(rèn)導(dǎo)入/導(dǎo)出

我并不喜歡用默認(rèn)導(dǎo)出,雖然有默認(rèn)導(dǎo)出的語法:

  • 使用 export default
    • 在一個(gè)變量之前(不需要使用 let/const/var);
    • 在一個(gè)函數(shù)之前;
    • 在一個(gè)類之前。
    // some var
    export default (someVar = 123);
    // some function
    export default function someFunction() {}
    // some class
    export default class someClass {}
  • 導(dǎo)入使用 import someName from 'someModule' 語法(你可以根據(jù)需要為導(dǎo)入命名):
    import someLocalNameForThisFile from './foo';

模塊路徑

TIP

假設(shè)你使用 moduleResolution: node 選項(xiàng)。這個(gè)選項(xiàng)應(yīng)該在你 TypeScript 配置文件里。如果你使用了 module: commonjs 選項(xiàng), moduleResolution: node 將會(huì)默認(rèn)開啟。

這里存在兩種不同截然不同的模塊,它們是由導(dǎo)入語句中的不同的路徑寫法所引起的(例如:import foo from 'THIS IS THE PATH SECTION')。

  • 相對模塊路徑(路徑以 . 開頭,例如:./someFile 或者 ../../someFolder/someFile 等);
  • 其他動(dòng)態(tài)查找模塊(如:core-jstypestylereact 或者甚至是 react/core 等)。

它們的主要區(qū)別來自于系統(tǒng)如何解析模塊。

TIP

我將會(huì)使用一個(gè)概念性術(shù)語,place -- 將在提及查找模式后解釋它。

相對模塊路徑

這很簡單,僅僅是按照相對路徑:

  • 如果文件 bar.ts 中含有 import * as foo from './foo'foo 文件所存在的地方必須是相同文件夾下;
  • 如果文件 bar.ts 中含有 import * as foo from '../foo'foo 文件所存在的地方必須是上一級目錄;
  • 如果文件 bar.ts 中含有 import * as foo from '../someFolder/foo'foo 文件所在的文件夾 someFolder 必須與 bar.ts 所在文件夾在相同的目錄下。

或者,你還可以想想其他相對路徑導(dǎo)入的情景。??

動(dòng)態(tài)查找

當(dāng)導(dǎo)入路徑不是相對路徑時(shí),模塊解析將會(huì)模仿 Node 模塊解析策略,以下我將給出一個(gè)簡單例子:

  • 當(dāng)你使用 import * as foo from 'foo',將會(huì)按如下順序查找模塊:
    • ./node_modules/foo
    • ../node_modules/foo
    • ../../node_modules/foo
    • 直到系統(tǒng)的根目錄
  • 當(dāng)你使用 import * as foo from 'something/foo',將會(huì)按照如下順序查找內(nèi)容
    • ./node_modules/something/foo
    • ../node_modules/something/foo
    • ../../node_modules/something/foo
    • 直到系統(tǒng)的根目錄

什么是 place

當(dāng)我提及被檢查的 place 時(shí),我想表達(dá)的是在這個(gè) place,TypeScript 將會(huì)檢查以下內(nèi)容(例如一個(gè) foo 的位置):

  • 如果這個(gè) place 表示一個(gè)文件,如:foo.ts,歡呼!
  • 否則,如果這個(gè) place 是一個(gè)文件夾,并且存在一個(gè)文件 foo/index.ts,歡呼!
  • 否則,如果這個(gè) place 是一個(gè)文件夾,并且存在一個(gè) foo/package.json 文件,在該文件中指定 types 的文件存在,那么就歡呼!
  • 否則,如果這個(gè) place 是一個(gè)文件夾,并且存在一個(gè) package.json 文件,在該文件中指定 main 的文件存在,那么就歡呼!

從文件類型上來說,我實(shí)際上是指 .ts.d.ts 或者 .js

就是這樣,現(xiàn)在你已經(jīng)是一個(gè)模塊查找專家(這并不是一個(gè)小小的成功)。

重寫類型的動(dòng)態(tài)查找

在你的項(xiàng)目里,你可以通過 declare module 'somePath' 來聲明一個(gè)全局模塊的方式,用來解決查找模塊路徑的問題:

    // globals.d.ts
    declare module 'foo' { // some variable declarations export var bar: number;
    }

接著:

    // anyOtherTsFileInYourProject.ts
    import * as foo from 'foo';
    // TypeScript 將假設(shè)(在沒有做其他查找的情況下)
    // foo 是 { bar: number }

import/require 僅僅是導(dǎo)入類型

以下導(dǎo)入語法:

    import foo = require('foo');

它實(shí)際上只做了兩件事:

  • 導(dǎo)入 foo 模塊的所有類型信息;
  • 確定 foo 模塊運(yùn)行時(shí)的依賴關(guān)系。

你可以選擇僅加載類型信息,而沒有運(yùn)行時(shí)的依賴關(guān)系。在繼續(xù)之前,你可能需要重新閱讀本書的 聲明空間部分 部分。

如果你沒有把導(dǎo)入的名稱當(dāng)做變量聲明空間來用,在編譯成 JavaScript 時(shí),導(dǎo)入的模塊將會(huì)被完全移除。這有一些較好的例子,當(dāng)你了解了它們之后,我們將會(huì)給出一些使用例子。

例子 1

    import foo = require('foo');

將會(huì)編譯成 JavaScript:

這是正確的,一個(gè)沒有被使用的空文件。

例子 2

    import foo = require('foo');
    var bar: foo;

將會(huì)被編譯成:

    let bar;

這是因?yàn)?foo (或者其他任何屬性如:foo.bas)沒有被當(dāng)做一個(gè)變量使用。

例子 3

    import foo = require('foo');
    const bar = foo;

將會(huì)被編譯成(假設(shè)是 commonjs):

    const foo = require('foo');
    const bar = foo;

這是因?yàn)?foo 被當(dāng)做變量使用了。

使用例子:懶加載

類型推斷需要提前完成,這意味著,如果你想在 bar 文件里,使用從其他文件 foo 導(dǎo)出的類型,你將不得不這么做:

    import foo = require('foo');
    let bar: foo.SomeType;

然而,在某些情景下,你只想在需要時(shí)加載模塊 foo,此時(shí)你需要僅在類型注解中使用導(dǎo)入的模塊名稱,而不是在變量中使用。在編譯成 JavaScript 式,這些將會(huì)被移除。接著,你可以手動(dòng)導(dǎo)入你需要的模塊。

做為一個(gè)例子,考慮以下基于 commonjs 的代碼,我們僅在一個(gè)函數(shù)內(nèi)導(dǎo)入 foo 模塊:

    import foo = require('foo');
    export function loadFoo() { // 這是懶加載 foo,原始的加載僅僅用來做類型注解 const _foo: typeof foo = require('foo'); // 現(xiàn)在,你可以使用 `_foo` 替代 `foo` 來做為一個(gè)變量使用
    }

一個(gè)同樣簡單的 amd 模塊(使用 requirejs):

    import foo = require('foo');
    export function loadFoo() { // 這是懶加載 foo,原始的加載僅僅用來做類型注解 require(['foo'], (_foo: typeof foo) => { // 現(xiàn)在,你可以使用 `_foo` 替代 `foo` 來做為一個(gè)變量使用 });
    }

這些通常在以下情景使用:

  • 在 web app 里, 當(dāng)你在特定路由上加載 JavaScript 時(shí);
  • 在 node 應(yīng)用里,當(dāng)你只想加載特定模塊,用來加快啟動(dòng)速度時(shí)。

使用例子:打破循環(huán)依賴

類似于懶加載的使用用例,某些模塊加載器(commonjs/node 和 amd/requirejs)不能很好的處理循環(huán)依賴。在這種情況下,一方面我們使用延遲加載代碼,并在另一方面預(yù)先加載模塊時(shí)很實(shí)用的。

使用例子:確保導(dǎo)入

當(dāng)你加載一個(gè)模塊,只是想引入其附加的作用(如:模塊可能會(huì)注冊一些像 CodeMirror addons)時(shí),然而,如果你僅僅是 import/require (導(dǎo)入)一些并沒有與你的模塊或者模塊加載器有任何依賴的 JavaScript 代碼,(如:webpack),經(jīng)過 TypeScript 編譯后,這些將會(huì)被完全忽視。在這種情況下,你可以使用一個(gè) ensureImport 變量,來確保編譯的 JavaScript 依賴與模塊。如:

    import foo = require('./foo');
    import bar = require('./bar');
    import bas = require('./bas');
    const ensureImport: any = foo || bar || bas;

globals.d.ts

在上文中,當(dāng)我們討論文件模塊時(shí),比較了全局變量與文件模塊,并且我們推薦使用基于文件的模塊,而不是選擇污染全局命名空間。

然而,如果你的團(tuán)隊(duì)里有 TypeScript 初學(xué)者,你可以提供他們一個(gè) globals.d.ts 文件,用來將一些接口或者類型放入全局命名空間里,這些定義的接口和類型能在你的所有 TypeScript 代碼里使用。

TIP

對于任何需要編譯成 JavaScript 代碼,我們強(qiáng)烈建議你放入文件模塊里。

  • globals.d.ts 是一種擴(kuò)充 lib.d.ts 很好的方式,如果你需要。
  • 當(dāng)你從 TS 遷移到 JS 時(shí),定義 declare module "some-library-you-dont-care-to-get-defs-for" 能讓你快速開始。

轉(zhuǎn)自 https://jkchao.github.io/typescript-book-chinese/project/modules.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,622評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,716評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,746評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,991評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,706評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,036評論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,029評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,203評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,725評論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,451評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,677評論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,161評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,857評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,266評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,606評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,407評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,643評論 2 380

推薦閱讀更多精彩內(nèi)容