<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【W(wǎng)eb技術(shù)】848- 超棒的 Babel 上手指南

          共 11664字,需瀏覽 24分鐘

           ·

          2021-01-27 10:02

          此文檔翻譯自?https://github.com/jamiebuilds/babel-handbook,由圖雀醬審驗。

          這個文檔涵蓋了所有你想知道的關(guān)于 Babel 及其相關(guān)工具使用的所有內(nèi)容。

          目錄

          • 引言
          • 配置 Babel 環(huán)境
            • babel-cli
            • 在項目內(nèi)部運行 Babel CLI
            • babel-register
            • babel-node
            • babel-core
          • 配置 Babel
            • .babelrc
            • babel-preset-es2015
            • babel-preset-react
            • babel-preset-stage-x
          • 執(zhí)行 babel 生成的代碼
            • babel-polyfill
            • babel-runtime
          • 配置 Babel (進階版)
            • 手動指定插件
            • 插件選項
            • 基于環(huán)境定制 Babel
            • 構(gòu)建自己的 Preset
          • Babel 和其他工具
            • 靜態(tài)分析工具
            • Linting
            • 文檔
            • 框架

          引言

          Babel 是一個用于 JavaScript 的通用多用途編譯器,使用 Babel 可以使用(或創(chuàng)建)下一代 的JavaScript,以及下一代 JavaScript 工具。

          作為一門語言,JavaScript 不斷發(fā)展,帶來了很多新的規(guī)范和建議,使用 Babel 可以讓你在這些新的規(guī)范和建議全面普及之前就提前使用它們。

          Babel 通過將最新標準的 JavaScript 代碼編譯為已經(jīng)在目前可以工作的代碼來實現(xiàn)上一段提到的內(nèi)容。這個過程被稱為?“源代碼到源代碼”?的編譯,這也被成為 “轉(zhuǎn)換”

          例如,Babel 可以將最新的 ES2015 的箭頭函數(shù)語法從:

          const?square?=?n?=>?n?*?n;

          轉(zhuǎn)換成下面的內(nèi)容:

          const?square?=?function?square(n)?{
          ??return?n?*?n;
          };

          然而,Babel 可以勝任更多的工作,因為Babel 支持語法擴展,例如 React 的 JSX 語法或者靜態(tài)類型檢查的 Flow 語法。

          更近一步,在 Babel 中一切皆插件,而每個人都可以充分利用 Babel 的強大能力來創(chuàng)建屬于自己的插件。且 Babel 被組織成幾個核心的模塊,允許用戶利用這些模塊來構(gòu)建下一代 JavaScript 工具鏈。

          許多人也是這樣去做的,Babel 的生態(tài)系統(tǒng)正在茁長的成長。在這本 Babel 手冊中,我將講解 Babel 內(nèi)建的一些工具以及社區(qū)里的一些擁有的工具。

          Babel 模塊介紹

          因為 JavaScript 社區(qū)沒有標準的構(gòu)建工具,框架或平臺等,Babel 官方性與其他所有的主要工具進行了集成。無論是來自 Gulp、Browserify,或者是 Ember、Meteor,亦或是 Webpack 等,無論你的啟動工具是什么,Babel 都存在一些官方性的集成。

          就本手冊而言,我們將介紹設(shè)置Babel的內(nèi)置方法,但是您也可以訪問交互式設(shè)置頁面[1]以了解所有集成。

          注意:本指南將參考諸如 nodenpm 之類的命令行工具。在繼續(xù)進行任何操作之前,您應(yīng)該對這些工具感到滿意。

          babel-cli

          Babel的CLI是從命令行使用Babel編譯文件的簡單方法。

          讓我們首先在全局安裝它以學習基礎(chǔ)知識。

          $?npm?install?--global?babel-cli

          我們可以像這樣編譯我們的第一個文件:

          $?babel?my-file.js

          這會將編譯后的輸出直接轉(zhuǎn)儲到您的終端中。要將其寫入文件,我們將指定 --out-file?或 -o?。

          $?babel?example.js?--out-file?compiled.js
          #?or
          $?babel?example.js?-o?compiled.js

          如果我們想將整個目錄編譯成一個新目錄,可以使用 --out-dir?或 -d?來完成。

          $?babel?src?--out-dir?lib
          #?or
          $?babel?src?-d?lib

          從項目中運行Babel CLI

          雖然您可以在計算機上全局安裝Babel CLI,但最好逐個項目在本地安裝它。

          這有兩個主要原因。

          • 同一臺計算機上的不同項目可能取決于Babel的不同版本,從而允許您一次更新一個版本。
          • 這意味著您對工作的環(huán)境沒有隱式依賴。使您的項目更加可移植且易于設(shè)置。

          我們可以通過運行以下命令在本地安裝Babel CLI:

          $?npm?install?--save-dev?babel-cli

          注意:由于在全局范圍內(nèi)運行 Babel 通常是一個壞主意,因此您可能需要通過運行以下命令來卸載全局副本:

          $?npm?uninstall?--global?babel-cli

          完成安裝后,您的 package.json?文件應(yīng)如下所示:

          {
          ??"name":?"my-project",
          ??"version":?"1.0.0",
          ??"devDependencies":?{
          ????"babel-cli":?"^6.0.0"
          ??}
          }

          現(xiàn)在,與其直接從命令行運行 Babel,不如將命令放入使用本地版本的 npm 腳本中。只需在您的 package.json?中添加一個 “script”?字段,然后將 babel?命令放入其中即可進行構(gòu)建。

          ??{
          ????"name":?"my-project",
          ????"version":?"1.0.0",
          +???"scripts":?{
          +?????"build":?"babel?src?-d?lib"
          +???},
          ????"devDependencies":?{
          ??????"babel-cli":?"^6.0.0"
          ????}
          ??}

          現(xiàn)在,從我們的終端我們可以運行:

          npm?run?build

          這將以與以前相同的方式運行Babel,只是現(xiàn)在我們正在使用本地副本。

          babel-register

          運行Babel的下一個最常見的方法是通過 babel-register?。通過此選項,您僅需要文件即可運行 Babel,這可能會更好地與您的設(shè)置集成。

          請注意,這并非供生產(chǎn)使用。部署以這種方式編譯的代碼被認為是不好的做法。最好在部署之前提前進行編譯。但是,這對于構(gòu)建腳本或您在本地運行的其他事情非常有效。

          首先讓我們在項目中創(chuàng)建一個 index.js?文件。

          console.log("Hello?world!");

          如果我們使用 node index.js?來運行它,那么 Babel 不會編譯它。因此,我們需要先設(shè)置 babel-register?。

          首先安裝 babel-register?。

          $?npm?install?--save-dev?babel-register

          接下來,在項目中創(chuàng)建一個 register.js?文件,并編寫以下代碼:

          require("babel-register");
          require("./index.js");

          這是在 Node 的模塊系統(tǒng)中注冊 Babel 并開始編譯每個 require?的文件。

          現(xiàn)在,我們可以使用 node egister.js?代替運行 node index.js?。

          $?node?register.js

          注意:您不能在要編譯的文件中注冊 Babel。在 Babel 有機會編譯文件之前,Node 正在執(zhí)行文件。

          require("babel-register");

          //?not?compiled:
          console.log("Hello?world!");

          babel-node

          如果您只是通過 node? CLI 運行某些代碼,則集成 Babel 的最簡單方法可能是使用 babel-node? CLI,這在很大程度上只是對 node?CLI 的替代。

          請注意,這并非供生產(chǎn)使用。部署以這種方式編譯的代碼被認為是不好的做法。最好在部署之前提前進行編譯。但是,這對于構(gòu)建腳本或您在本地運行的其他事情非常有效。

          首先,請確保您已安裝 babel-cli?。

          $?npm?install?--save-dev?babel-cli

          **注意:**如果您想知道為什么要在本地安裝此軟件,請在上面的項目部分中閱讀 “從項目中運行 Babel CLI”。

          然后,將運行 node?的任何位置替換為 babel-node?。

          如果您使用的是 npm script?,則只需執(zhí)行以下操作:

          ??{
          ????"scripts":?{
          -?????"script-name":?"node?script.js"
          +?????"script-name":?"babel-node?script.js"
          ????}
          ??}

          否則,您將需要寫出通向 babel-node?本身的路徑。

          -?node?script.js
          +?./node_modules/.bin/babel-node?script.js

          babel-core

          如果出于某種原因需要在代碼中使用 Babel,則可以使用 babel-core?軟件包本身。

          首先安裝 babel-core?。

          $?npm?install?babel-core
          var?babel?=?require("babel-core");

          如果您具有 JavaScript 字符串,則可以直接使用 babel.transform?對其進行編譯。

          babel.transform("code();",?options);
          //?=>?{?code,?map,?ast?}

          如果使用文件,則可以使用異步api:

          babel.transformFile("filename.js",?options,?function(err,?result)?{
          ??result;?//?=>?{?code,?map,?ast?}
          });

          如果您出于任何原因已經(jīng)擁有Babel AST,則可以直接從AST轉(zhuǎn)換。

          babel.transformFromAst(ast,?code,?options);
          //?=>?{?code,?map,?ast?}

          對于上述所有方法, options?可以傳遞指南可以從這里了解 https://babeljs.io/docs/usage/api/#options[2]

          配置 Babel

          您現(xiàn)在可能已經(jīng)注意到,僅運行 Babel 似乎除了將 JavaScript 文件從一個位置復制到另一個位置之外沒有執(zhí)行任何其他操作。

          這是因為我們尚未告訴 Babel 該做什么事情。

          由于Babel是通用編譯器,它以多種不同的方式使用,因此默認情況下它不會執(zhí)行任何操作。您必須明確告訴Babel 它應(yīng)該做什么。

          您可以通過安裝 plugins?或 presets (plugins 組)為Babel提供操作說明。

          .babelrc

          在我們開始告訴 Babel 怎么做之前。我們需要創(chuàng)建一個配置文件。您需要做的就是在項目的根目錄下創(chuàng)建一個 .babelrc?文件。從這樣開始:

          {
          ??"presets":?[],
          ??"plugins":?[]
          }

          該文件是您配置 Babel 以執(zhí)行所需操作的方式。

          注意:雖然您還可以通過其他方式將選項傳遞給 Babel,但 .babelrc?文件是約定俗成的,也是最好的方法。

          babel-preset-es2015

          讓我們首先告訴 Babel 將 ES2015(JavaScript標準的最新版本,也稱為ES6)編譯為ES5(當今大多數(shù)JavaScript環(huán)境中可用的版本)。

          我們將通過安裝“ es2015” Babel預(yù)設(shè)來做到這一點(當然目前瀏覽器支持了絕大部分 ES2015 的特性了,這里是用作演示,使用形式是一致的):

          $?npm?install?--save-dev?babel-preset-es2015

          接下來,我們將修改 .babelrc?以包括該預(yù)設(shè)。

          ??{
          ????"presets":?[
          +?????"es2015"
          ????],
          ????"plugins":?[]
          ??}

          babel-preset-react

          設(shè)置 React 同樣簡單。只需安裝預(yù)設(shè):

          $?npm?install?--save-dev?babel-preset-react

          然后將預(yù)設(shè)添加到您的 .babelrc?文件中:

          ??{
          ????"presets":?[
          ??????"es2015",
          +?????"react"
          ????],
          ????"plugins":?[]
          ??}

          babel-preset-stage-x

          JavaScript還提出了一些建議,這些建議正在通過TC39(ECMAScript標準背后的技術(shù)委員會)流程納入標準。

          此過程分為5個階段(0-4)。隨著提案獲得更大的吸引力,并更有可能被采納為標準,它們經(jīng)歷了各個階段,最終在階段4被接納為標準。

          這些以babel的形式捆綁為4種不同的預(yù)設(shè):

          • babel-preset-stage-0
          • babel-preset-stage-1
          • babel-preset-stage-2
          • babel-preset-stage-3

          請注意,沒有階段 4 的 preset?,因為它只是上面的 es2015 預(yù)設(shè)。

          這些預(yù)設(shè)中的每個預(yù)設(shè)都需要用于后續(xù)階段的預(yù)設(shè)。即 babel-preset-stage-1?需要 babel-preset-stage-2?,而 babel-preset-stage-3? 也需要。

          安裝您感興趣的 stage 很簡單:

          $?npm?install?--save-dev?babel-preset-stage-2

          然后,您可以將其添加到您的 .babelrc?配置中。

          ??{
          ????"presets":?[
          ??????"es2015",
          ??????"react",
          +?????"stage-2"
          ????],
          ????"plugins":?[]
          ??}

          執(zhí)行 Babel 生成的代碼

          目前,您已經(jīng)使用Babel編譯了代碼,但這還不是故事的結(jié)局。

          babel-polyfill

          幾乎所有未來 JavaScript 語法都可以使用 Babel 進行編譯,但 API 并非如此。

          例如,以下代碼具有需要編譯的箭頭函數(shù)功能:

          function?addAll()?{
          ??return?Array.from(arguments).reduce((a,?b)?=>?a?+?b);
          }

          在編譯之后會變成如下這樣:

          function?addAll()?{
          ??return?Array.from(arguments).reduce(function(a,?b)?{
          ????return?a?+?b;
          ??});
          }

          但是,由于 Array.from?并非在每個JavaScript環(huán)境中都存在,因此在編譯之后它仍然無法使用:

          Uncaught?TypeError:?Array.from?is?not?a?function

          為了解決這個問題,我們使用一種叫做 Polyfill[3] 的東西。簡而言之,Polyfill 是一段代碼,該代碼復制當前運行時中不存在的 API,允許您在當前環(huán)境可用之前能提前使用 Array.from?等 API。

          Babel使用出色的 core-js[4] 作為其polyfill,以及定制的 regenerator[5] 運行時,以使生成器和異步函數(shù)正常工作。

          要包含 Babel polyfill,請首先使用npm安裝它:

          $?npm?install?--save?babel-polyfill

          然后只需將 polyfill 包含在任何需要它的文件的頂部:

          import?"babel-polyfill";

          babel-runtime

          為了實現(xiàn) ECMAScript 規(guī)范的詳細信息,Babel將使用 “helper” 方法來保持生成的代碼干凈。

          由于這些 “helper” 方法會變得很長,而且它們被添加到每個文件的頂部,因此您可以將它們移動到 require?的單個“運行時”中。

          首先安裝 babel-plugin-transform-runtime?和 babel-runtime?:

          $?npm?install?--save-dev?babel-plugin-transform-runtime
          $?npm?install?--save?babel-runtime

          然后更新您的 .babelrc?:

          ??{
          ????"plugins":?[
          +?????"transform-runtime",
          ??????"transform-es2015-classes"
          ????]
          ??}

          現(xiàn)在,Babel 將如下代碼:

          class?Foo?{
          ??method()?{}
          }

          編譯成這樣:

          import?_classCallCheck?from?"babel-runtime/helpers/classCallCheck";
          import?_createClass?from?"babel-runtime/helpers/createClass";

          let?Foo?=?function?()?{
          ??function?Foo()?{
          ????_classCallCheck(this,?Foo);
          ??}

          ??_createClass(Foo,?[{
          ????key:?"method",
          ????value:?function?method()?{}
          ??}]);

          ??return?Foo;
          }();

          而不是將 _classCallCheck?和 _createClass?helper 函數(shù)放在需要的每個文件中。

          配置 Babel(進階版)

          大多數(shù)人都可以通過僅使用內(nèi)置預(yù)設(shè)來使用 Babel,但是 Babel 所展現(xiàn)的功能遠不止于此。

          手動指定插件

          Babel 預(yù)設(shè)只是預(yù)配置插件的集合,如果您想做不同的事情,可以手動指定插件。這幾乎與預(yù)設(shè)完全相同。

          首先安裝一個插件:

          $?npm?install?--save-dev?babel-plugin-transform-es2015-classes

          然后將 plugins?字段添加到您的 .babelrc?中。

          ??{
          +???"plugins":?[
          +?????"transform-es2015-classes"
          +???]
          ??}

          這使您可以更精確地控制正在運行的確切的 transforms?。

          有關(guān)官方插件的完整列表,請參見Babel插件頁面[6]

          還請看一下社區(qū)構(gòu)建的所有插件[7]。如果您想學習如何編寫自己的插件,請閱讀Babel插件手冊[8](圖雀社區(qū)將在之后翻譯這本插件手冊,敬請期待~)。

          插件選項

          許多插件還具有將其配置為不同行為的 option?。例如,許多 transform?都具有 loose?模式,該模式會放棄某些規(guī)范行為,而傾向于使用更簡單,性能更高的代碼。

          要將選項添加到插件,只需進行以下更改:

          ??{
          ????"plugins":?[
          -?????"transform-es2015-classes"
          +?????["transform-es2015-classes",?{?"loose":?true?}]
          ????]
          ??}

          根據(jù)環(huán)境定制 Babel

          Babel插件解決了許多不同的任務(wù)。其中許多是開發(fā)工具,可以幫助您調(diào)試代碼或與工具集成。還有許多用于優(yōu)化生產(chǎn)中代碼的插件。

          因此,通常需要基于環(huán)境的 Babel 配置。您可以使用 .babelrc?文件輕松完成此操作。

          ??{
          ????"presets":?["es2015"],
          ????"plugins":?[],
          +???"env":?{
          +?????"development":?{
          +???????"plugins":?[...]
          +?????},
          +?????"production":?{
          +???????"plugins":?[...]
          +?????}
          ????}
          ??}

          Babel將根據(jù)當前環(huán)境在 env?內(nèi)部啟用配置。

          當前環(huán)境將使用 process.env.BABEL_ENV?。當 BABEL_ENV?不可用時,它將回退到 NODE_ENV?,如果不可用,則默認為“ development?”。

          Unix

          $?BABEL_ENV=production?[COMMAND]
          $?NODE_ENV=production?[COMMAND]

          Windows

          $?SET?BABEL_ENV=production
          $?[COMMAND]

          注意:[COMMAND]?是您用來運行Babel的任何東西(即 babel?, babel-node?,或者如果您正在使用 babel-register?鉤子,則可能只是 node?)。

          提示:如果要讓命令在 Unix 和 Windows 跨平臺上運行,請使用 cross-env[9]

          構(gòu)建自己的預(yù)設(shè)

          手動指定插件?插件選項?基于環(huán)境的設(shè)置?對于所有項目,所有這些配置似乎都需要重復很多次。

          因此,我們鼓勵社區(qū)創(chuàng)建自己的預(yù)設(shè)。這可以是您整個公司[10]的預(yù)設(shè)。

          創(chuàng)建預(yù)設(shè)很容易。假設(shè)您有以下 .babelrc?文件:

          {
          ??"presets":?[
          ????"es2015",
          ????"react"
          ??],
          ??"plugins":?[
          ????"transform-flow-strip-types"
          ??]
          }

          您需要做的就是按照命名約定 babel-preset-*?創(chuàng)建一個新項目(請對此命名空間負責!),并創(chuàng)建兩個文件。

          首先,創(chuàng)建一個新的 package.json?文件,該文件具有您的預(yù)設(shè)所需的 dependencies?關(guān)系。

          {
          ??"name":?"babel-preset-my-awesome-preset",
          ??"version":?"1.0.0",
          ??"author":?"James?Kyle?",
          ??"dependencies":?{
          ????"babel-preset-es2015":?"^6.3.13",
          ????"babel-preset-react":?"^6.3.13",
          ????"babel-plugin-transform-flow-strip-types":?"^6.3.15"
          ??}
          }

          然后創(chuàng)建一個 index.js?文件,該文件導出 .babelrc?文件的內(nèi)容,并用 require?調(diào)用替換插件/預(yù)設(shè)字符串。

          module.exports?=?{
          ??presets:?[
          ????require("babel-preset-es2015"),
          ????require("babel-preset-react")
          ??],
          ??plugins:?[
          ????require("babel-plugin-transform-flow-strip-types")
          ??]
          };

          然后只需將其發(fā)布到 npm,就可以像使用任何預(yù)設(shè)一樣使用它。

          Babel 和其他工具結(jié)合

          一旦掌握了 Babel,Babel 便會很直接地進行設(shè)置,但是使用其他工具進行設(shè)置可能非常困難。但是,我們嘗試與其他項目緊密合作,以使體驗盡可能輕松。

          靜態(tài)分析工具

          較新的標準為語言帶來了許多新語法,而靜態(tài)分析工具才剛剛開始利用它。

          Linting

          ESLint 是最受歡迎的 Lint 工具之一,因此,我們維護了官方的 babel-eslint[11] 集成。首先安裝 eslint?和 babel-eslint?。

          $?npm?install?--save-dev?eslint?babel-eslint

          接下來,在項目中創(chuàng)建或使用現(xiàn)有的 .eslintrc?文件,并將解析器設(shè)置為 babel-eslint?。

          ??{
          +???"parser":?"babel-eslint",
          ????"rules":?{
          ??????...
          ????}
          ??}

          現(xiàn)在將一個 lint? 任務(wù)添加到您的 npm package.json?腳本中:

          ??{
          ????"name":?"my-module",
          ????"scripts":?{
          +?????"lint":?"eslint?my-files.js"
          ????},
          ????"devDependencies":?{
          ??????"babel-eslint":?"...",
          ??????"eslint":?"..."
          ????}
          ??}

          然后只需運行任務(wù)即可完成所有設(shè)置。

          $?npm?run?lint

          有關(guān)更多信息,請查閱 babel-eslint[12]eslint[13]文檔。

          文檔

          使用Babel,ES2015和Flow,您可以推斷出很多有關(guān)您的代碼的信息。使用documentation.js[14],您可以非常輕松地生成詳細的API文檔。

          Documentation.js在后臺使用Babel支持所有最新語法,包括Flow注釋,以便在代碼中聲明類型。

          框架

          現(xiàn)在,所有主要的JavaScript框架都專注于圍繞語言的未來調(diào)整其API。因此,在工具中進行了大量工作。

          框架不僅有機會使用Babel,而且有機會以改善用戶體驗的方式對其進行擴展。

          React

          React極大地改變了其API以使其與ES2015類保持一致(在此處了解更新的API)。更進一步,React依賴Babel來編譯它的JSX語法,不贊成Babel來使用它自己的自定義工具。您可以按照上述說明開始設(shè)置 babel-preset-react?程序包。

          React社區(qū)接受了Babel并與之合作。社區(qū)[15]現(xiàn)在進行了許多轉(zhuǎn)換。

          最著名的是 babel-plugin-react-transform?插件,結(jié)合了許多特定于 React 的轉(zhuǎn)換,可以啟用熱模塊重裝和其他調(diào)試實用程序。

          參考資料

          [1]

          交互式設(shè)置頁面: https://babeljs.io/en/setup/

          [2]

          https://babeljs.io/docs/usage/api/#options: https://babeljs.io/docs/usage/api/#options

          [3]

          Polyfill: https://www.google.com/search?q=%E4%BB%80%E4%B9%88%E6%98%AF+polyfill&oq=%E4%BB%80%E4%B9%88%E6%98%AF+polyfill&aqs=chrome..69i57j0i12.3956j1j4&sourceid=chrome&ie=UTF-8

          [4]

          core-js: https://github.com/zloirock/core-js

          [5]

          regenerator: https://github.com/facebook/regenerator

          [6]

          Babel插件頁面: http://babeljs.io/docs/plugins/

          [7]

          所有插件: https://www.npmjs.com/search?q=babel-plugin

          [8]

          Babel插件手冊: https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md

          [9]

          cross-env: https://www.npmjs.com/package/cross-env

          [10]

          公司: https://github.com/cloudflare/babel-preset-cf

          [11]

          babel-eslint: https://github.com/babel/babel/tree/master/eslint/babel-eslint-parser

          [12]

          babel-eslint: https://github.com/babel/babel/tree/master/eslint/babel-eslint-parser

          [13]

          eslint: https://eslint.org/

          [14]

          documentation.js: http://documentation.js.org/

          [15]

          社區(qū): https://www.npmjs.com/search?q=babel-plugin+react

          1. JavaScript 重溫系列(22篇全)
          2. ECMAScript 重溫系列(10篇全)
          3. JavaScript設(shè)計模式 重溫系列(9篇全)
          4.?正則 / 框架 / 算法等 重溫系列(16篇全)
          5.?Webpack4 入門(上)||?Webpack4 入門(下)
          6.?MobX 入門(上)?||??MobX 入門(下)
          7. 100+篇原創(chuàng)系列匯總

          回復“加群”與大佬們一起交流學習~

          點擊“閱讀原文”查看 100+ 篇原創(chuàng)文章

          瀏覽 49
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美变态拉屎操逼网站 | 操逼网址视频 | 久久免费小电影 | 日操逼黄色 | 日韩精品一区二区三区四区五区六区 |