深入理解TypeScript-1

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

編譯上下文

用來(lái)給文件分組虎眨,告訴 TypeScript 哪些文件是有效的傅瞻,哪些是無(wú)效的亲澡。定義這種邏輯分組沥割,一個(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": [],                             // 指定要包含在編譯中的庫(kù)文件
        "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": "./",                       // 用來(lái)控制輸出目錄結(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 語(yǔ)句的 fallthrough 錯(cuò)誤似将。(即,不允許 switch 的 case 語(yǔ)句貫穿)

        /* 模塊解析選項(xiàng) */
        "moduleResolution": "node",            // 選擇模塊解析策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)
        "baseUrl": "./",                       // 用于解析非相對(duì)模塊名稱的基目錄
        "paths": {},                           // 模塊名到基于 baseUrl 的路徑映射的列表
        "rootDirs": [],                        // 根文件夾列表蚀苛,其組合內(nèi)容表示項(xiàng)目運(yùn)行時(shí)的結(jié)構(gòu)內(nèi)容
        "typeRoots": [],                       // 包含類型聲明的文件列表
        "types": [],                           // 需要包含的類型聲明文件名列表
        "allowSyntheticDefaultImports": true,  // 允許從沒(méi)有設(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 支持對(duì) TypeScript 的即時(shí)編譯既峡。但是署恍,如果你想在使用 tsconfig.json 時(shí)從命令行手動(dòng)運(yùn)行 TypeScript 編譯器,你可以通過(guò)以下方式:

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

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

聲明空間

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

類型聲明空間

類型聲明空間包含用來(lái)當(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)樗鼪](méi)有定義在變量聲明空間中:

    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è)類來(lái)當(dāng)做變量傳遞時(shí)大年。

WARNING

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

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

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

提示 cannot find name 的原因是,名稱 foo 沒(méi)有定義在類型聲明空間里赢底。

模塊

全局模塊

默認(rèn)情況下失都,當(dāng)你開(kāi)始在一個(gè)新的 TypeScript 文件中寫(xiě)下代碼時(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 文件的根級(jí)別位置含有 import 或者 export,它會(huì)在這個(gè)文件中創(chuàng)建一個(gè)本地的作用域延刘。因此漫试,我們需要把上文 foo.ts 改成如下方式(注意 export 用法):

    export const foo = 123;

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

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

如果你想在 bar.ts 里使用來(lái)自 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)大的能力和可用性歧匈。在這里割笙,我們來(lái)討論它的能力以及一些用法。

澄清:commonjs, amd, es modules, others

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

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

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

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

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

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

這很酷虏等,接下來(lái),讓我們看看 ES 模塊語(yǔ)法适肠。

TIP

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

ES 模塊語(yǔ)法

  • 使用 export 關(guān)鍵字導(dǎo)出一個(gè)變量(或者類型):
    // foo.ts
    export const someVar = 123;
    export type someType = { foo: string;
    };
  • export 的寫(xiě)法除了上面這樣,還有另外一種:
    // 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è)輸出值侯养,還可以使用整體加載敦跌,即用星號(hào)(*)指定一個(gè)對(duì)象,所有輸出值都加載在這個(gè)對(duì)象上面:
    // bar.ts
    import * as foo from './foo';
    // 你可以使用 `foo.someVar` 和 `foo.someType` 以及其他任何從 `foo` 導(dǎo)出的變量或者類型
  • 僅導(dǎo)入模塊:
    import 'core-js'; // 一個(gè)普通的 polyfill 庫(kù)
  • 從其他模塊導(dǎo)入后整體導(dǎo)出:
    export * from './foo';
  • 從其他模塊導(dǎo)入后逛揩,部分導(dǎo)出:
    export { someVar } from './foo';
  • 通過(guò)重命名柠傍,部分導(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)出的語(yǔ)法:

  • 使用 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' 語(yǔ)法(你可以根據(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)開(kāi)啟。

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

  • 相對(duì)模塊路徑(路徑以 . 開(kāi)頭,例如:./someFile 或者 ../../someFolder/someFile 等)嘲碧;
  • 其他動(dòng)態(tài)查找模塊(如:core-js稻励,typestylereact 或者甚至是 react/core 等)愈涩。

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

TIP

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

相對(duì)模塊路徑

這很簡(jiǎn)單煤篙,僅僅是按照相對(duì)路徑:

  • 如果文件 bar.ts 中含有 import * as foo from './foo'foo 文件所存在的地方必須是相同文件夾下毁腿;
  • 如果文件 bar.ts 中含有 import * as foo from '../foo'辑奈,foo 文件所存在的地方必須是上一級(jí)目錄;
  • 如果文件 bar.ts 中含有 import * as foo from '../someFolder/foo'已烤,foo 文件所在的文件夾 someFolder 必須與 bar.ts 所在文件夾在相同的目錄下鸠窗。

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

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

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

  • 當(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 的文件存在溶浴,那么就歡呼乍迄!

從文件類型上來(lái)說(shuō),我實(shí)際上是指 .ts士败, .d.ts 或者 .js

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

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

在你的項(xiàng)目里谅将,你可以通過(guò) declare module 'somePath' 來(lái)聲明一個(gè)全局模塊的方式漾狼,用來(lái)解決查找模塊路徑的問(wèn)題:

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

接著:

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

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

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

    import foo = require('foo');

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

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

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

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

例子 1

    import foo = require('foo');

將會(huì)編譯成 JavaScript:

這是正確的吉懊,一個(gè)沒(méi)有被使用的空文件庐橙。

例子 2

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

將會(huì)被編譯成:

    let bar;

這是因?yàn)?foo (或者其他任何屬性如:foo.bas)沒(méi)有被當(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测萎,原始的加載僅僅用來(lái)做類型注解 const _foo: typeof foo = require('foo'); // 現(xiàn)在亡电,你可以使用 `_foo` 替代 `foo` 來(lái)做為一個(gè)變量使用
    }

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

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

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

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

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

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

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

當(dāng)你加載一個(gè)模塊,只是想引入其附加的作用(如:模塊可能會(huì)注冊(cè)一些像 CodeMirror addons)時(shí)膀曾,然而县爬,如果你僅僅是 import/require (導(dǎo)入)一些并沒(méi)有與你的模塊或者模塊加載器有任何依賴的 JavaScript 代碼,(如:webpack)添谊,經(jīng)過(guò) TypeScript 編譯后财喳,這些將會(huì)被完全忽視。在這種情況下斩狱,你可以使用一個(gè) ensureImport 變量耳高,來(lái)確保編譯的 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 文件陆蟆,用來(lái)將一些接口或者類型放入全局命名空間里,這些定義的接口和類型能在你的所有 TypeScript 代碼里使用惋增。

TIP

對(duì)于任何需要編譯成 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" 能讓你快速開(kāi)始。

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末壶冒,一起剝皮案震驚了整個(gè)濱河市缕题,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌胖腾,老刑警劉巖烟零,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異咸作,居然都是意外死亡锨阿,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門记罚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)墅诡,“玉大人,你說(shuō)我怎么就攤上這事桐智∧┰纾” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵说庭,是天一觀的道長(zhǎng)然磷。 經(jīng)常有香客問(wèn)我,道長(zhǎng)口渔,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任穿撮,我火速辦了婚禮缺脉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘悦穿。我一直安慰自己攻礼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布栗柒。 她就那樣靜靜地躺著礁扮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瞬沦。 梳的紋絲不亂的頭發(fā)上太伊,一...
    開(kāi)封第一講書(shū)人閱讀 49,111評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音逛钻,去河邊找鬼僚焦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛曙痘,可吹牛的內(nèi)容都是我干的芳悲。 我是一名探鬼主播立肘,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼名扛!你這毒婦竟也來(lái)了谅年?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤肮韧,失蹤者是張志新(化名)和其女友劉穎融蹂,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體惹苗,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡殿较,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了桩蓉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片淋纲。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖院究,靈堂內(nèi)的尸體忽然破棺而出洽瞬,到底是詐尸還是另有隱情,我是刑警寧澤业汰,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布伙窃,位于F島的核電站,受9級(jí)特大地震影響样漆,放射性物質(zhì)發(fā)生泄漏为障。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一放祟、第九天 我趴在偏房一處隱蔽的房頂上張望鳍怨。 院中可真熱鬧,春花似錦跪妥、人聲如沸鞋喇。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)侦香。三九已至,卻和暖如春纽疟,著一層夾襖步出監(jiān)牢的瞬間罐韩,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工污朽, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留伴逸,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像错蝴,于是被迫代替她去往敵國(guó)和親洲愤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

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