Vite study

總覽

Vite(法語意為 "快速的"曙聂,發(fā)音 /vit/[圖片上傳失敗...(image-7771a7-1647833168481)] 廊镜,發(fā)音同 "veet")是一種新型前端構(gòu)建工具榜聂,能夠顯著提升前端開發(fā)體驗(yàn)。它主要由兩部分組成:

  • 一個(gè)開發(fā)服務(wù)器陌凳,它基于 原生 ES 模塊 提供了 豐富的內(nèi)建功能剥懒,如速度快到驚人的 模塊熱更新(HMR)

  • 一套構(gòu)建指令合敦,它使用 Rollup 打包你的代碼初橘,并且它是預(yù)配置的,可輸出用于生產(chǎn)環(huán)境的高度優(yōu)化過的靜態(tài)資源充岛。

Vite 意在提供開箱即用的配置保檐,同時(shí)它的 插件 APIJavaScript API 帶來了高度的可擴(kuò)展性,并有完整的類型支持裸准。
你可以在 為什么選 Vite 中了解更多關(guān)于項(xiàng)目的設(shè)計(jì)初衷。


Vue 第一優(yōu)先級支持

Vite 最初是作為 Vue.js 開發(fā)工具的未來基礎(chǔ)而創(chuàng)建的赔硫。盡管 Vite 2.0 版本完全不依賴于任何框架炒俱,但官方 Vue 插件仍然對 Vue 的單文件組件格式提供了第一優(yōu)先級的支持,涵蓋了所有高級特性爪膊,如模板資源引用解析权悟、<script setup><style module>推盛,自定義塊等等峦阁。除此之外,Vite 還對 Vue 單文件組件提供了細(xì)粒度的 HMR耘成。舉個(gè)例子榔昔,更新一個(gè)單文件組件的 <template><style> 會(huì)執(zhí)行不重置其狀態(tài)的熱更新驹闰。

瀏覽器支持


搭建第一個(gè) Vite 項(xiàng)目

兼容性注意, Vite 需要 Node.js 版本 >= 12.0.0嘹朗。

### npm 7+, 需要額外的雙橫線:
npm init vite@latest my-vue-app -- --template vue

查看 create-vite 以獲取每個(gè)模板的更多細(xì)節(jié):vanillavanilla-ts诵肛,vue屹培,vue-tsreact怔檩,react-ts褪秀,preactpreact-ts薛训,lit媒吗,lit-tssvelte许蓖,svelte-ts蝴猪。


index.html 與項(xiàng)目根目錄

Vite 將 index.html 視為源碼和模塊圖的一部分。Vite 解析 <script type="module" src="..."> 膊爪,這個(gè)標(biāo)簽指向你的 JavaScript 源碼自阱。甚至內(nèi)聯(lián)引入 JavaScript 的 <script type="module"> 和引用 CSS 的 <link href> 也能利用 Vite 特有的功能被解析。另外米酬,index.html 中的 URL 將被自動(dòng)轉(zhuǎn)換沛豌,因此不再需要 %PUBLIC_URL% 占位符了。

Vite 也支持多個(gè) .html 作入口點(diǎn)的 多頁面應(yīng)用模式赃额。

指定替代根目錄

vite 以當(dāng)前工作目錄作為根目錄啟動(dòng)開發(fā)服務(wù)器加派。你也可以通過 vite serve some/sub/dir 來指定一個(gè)替代的根目錄。

在安裝了 Vite 的項(xiàng)目中跳芳,可以在 npm scripts 中使用 vite 可執(zhí)行文件芍锦,或者直接使用 npx vite 運(yùn)行它。下面是通過腳手架創(chuàng)建的 Vite 項(xiàng)目中默認(rèn)的 npm scripts:

### package.json
{
  "name": "vite-henrypt",
  "private": true,
  "version": "0.0.0",
  "scripts": {
    "dev": "vite",  # 啟動(dòng)開發(fā)服務(wù)器飞盆,別名:`vite dev`, `vite serve`
    "build": "vite build", # 為生產(chǎn)環(huán)境構(gòu)建產(chǎn)物
    "preview": "vite preview" # 本地預(yù)覽生產(chǎn)構(gòu)建產(chǎn)物
  },
  "dependencies": {
    "vue": "^3.2.25"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^2.2.0",
    "vite": "^2.8.0"
  }
}

可以指定額外的命令行選項(xiàng)娄琉,如 --port 或 --https。運(yùn)行 npx vite --help 獲得完整的命令行選項(xiàng)列表吓歇。

功能

對非衬跛基礎(chǔ)的使用來說,使用 Vite 開發(fā)和使用一個(gè)靜態(tài)文件服務(wù)器并沒有太大區(qū)別城看。然而女气,Vite 還通過原生 ESM 導(dǎo)入提供了許多主要用于打包場景的增強(qiáng)功能。

NPM 依賴解析和預(yù)構(gòu)建#

原生 ES 導(dǎo)入不支持下面這樣的裸模塊導(dǎo)入:import { add } from 'my-dep'
上面的代碼會(huì)在瀏覽器中拋出一個(gè)錯(cuò)誤测柠。Vite 將會(huì)檢測到所有被加載的源文件中的此類裸模塊導(dǎo)入炼鞠,并執(zhí)行以下操作:

  1. 預(yù)構(gòu)建 它們可以提高頁面加載速度缘滥,并將 CommonJS / UMD 轉(zhuǎn)換為 ESM 格式。預(yù)構(gòu)建這一步由 esbuild 執(zhí)行簇搅,這使得 Vite 的冷啟動(dòng)時(shí)間比任何基于 JavaScript 的打包器都要快得多完域。

  2. 重寫導(dǎo)入為合法的 URL,例如 /node_modules/.vite/my-dep.js?v=f3sf2ebd 以便瀏覽器能夠正確導(dǎo)入它們瘩将。

依賴是強(qiáng)緩存的

Vite 通過 HTTP 頭來緩存請求得到的依賴吟税,所以如果你想要編輯或調(diào)試一個(gè)依賴,請按照 這里 的步驟操作姿现。

模塊熱重載

Vite 提供了一套原生 ESM 的 HMR API肠仪。 具有 HMR 功能的框架可以利用該 API 提供即時(shí)、準(zhǔn)確的更新备典,而無需重新加載頁面或清除應(yīng)用程序狀態(tài)异旧。Vite 內(nèi)置了 HMR 到 Vue 單文件組件(SFC)React Fast Refresh 中。也通過 @prefresh/vite 對 Preact 實(shí)現(xiàn)了官方集成提佣。

注意吮蛹,你不需要手動(dòng)設(shè)置這些 —— 當(dāng)你通過 create-vite 創(chuàng)建應(yīng)用程序時(shí),所選模板已經(jīng)為你預(yù)先配置了這些拌屏。

TypeScript#

略過

Vue

Vite 為 Vue 提供第一優(yōu)先級支持:

JSX

略過

CSS

CSS 預(yù)處理器支持
Vite 為 Sass and Less 提供了更精細(xì)化的支持潮针,包括改進(jìn) @import 解析(可使用別名與 npm 依賴)和 提供 url() 內(nèi)聯(lián)引入與變基

導(dǎo)入 .css 文件將會(huì)把內(nèi)容插入到 <style> 標(biāo)簽中倚喂,同時(shí)也帶有 HMR 支持每篷。也能夠以字符串的形式檢索處理后的、作為其模塊默認(rèn)導(dǎo)出的 CSS端圈。

  1. @import 內(nèi)聯(lián)和變基
    Vite 通過 postcss-import 預(yù)配置支持了 CSS @import 內(nèi)聯(lián)焦读,Vite 的路徑別名也遵從 CSS @import。換句話說舱权,所有 CSS url() 引用矗晃,即使導(dǎo)入的文件在不同的目錄中,也總是自動(dòng)變基宴倍,以確保正確性张症。

  2. PostCSS
    如果項(xiàng)目包含有效的 PostCSS 配置 (任何受 postcss-load-config 支持的格式,例如 postcss.config.js)啊楚,它將會(huì)自動(dòng)應(yīng)用于所有已導(dǎo)入的 CSS吠冤。

  3. CSS Modules
    任何以 .module.css 為后綴名的 CSS 文件都被認(rèn)為是一個(gè) CSS modules 文件浑彰。

  4. CSS 預(yù)處理器
    由于 Vite 的目標(biāo)僅為現(xiàn)代瀏覽器恭理,因此建議使用原生 CSS 變量和實(shí)現(xiàn) CSSWG 草案的 PostCSS 插件(例如 postcss-nesting)來編寫簡單的、符合未來標(biāo)準(zhǔn)的 CSS郭变。

話雖如此颜价,但 Vite 也同時(shí)提供了對 .scss, .sass, .less, .styl.stylus 文件的內(nèi)置支持涯保。沒有必要為它們安裝特定的 Vite 插件,但必須安裝相應(yīng)的預(yù)處理器依賴:

# .scss and .sass
npm install -D sass

# .less
npm install -D less

# .styl and .stylus
npm install -D stylus

如果是用的是單文件組件周伦,可以通過 <style lang="sass">(或其他預(yù)處理器)自動(dòng)開啟夕春。


靜態(tài)資源處理

導(dǎo)入一個(gè)靜態(tài)資源會(huì)返回解析后的 URL:

import imgUrl from './img.png'
document.getElementById('hero-img').src = imgUrl

添加一些特殊的查詢參數(shù)可以更改資源被引入的方式:

// 顯式加載資源為一個(gè) URL
import assetAsURL from './asset.js?url'

// 以字符串形式加載資源
import assetAsString from './shader.glsl?raw'

// 加載為 Web Worker
import Worker from './worker.js?worker'

// 在構(gòu)建時(shí) Web Worker 內(nèi)聯(lián)為 base64 字符串
import InlineWorker from './worker.js?worker&inline'

更多細(xì)節(jié)請見 靜態(tài)資源處理

JSON

JSON 可以被直接導(dǎo)入 —— 同樣支持具名導(dǎo)入:

// 導(dǎo)入整個(gè)對象
import json from './example.json'
// 對一個(gè)根字段使用具名導(dǎo)入 —— 有效幫助 Tree Shaking专挪!
import { field } from './example.json'

Glob 導(dǎo)入

Vite 支持使用特殊的 import.meta.glob 函數(shù)從文件系統(tǒng)導(dǎo)入多個(gè)模塊:
const modules = import.meta.glob('./dir/*.js')
以上將會(huì)被轉(zhuǎn)譯為下面的樣子:

// vite 生成的代碼
const modules = {
  './dir/foo.js': () => import('./dir/foo.js'),
  './dir/bar.js': () => import('./dir/bar.js')
}

你可以遍歷 modules 對象的 key 值來訪問相應(yīng)的模塊:

for (const path in modules) {
  modules[path]().then((mod) => {
    console.log(path, mod)
  })
}

WebAssembly

預(yù)編譯的 .wasm 文件可以直接被導(dǎo)入 —— 默認(rèn)導(dǎo)出一個(gè)函數(shù)及志,返回值為所導(dǎo)出 wasm 實(shí)例對象的 Promise:...


Web Worker

一個(gè) web worker 腳本可以直接通過添加一個(gè) ?worker 或 ? shared worker 查詢參數(shù)來導(dǎo)入。默認(rèn)導(dǎo)出一個(gè)自定義的 worker 構(gòu)造器:

import MyWorker from './worker?worker'
const worker = new MyWorker()

注意寨腔,在開發(fā)過程中速侈,這依賴于瀏覽器原生支持,目前只在 Chrome 中適用迫卢,而在生產(chǎn)版本中倚搬,它已經(jīng)被編譯掉了。

構(gòu)建優(yōu)化

下面所羅列的功能會(huì)自動(dòng)應(yīng)用為構(gòu)建過程的一部分乾蛤,除非你想禁用它們每界,否則沒有必要顯式配置。

  1. CSS 代碼分割
  2. 預(yù)加載指令生成
  3. 異步 Chunk 加載優(yōu)化
    在無優(yōu)化的情境下家卖,當(dāng)異步 chunk A 被導(dǎo)入時(shí)眨层,瀏覽器將必須請求和解析 A,然后它才能弄清楚它也需要共用 chunk C篡九。這會(huì)導(dǎo)致額外的網(wǎng)絡(luò)往返:Entry ---> A ---> C
    Vite 將使用一個(gè)預(yù)加載步驟自動(dòng)重寫代碼谐岁,來分割動(dòng)態(tài)導(dǎo)入調(diào)用,以實(shí)現(xiàn)當(dāng) A 被請求時(shí)榛臼,C 也將 同時(shí) 被請求:Entry ---> (A + C)
    C 也可能有更深的導(dǎo)入伊佃,在未優(yōu)化的場景中,這會(huì)導(dǎo)致更多的網(wǎng)絡(luò)往返沛善。Vite 的優(yōu)化會(huì)跟蹤所有的直接導(dǎo)入航揉,無論導(dǎo)入的深度如何,都能夠完全消除不必要的往返金刁。

使用插件

Vite 可以使用插件進(jìn)行擴(kuò)展帅涂,這得益于 Rollup 優(yōu)秀的插件接口設(shè)計(jì)和一部分 Vite 獨(dú)有的額外選項(xiàng)。這意味著 Vite 用戶可以利用 Rollup 插件的強(qiáng)大生態(tài)系統(tǒng)尤蛮,同時(shí)根據(jù)需要也能夠擴(kuò)展開發(fā)服務(wù)器和 SSR 功能媳友。

添加一個(gè)插件

若要使用一個(gè)插件,需要將它添加到項(xiàng)目的 devDependencies 并在 vite.config.js 配置文件中的 plugins 數(shù)組中引入它产捞。例如醇锚,要想為傳統(tǒng)瀏覽器提供支持,可以按下面這樣使用官方插件 @vitejs/plugin-legacy
$ npm i -D @vitejs/plugin-legacy

// vite.config.js
import legacy from '@vitejs/plugin-legacy'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    legacy({
      targets: ['defaults', 'not IE 11']
    })
  ]
})

查找插件

查看 Plugins 章節(jié) 獲取官方插件信息。社區(qū)插件列表請參見 awesome-vite焊唬。而對于兼容的 Rollup 插件恋昼,請查看 Vite Rollup 插件 獲取一個(gè)帶使用說明的兼容 Rollup 官方插件列表,若列表中沒有找到赶促,則請參閱 Rollup 插件兼容性章節(jié)液肌。

你也可以使用此 npm Vite 插件搜索鏈接 來找到一些遵循了 推薦約定 的 Vite 插件,或者通過 npm Rollup 插件搜索鏈接 獲取 Rollup 插件鸥滨。

強(qiáng)制插件排序

為了與某些 Rollup 插件兼容嗦哆,可能需要強(qiáng)制執(zhí)行插件的順序,或者只在構(gòu)建時(shí)使用婿滓。這應(yīng)該是 Vite 插件的實(shí)現(xiàn)細(xì)節(jié)吝秕。可以使用 enforce 修飾符來強(qiáng)制插件的位置:

  • pre:在 Vite 核心插件之前調(diào)用該插件
  • 默認(rèn):在 Vite 核心插件之后調(diào)用該插件
  • post:在 Vite 構(gòu)建插件之后調(diào)用該插件
// vite.config.js
import image from '@rollup/plugin-image'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    {
      ...image(),
      enforce: 'pre'
    }
  ]
})

查看 Plugins API Guide 獲取細(xì)節(jié)信息空幻,并在 Vite Rollup 插件 兼容性列表中注意 enforce 標(biāo)簽和流行插件的使用說明烁峭。

按需應(yīng)用

默認(rèn)情況下插件在開發(fā) (serve) 和生產(chǎn) (build) 模式中都會(huì)調(diào)用。如果插件在服務(wù)或構(gòu)建期間按需使用秕铛,請使用 apply 屬性指明它們僅在 'build' 或 'serve' 模式時(shí)調(diào)用:

// vite.config.js
import typescript2 from 'rollup-plugin-typescript2'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    {
      ...typescript2(),
      apply: 'build'
    }
  ]
})

創(chuàng)建插件

閱讀 插件 API 指引 文檔了解如何創(chuàng)建插件约郁。


依賴預(yù)構(gòu)建

image.png

原因

這就是 Vite 執(zhí)行的所謂的“依賴預(yù)構(gòu)建”。這個(gè)過程有兩個(gè)目的:

  1. CommonJS 和 UMD 兼容性
  2. 性能
    Vite 將有許多內(nèi)部模塊的 ESM 依賴關(guān)系轉(zhuǎn)換為單個(gè)模塊但两,以提高后續(xù)頁面加載性能鬓梅。

自動(dòng)依賴搜尋

如果沒有找到相應(yīng)的緩存,Vite 將抓取你的源碼谨湘,并自動(dòng)尋找引入的依賴項(xiàng)(即 "bare import"绽快,表示期望從 node_modules 解析),并將這些依賴項(xiàng)作為預(yù)構(gòu)建包的入口點(diǎn)紧阔。預(yù)構(gòu)建通過 esbuild 執(zhí)行坊罢,所以它通常非常快擅耽。在服務(wù)器已經(jīng)啟動(dòng)之后活孩,如果遇到一個(gè)新的依賴關(guān)系導(dǎo)入,而這個(gè)依賴關(guān)系還沒有在緩存中乖仇,Vite 將重新運(yùn)行依賴構(gòu)建進(jìn)程并重新加載頁面憾儒。

Monorepo 和鏈接依賴

略過

自定義行為

默認(rèn)的依賴項(xiàng)發(fā)現(xiàn)為啟發(fā)式可能并不總是可取的。在你想要顯式地從列表中包含/排除依賴項(xiàng)的情況下, 請使用 optimizeDeps 配置項(xiàng)乃沙。

緩存

  1. 文件系統(tǒng)緩存
    Vite 會(huì)將預(yù)構(gòu)建的依賴緩存到 node_modules/.vite起趾。它根據(jù)幾個(gè)源來決定是否需要重新運(yùn)行預(yù)構(gòu)建步驟:
  • package.json 中的 dependencies 列表
  • 包管理器的 lockfile,例如 package-lock.json, yarn.lock警儒,或者 pnpm-lock.yaml
  • 可能在 vite.config.js 相關(guān)字段中配置過的
    只有在上述其中一項(xiàng)發(fā)生更改時(shí)训裆,才需要重新運(yùn)行預(yù)構(gòu)建。

如果出于某些原因,你想要強(qiáng)制 Vite 重新構(gòu)建依賴缭保,你可以用 --force 命令行選項(xiàng)啟動(dòng)開發(fā)服務(wù)器,或者手動(dòng)刪除 node_modules/.vite 目錄蝙茶。

  1. 瀏覽器緩存
    解析后的依賴請求會(huì)以 HTTP 頭 max-age=31536000,immutable 強(qiáng)緩存艺骂,以提高在開發(fā)時(shí)的頁面重載性能。一旦被緩存隆夯,這些請求將永遠(yuǎn)不會(huì)再到達(dá)開發(fā)服務(wù)器钳恕。如果安裝了不同的版本(這反映在包管理器的 lockfile 中),則附加的版本 query 會(huì)自動(dòng)使它們失效蹄衷。如果你想通過本地編輯來調(diào)試依賴項(xiàng)忧额,你可以:
  • 通過瀏覽器調(diào)試工具的 Network 選項(xiàng)卡暫時(shí)禁用緩存;
  • 重啟 Vite dev server愧口,并添加 --force 命令以重新構(gòu)建依賴睦番;
  • 重新載入頁面。

靜態(tài)資源處理

將資源引入為 URL

服務(wù)時(shí)引入一個(gè)靜態(tài)資源會(huì)返回解析后的公共路徑:

import imgUrl from './img.png'
document.getElementById('hero-img').src = imgUrl

例如耍属,imgUrl 在開發(fā)時(shí)會(huì)是 /img.png托嚣,在生產(chǎn)構(gòu)建后會(huì)是 /assets/img.2d8efhg.png。
行為類似于 Webpack 的 file-loader厚骗。區(qū)別在于導(dǎo)入既可以使用絕對公共路徑(基于開發(fā)期間的項(xiàng)目根路徑)示启,也可以使用相對路徑。

  • url() 在 CSS 中的引用也以同樣的方式處理领舰。
  • 如果 Vite 使用了 Vue 插件夫嗓,Vue SFC 模板中的資源引用都將自動(dòng)轉(zhuǎn)換為導(dǎo)入。
  • 常見的圖像冲秽、媒體和字體文件類型被自動(dòng)檢測為資源舍咖。你可以使用 assetsInclude 選項(xiàng) 擴(kuò)展內(nèi)部列表。
  • 引用的資源作為構(gòu)建資源圖的一部分包括在內(nèi)锉桑,將生成散列文件名谎仲,并可以由插件進(jìn)行處理以進(jìn)行優(yōu)化。
  • 較小的資源體積小于 assetsInlineLimit 選項(xiàng)值 則會(huì)被內(nèi)聯(lián)為 base64 data URL刨仑。

顯式 URL 引入

未被包含在內(nèi)部列表或 assetsInclude 中的資源郑诺,可以使用 ?url 后綴顯式導(dǎo)入為一個(gè) URL。這十分有用杉武,例如辙诞,要導(dǎo)入 Houdini Paint Worklets 時(shí):

import workletURL from 'extra-scalloped-border/worklet.js?url'
CSS.paintWorklet.addModule(workletURL)
// 顯式加載資源為一個(gè) URL
import assetAsURL from './asset.js?url'

// 以字符串形式加載資源
import assetAsString from './shader.glsl?raw'

// 在生產(chǎn)構(gòu)建中將會(huì)分離出 chunk
import Worker from './shader.js?worker'
const worker = new Worker()

// sharedworker
import SharedWorker from './shader.js?sharedworker'
const sharedWorker = new SharedWorker()

// 內(nèi)聯(lián)為 base64 字符串
import InlineWorker from './shader.js?worker&inline'

查看 Web Worker 小節(jié) 獲取更多細(xì)節(jié)。

public 目錄

如果你有下列這些資源:

  • 不會(huì)被源碼引用(例如 robots.txt
  • 必須保持原有文件名(沒有經(jīng)過 hash)
  • ...或者你壓根不想引入該資源轻抱,只是想得到其 URL飞涂。

那么你可以將該資源放在指定的 public 目錄中,它應(yīng)位于你的項(xiàng)目根目錄。該目錄中的資源在開發(fā)時(shí)能直接通過 / 根路徑訪問到较店,并且打包時(shí)會(huì)被完整復(fù)制到目標(biāo)目錄的根目錄下士八。

目錄默認(rèn)是 <root>/public,但可以通過 publicDir 選項(xiàng) 來配置梁呈。
請注意:

  • 引入 public 中的資源永遠(yuǎn)應(yīng)該使用根絕對路徑, 舉例public/icon.png 應(yīng)該在源碼中被引用為 /icon.png婚度。
  • public 中的資源不應(yīng)該被 JavaScript 文件引用。

new URL(url, import.meta.url)

import.meta.url 是一個(gè) ESM 的原生功能官卡,會(huì)暴露當(dāng)前模塊的 URL蝗茁。將它與原生的 URL 構(gòu)造器 組合使用,在一個(gè) JavaScript 模塊中寻咒,通過相對路徑我們就能得到一個(gè)被完整解析的靜態(tài)資源 URL:

const imgUrl = new URL('./img.png', import.meta.url).href
document.getElementById('hero-img').src = imgUrl

這在現(xiàn)代瀏覽器中能夠原生使用 - 實(shí)際上哮翘,Vite 并不需要在開發(fā)階段處理這些代碼!

這個(gè)模式同樣還可以通過字符串模板支持動(dòng)態(tài) URL:

function getImageUrl(name) {
  return new URL(`./dir/${name}.png`, import.meta.url).href
}

在生產(chǎn)構(gòu)建時(shí)毛秘,Vite 才會(huì)進(jìn)行必要的轉(zhuǎn)換保證 URL 在打包和資源哈希后仍指向正確的地址饭寺。

注意:無法在 SSR 中使用

如果你正在以服務(wù)端渲染模式使用 Vite 則此模式不支持,因?yàn)?import.meta.url 在瀏覽器和 Node.js 中有不同的語義叫挟。服務(wù)端的產(chǎn)物也無法預(yù)先確定客戶端主機(jī) URL佩研。


構(gòu)建生產(chǎn)版本

當(dāng)需要將應(yīng)用部署到生產(chǎn)環(huán)境時(shí),只需運(yùn)行 vite build 命令霞揉。默認(rèn)情況下旬薯,它使用 <root>/index.html 作為其構(gòu)建入口點(diǎn),并生成能夠靜態(tài)部署的應(yīng)用程序包适秩。請查閱 部署靜態(tài)站點(diǎn) 獲取常見服務(wù)的部署指引绊序。

瀏覽器兼容性

用于生產(chǎn)環(huán)境的構(gòu)建包會(huì)假設(shè)目標(biāo)瀏覽器支持現(xiàn)代 JavaScript 語法。默認(rèn)情況下秽荞,Vite 的目標(biāo)瀏覽器是指能夠 支持原生 ESM script 標(biāo)簽支持原生 ESM 動(dòng)態(tài)導(dǎo)入 的骤公。作為參考,Vite 使用這個(gè) browserslist 作為查詢標(biāo)準(zhǔn):defaults and supports es6-module and supports es6-module-dynamic-import, not opera > 0, not samsung > 0, not and_qq > 0
你也可以通過 build.target 配置項(xiàng) 指定構(gòu)建目標(biāo)扬跋,最低支持 es2015阶捆。

請注意,默認(rèn)情況下 Vite 只處理語法轉(zhuǎn)譯钦听,且 默認(rèn)不包含任何 polyfill洒试。你可以前往 Polyfill.io 查看,這是一個(gè)基于用戶瀏覽器 User-Agent 字符串自動(dòng)生成 polyfill 包的服務(wù)朴上。

傳統(tǒng)瀏覽器可以通過插件 @vitejs/plugin-legacy 來支持垒棋,它將自動(dòng)生成傳統(tǒng)版本的 chunk 及與其相對應(yīng) ES 語言特性方面的 polyfill。兼容版的 chunk 只會(huì)在不支持原生 ESM 的瀏覽器中進(jìn)行按需加載痪宰。

公共基礎(chǔ)路徑

如果你需要在嵌套的公共路徑下部署項(xiàng)目叼架,只需指定 base 配置項(xiàng)畔裕,然后所有資源的路徑都將據(jù)此配置重寫。這個(gè)選項(xiàng)也可以通過命令行參數(shù)指定乖订,例如 vite build --base=/my/public/path/扮饶。

由 JS 引入的資源 URL,CSS 中的 url() 引用以及 .html 文件中引用的資源在構(gòu)建過程中都會(huì)自動(dòng)調(diào)整乍构,以適配此選項(xiàng)甜无。

當(dāng)然,情況也有例外蜡吧,當(dāng)訪問過程中需要使用動(dòng)態(tài)連接的 url 時(shí),可以使用全局注入的 import.<wbr style="box-sizing: border-box;">meta.env.BASE_URL 變量占键,它的值為公共基礎(chǔ)路徑昔善。注意,這個(gè)變量在構(gòu)建時(shí)會(huì)被靜態(tài)替換畔乙,因此君仆,它必須按 import.<wbr style="box-sizing: border-box;">meta.env.BASE_URL 的原樣出現(xiàn)(例如 import.<wbr style="box-sizing: border-box;">meta.env['BASE_URL'] 是無效的)

自定義構(gòu)建

略過

文件變化時(shí)重新構(gòu)建

略過

多頁面應(yīng)用模式

假設(shè)你有下面這樣的項(xiàng)目文件結(jié)構(gòu)

├── package.json
├── vite.config.js
├── index.html
├── main.js
└── nested
    ├── index.html
    └── nested.js

在開發(fā)過程中,簡單地導(dǎo)航或鏈接到 /nested/ - 將會(huì)按預(yù)期工作牲距,與正常的靜態(tài)文件服務(wù)器表現(xiàn)一致返咱。
在構(gòu)建過程中,你只需指定多個(gè) .html 文件作為入口點(diǎn)即可:
// vite.config.js
const { resolve } = require('path')
const { defineConfig } = require('vite')

module.exports = defineConfig({
  build: {
    rollupOptions: {
      input: {
        main: resolve(__dirname, 'index.html'),
        nested: resolve(__dirname, 'nested/index.html')
      }
    }
  }
})

如果你指定了另一個(gè)根目錄牍鞠,請記住咖摹,在解析輸入路徑時(shí),__dirname 的值將仍然是 vite.config.js 文件所在的目錄难述。因此萤晴,你需要把對應(yīng)入口文件的 root 的路徑添加到 resolve 的參數(shù)中。

庫模式

當(dāng)你開發(fā)面向?yàn)g覽器的庫時(shí)胁后,你可能會(huì)將大部分時(shí)間花在該庫的測試/演示頁面上店读。在 Vite 中你可以使用 index.html 獲得如絲般順滑的開發(fā)體驗(yàn)。
略過


部署靜態(tài)站點(diǎn)

本指南建立在以下幾個(gè)假設(shè)基礎(chǔ)之上:

  • 你正在使用的是默認(rèn)的構(gòu)建輸出路徑(dist)攀芯。這個(gè)路徑 可以通過 build.outDir 更改屯断,在這種情況下,你可以從這篇指南中找到出所需的指引侣诺。
  • 你正在使用 NPM殖演;或者 Yarn 等其他可以運(yùn)行下面的腳本指令的包管理工具。
  • Vite 已作為一個(gè)本地開發(fā)依賴(dev dependency)安裝在你的項(xiàng)目中年鸳,并且你已經(jīng)配置好了如下的 npm scripts:
{
  "scripts": {
    "build": "vite build",
    "preview": "vite preview"
  }
}

值得注意的是 vite preview 用作預(yù)覽本地構(gòu)建剃氧,而不應(yīng)直接作為生產(chǎn)服務(wù)器。

注意
本篇指南提供了部署 Vite 靜態(tài)站點(diǎn)的說明阻星。Vite 也對服務(wù)端渲染(SSR)有了實(shí)驗(yàn)性的支持朋鞍。SSR 是指支持在 Node 中運(yùn)行相應(yīng)應(yīng)用的前端框架已添,預(yù)渲染成 HTML,最后在客戶端激活(hydrate)滥酥。查看 SSR 指南 了解更多細(xì)節(jié)更舞。另一方面,如果你在尋找與傳統(tǒng)服務(wù)端框架集成的方式坎吻,那么請查看 后端集成 章節(jié)缆蝉。

構(gòu)建應(yīng)用

你可以運(yùn)行 npm run build 命令來執(zhí)行應(yīng)用的構(gòu)建。默認(rèn)情況下瘦真,構(gòu)建會(huì)輸出到 dist 文件夾中刊头。你可以部署這個(gè) dist 文件夾到任何你喜歡的平臺。

本地測試應(yīng)用

當(dāng)你構(gòu)建完成應(yīng)用后诸尽,你可以通過運(yùn)行 npm run preview 命令原杂,在本地測試該應(yīng)用。
vite preview 命令會(huì)在本地啟動(dòng)一個(gè)靜態(tài) Web 服務(wù)器您机,將 dist 文件夾運(yùn)行在 http://localhost:5000穿肄。這樣在本地環(huán)境下查看該構(gòu)建產(chǎn)物是否正常可用就方便了际看。
你可以通過 --port 參數(shù)來配置服務(wù)的運(yùn)行端口咸产。package.json { "scripts": { "preview": "vite preview --port 8080" } }

GitHub Pages

部署

騰訊云-Webify

  1. 開通云托管
    登錄騰訊云https://webify.cloudbase.net/, 我是用微信登錄的,實(shí)用認(rèn)證后開啟服務(wù)仲闽,“新建應(yīng)用”
    https://console.cloud.tencent.com/webify/index
    image.png

    應(yīng)用創(chuàng)建之后脑溢,等待構(gòu)建、部署完畢赖欣,便可以通過應(yīng)用的默認(rèn)域名(xxx.app.tcloudbase.com)來訪問應(yīng)用焚志。
    我的是https://vite-henrypt-0gitm56jd2697f0e-1310395618.ap-shanghai.app.tcloudbase.com/
    注:創(chuàng)建云托管成功不久,我的信息就被賣了畏鼓,有人給我打電話問我注冊云托管酱酬,要不要買服務(wù)器!
  1. 使用xxx.sh腳本(測試沒成功)
    在你的項(xiàng)目中云矫,創(chuàng)建一個(gè) deploy.sh 腳本膳沽,包含以下內(nèi)容(注意高亮的行,按需使用)让禀,運(yùn)行腳本來部署站點(diǎn):
#!/usr/bin/env sh

# 發(fā)生錯(cuò)誤時(shí)終止
set -e

# 構(gòu)建
npm run build

# 進(jìn)入構(gòu)建文件夾
cd dist

# 如果你要部署到自定義域名
# echo 'www.example.com' > CNAME

# git init
git add -A
git commit -m "deploy"

# 如果你要部署在 https://<USERNAME>.github.io
# git push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git main

# 如果你要部署在 https://<USERNAME>.github.io/<REPO>
# git push -f git@github.com:<USERNAME>/<REPO>.git master:branch-test1   [master是默認(rèn)主分支; branch-test1是子分支]
git push -f https://gitee.com/henrypt1213/vite-henrypt master:branch-test1
 
cd -

*** .sh文件執(zhí)行 ***

windows下vscode運(yùn)行shell腳本

image.png

image.png

環(huán)境變量和模式

環(huán)境變量

Vite 在一個(gè)特殊的 import.meta.env 對象上暴露環(huán)境變量验残。這里有一些在所有情況下都可以使用的內(nèi)建變量:

  • import.meta.env.MODE: {string} 應(yīng)用運(yùn)行的模式培己。

  • import.meta.env.BASE_URL: {string} 部署應(yīng)用時(shí)的基本 URL盈咳。他由base 配置項(xiàng)決定油够。

  • import.meta.env.PROD: {boolean} 應(yīng)用是否運(yùn)行在生產(chǎn)環(huán)境。

  • import.meta.env.DEV: {boolean} 應(yīng)用是否運(yùn)行在開發(fā)環(huán)境 (永遠(yuǎn)與 import.<wbr style="box-sizing: border-box;">meta.env.PROD相反)腮敌。

生產(chǎn)環(huán)境替換

在生產(chǎn)環(huán)境中阱当,這些環(huán)境變量會(huì)在構(gòu)建時(shí)被靜態(tài)替換俏扩,因此,在引用它們時(shí)請使用完全靜態(tài)的字符串弊添。動(dòng)態(tài)的 key 將無法生效录淡。例如,動(dòng)態(tài) key 取值 import.meta.env[key] 是無效的油坝。
它還將替換出現(xiàn)在 JavaScript 和 Vue 模板中的字符串嫉戚。這本應(yīng)是非常少見的,但也可能是不小心為之的澈圈。在這種情況下你可能會(huì)看到類似 Missing SemicolonUnexpected token 等錯(cuò)誤彬檀,例如當(dāng) "process.env.NODE_ENV" 被替換為 ""development": "。有一些方法可以避免這個(gè)問題:

  • 對于 JavaScript 字符串瞬女,你可以使用 unicode 零寬度空格 \u200b (一個(gè)看不見的分隔符)來分割這個(gè)字符串窍帝,例如: 'import.meta.env.MODE'

  • 對于 Vue 模板或其他編譯到 JavaScript 字符串的 HTML拆魏,你可以使用 <wbr> 標(biāo)簽盯桦,例如:import.meta.env.MODE慈俯。
    略過


服務(wù)端渲染

實(shí)驗(yàn)性
SSR 支持還處于試驗(yàn)階段渤刃,你可能會(huì)遇到 bug 和不受支持的用例。請考慮你可能承擔(dān)的風(fēng)險(xiǎn)贴膘。

注意
SSR 特別指支持在 Node.js 中運(yùn)行相同應(yīng)用程序的前端框架(例如 React卖子、Preact、Vue 和 Svelte)刑峡,將其預(yù)渲染成 HTML洋闽,最后在客戶端進(jìn)行注水化處理。如果你正在尋找與傳統(tǒng)服務(wù)器端框架的集成突梦,請查看 后端集成指南诫舅。
下面的指南還假定你在選擇的框架中有使用 SSR 的經(jīng)驗(yàn),并且只關(guān)注特定于 Vite 的集成細(xì)節(jié)宫患。

示例項(xiàng)目

Vite 為服務(wù)端渲染(SSR)提供了內(nèi)建支持刊懈。這里的 Vite 范例包含了 Vue 3 和 React 的 SSR 設(shè)置示例,可以作為本指南的參考:

源碼結(jié)構(gòu)

一個(gè)典型的 SSR 應(yīng)用應(yīng)該有如下的源文件結(jié)構(gòu):

- index.html
- src/
  - main.js          # 導(dǎo)出環(huán)境無關(guān)的(通用的)應(yīng)用代碼
  - entry-client.js  # 將應(yīng)用掛載到一個(gè) DOM 元素上
  - entry-server.js  # 使用某框架的 SSR API 渲染該應(yīng)用

index.html 將需要引用 entry-client.js 并包含一個(gè)占位標(biāo)記供給服務(wù)端渲染時(shí)注入:

<div id="app"><!--ssr-outlet--></div>
<script type="module" src="/src/entry-client.js"></script>

你可以使用任何你喜歡的占位標(biāo)記來替代 娃闲,只要它能夠被正確替換虚汛。

情景邏輯

如果需要執(zhí)行 SSR 和客戶端間情景邏輯,可以使用:

if ( import.meta.env.SSR ) {
  // ... 僅在服務(wù)端執(zhí)行的邏輯
}

這是在構(gòu)建過程中被靜態(tài)替換的皇帮,因此它將允許對未使用的條件分支進(jìn)行搖樹優(yōu)化卷哩。

設(shè)置開發(fā)服務(wù)器

在構(gòu)建 SSR 應(yīng)用程序時(shí),你可能希望完全控制主服務(wù)器属拾,并將 Vite 與生產(chǎn)環(huán)境脫鉤将谊。因此冷溶,建議以中間件模式使用 Vite。下面是一個(gè)關(guān)于 express 的例子:

# server.js
const fs = require('fs')
const path = require('path')
const express = require('express')
const { createServer: createViteServer } = require('vite')

async function createServer() {
  const app = express()

  // 以中間件模式創(chuàng)建 Vite 應(yīng)用瓢娜,這將禁用 Vite 自身的 HTML 服務(wù)邏輯
  // 并讓上級服務(wù)器接管控制
  //
  // 如果你想使用 Vite 自己的 HTML 服務(wù)邏輯(將 Vite 作為
  // 一個(gè)開發(fā)中間件來使用)挂洛,那么這里請用 'html'
  const vite = await createViteServer({
    server: { middlewareMode: 'ssr' }
  })
  // 使用 vite 的 Connect 實(shí)例作為中間件
  app.use(vite.middlewares)

  app.use('*', async (req, res) => {
    // 服務(wù) index.html - 下面我們來處理這個(gè)問題
  })

  app.listen(3000)
}

createServer()

這里 viteViteDevServer 的一個(gè)實(shí)例。vite.middlewares 是一個(gè) Connect 實(shí)例眠砾,它可以在任何一個(gè)兼容 connect 的 Node.js 框架中被用作一個(gè)中間件虏劲。

下一步是實(shí)現(xiàn) * 處理程序供給服務(wù)端渲染的 HTML:

app.use('*', async (req, res) => {
  const url = req.originalUrl

  try {
    // 1. 讀取 index.html
    let template = fs.readFileSync(
      path.resolve(__dirname, 'index.html'),
      'utf-8'
    )

    // 2. 應(yīng)用 Vite HTML 轉(zhuǎn)換。這將會(huì)注入 Vite HMR 客戶端褒颈,
    //    同時(shí)也會(huì)從 Vite 插件應(yīng)用 HTML 轉(zhuǎn)換柒巫。
    //    例如:@vitejs/plugin-react-refresh 中的 global preambles
    template = await vite.transformIndexHtml(url, template)

    // 3. 加載服務(wù)器入口。vite.ssrLoadModule 將自動(dòng)轉(zhuǎn)換
    //    你的 ESM 源碼使之可以在 Node.js 中運(yùn)行谷丸!無需打包
    //    并提供類似 HMR 的根據(jù)情況隨時(shí)失效堡掏。
    const { render } = await vite.ssrLoadModule('/src/entry-server.js')

    // 4. 渲染應(yīng)用的 HTML。這假設(shè) entry-server.js 導(dǎo)出的 `render`
    //    函數(shù)調(diào)用了適當(dāng)?shù)?SSR 框架 API刨疼。
    //    例如 ReactDOMServer.renderToString()
    const appHtml = await render(url)

    // 5. 注入渲染后的應(yīng)用程序 HTML 到模板中泉唁。
    const html = template.replace(`<!--ssr-outlet-->`, appHtml)

    // 6. 返回渲染后的 HTML。
    res.status(200).set({ 'Content-Type': 'text/html' }).end(html)
  } catch (e) {
    // 如果捕獲到了一個(gè)錯(cuò)誤揩慕,讓 Vite 來修復(fù)該堆棧亭畜,這樣它就可以映射回
    // 你的實(shí)際源碼中。
    vite.ssrFixStacktrace(e)
    console.error(e)
    res.status(500).end(e.message)
  }
})

package.json 中的 dev 腳本也應(yīng)該相應(yīng)地改變迎卤,使用服務(wù)器腳本:

"scripts": {
-   "dev": "vite"
+   "dev": "node server"
  }

生產(chǎn)環(huán)境構(gòu)建

為了將 SSR 項(xiàng)目交付生產(chǎn)拴鸵,我們需要:

  1. 正常生成一個(gè)客戶端構(gòu)建;
  2. 再生成一個(gè) SSR 構(gòu)建蜗搔,使其通過 require() 直接加載劲藐,這樣便無需再使用 Vite 的 ssrLoadModule
    package.json 中的腳本應(yīng)該看起來像這樣:
{
  "scripts": {
    "dev": "node server",
    "build:client": "vite build --outDir dist/client",
    "build:server": "vite build --outDir dist/server --ssr src/entry-server.js "
  }
}

注意使用 --ssr 標(biāo)志表明這將會(huì)是一個(gè) SSR 構(gòu)建樟凄。同時(shí)需要指定 SSR 的入口聘芜。

接著,在 server.js 中缝龄,通過 process.env.NODE_ENV 條件分支汰现,需要添加一些用于生產(chǎn)環(huán)境的特定邏輯:

  • 使用 dist/client/index.html 作為模板,而不是根目錄的 index.html二拐,因?yàn)榍罢甙说娇蛻舳藰?gòu)建的正確資源鏈接服鹅。

  • 使用 require('./dist/server/entry-server.js') ,而不是 await vite.ssrLoadModule('/src/entry-server.js')(前者是 SSR 構(gòu)建后的最終結(jié)果)百新。

  • vite 開發(fā)服務(wù)器的創(chuàng)建和所有使用都移到 dev-only 條件分支后面企软,然后添加靜態(tài)文件服務(wù)中間件來服務(wù) dist/client 中的文件。

可以在此參考 VueReact 的設(shè)置范例饭望。

生成預(yù)加載指令

略過

預(yù)渲染 / SSG

如果預(yù)先知道某些路由所需的路由和數(shù)據(jù)仗哨,我們可以使用與生產(chǎn)環(huán)境 SSR 相同的邏輯將這些路由預(yù)先渲染到靜態(tài) HTML 中形庭。這也被視為一種靜態(tài)站點(diǎn)生成(SSG)的形式。查看 示例渲染代碼 獲取有效示例厌漂。

SSR 外部化

略過

SSR 專有插件邏輯

一些框架萨醒,如 Vue 或 Svelte,會(huì)根據(jù)客戶端渲染和服務(wù)端渲染的區(qū)別苇倡,將組件編譯成不同的格式富纸。可以向以下的插件鉤子中旨椒,給 Vite 傳遞額外的 options 對象晓褪,對象中包含 ssr 屬性來支持根據(jù)情景轉(zhuǎn)換:

  • resolveId
  • load
  • transform
    ...

SSR Target

SSR 構(gòu)建的默認(rèn)目標(biāo)為 node 環(huán)境,但你也可以讓服務(wù)運(yùn)行在 Web Worker 上综慎。每個(gè)平臺的打包條目解析是不同的涣仿。你可以將ssr.target 設(shè)置為 webworker,以將目標(biāo)配置為 Web Worker示惊。

SSR Bundle

在某些如 webworker 運(yùn)行時(shí)等特殊情況中好港,你可能想要將你的 SSR 打包成單個(gè) JavaScript 文件。你可以通過設(shè)置 ssr.noExternal 為 true 來啟用這個(gè)行為米罚。這將會(huì)做兩件事:

  • 將所有依賴視為 noExternal(非外部化)
  • 若任何 Node.js 內(nèi)置內(nèi)容被引入钧汹,將拋出一個(gè)錯(cuò)誤

后端集成

如果你想使用傳統(tǒng)的后端(如 Rails, Laravel)來服務(wù) HTML,但使用 Vite 來服務(wù)其他資源阔拳,可以查看在 Awesome Vite 上的已有的后端集成列表崭孤。

如果你需要自定義集成类嗤,你可以按照本指南的步驟配置它:
略過


與其它非打包解決方案比較

略過


插件 API

略過


HMR API

注意
這里是客戶端 HMR API糊肠。若要在插件中處理 HMR 更新,詳見 handleHotUpdate遗锣。
手動(dòng) HMR API 主要用于框架和工具作者货裹。作為最終用戶,HMR 可能已經(jīng)在特定于框架的啟動(dòng)器模板中為你處理過了精偿。

Vite 通過特殊的 import.meta.hot 對象暴露手動(dòng) HMR API弧圆。
略過


JavaScript API

Vite 的 JavaScript API 是完全類型化的,我們推薦使用 TypeScript 或者在 VSCode 中啟用 JS 類型檢查來利用智能提示和類型校驗(yàn)笔咽。

createServer 類型簽名:

InlineConfig#

ViteDevServer

build

preview

resolveConfig

transformWithEsbuild

配置 Vite

配置文件解析

當(dāng)以命令行方式運(yùn)行 vite 時(shí)搔预,Vite 會(huì)自動(dòng)解析 項(xiàng)目根目錄 下名為 vite.config.js 的文件

配置智能提示

因?yàn)?Vite 本身附帶 Typescript 類型,所以你可以通過 IDE 和 jsdoc 的配合來實(shí)現(xiàn)智能提示

情景配置

如果配置文件需要基于(dev/servebuild)命令或者不同的 模式 來決定選項(xiàng)叶组,則可以選擇導(dǎo)出這樣一個(gè)函數(shù)

異步配置

共享配置

vite.config.js的全部配置都在這里

開發(fā)服務(wù)器選項(xiàng)

構(gòu)建選項(xiàng)

預(yù)覽選項(xiàng)

依賴優(yōu)化選項(xiàng)

SSR 選項(xiàng)

插件

官方插件#

@vitejs/plugin-vue#

  • 提供 Vue 3 單文件組件支持

@vitejs/plugin-vue-jsx#

@vitejs/plugin-react#

  • 提供完整的 React 支持

@vitejs/plugin-legacy#

  • 為打包后的文件提供傳統(tǒng)瀏覽器兼容性支持

Rollup 插件

Vite 插件 是 Rollup 插件接口的一種擴(kuò)展。查看 Rollup 插件兼容性章節(jié) 獲取更多信息甩十。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末船庇,一起剝皮案震驚了整個(gè)濱河市吭产,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鸭轮,老刑警劉巖臣淤,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異窃爷,居然都是意外死亡邑蒋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門按厘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寺董,“玉大人,你說我怎么就攤上這事刻剥≌诳В” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵造虏,是天一觀的道長御吞。 經(jīng)常有香客問我,道長漓藕,這世上最難降的妖魔是什么陶珠? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮享钞,結(jié)果婚禮上揍诽,老公的妹妹穿的比我還像新娘。我一直安慰自己栗竖,他們只是感情好暑脆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著狐肢,像睡著了一般添吗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上份名,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天碟联,我揣著相機(jī)與錄音,去河邊找鬼僵腺。 笑死鲤孵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的辰如。 我是一名探鬼主播普监,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了鹰椒?” 一聲冷哼從身側(cè)響起锡移,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎漆际,沒想到半個(gè)月后淆珊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奸汇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年施符,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片擂找。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡戳吝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出贯涎,到底是詐尸還是另有隱情听哭,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布塘雳,位于F島的核電站陆盘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏败明。R本人自食惡果不足惜隘马,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望妻顶。 院中可真熱鬧酸员,春花似錦、人聲如沸讳嘱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呢燥。三九已至崭添,卻和暖如春寓娩,著一層夾襖步出監(jiān)牢的瞬間叛氨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工棘伴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留寞埠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓焊夸,卻偏偏與公主長得像仁连,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

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