精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

前端模塊化的今生

開發 前端
眾所周知,早期 JavaScript 原生并不支持模塊化,直到 2015 年,TC39 發布 ES6,其中有一個規范就是 ES modules(為了方便表述,后面統一簡稱 ESM)。

 [[342654]]

背景

眾所周知,早期 JavaScript 原生并不支持模塊化,直到 2015 年,TC39 發布 ES6,其中有一個規范就是 ES modules(為了方便表述,后面統一簡稱 ESM)。但是在 ES6 規范提出前,就已經存在了一些模塊化方案,比如 CommonJS(in Node.js)、AMD。ESM 與這些規范的共同點就是都支持導入(import)和導出(export)語法,只是其行為的關鍵詞也一些差異。

CommonJS

  1. // add.js 
  2. const add = (a, b) => a + b 
  3. module.exports = add 
  4. // index.js 
  5. const add = require('./add'
  6. add(1, 5) 

AMD

  1. // add.js 
  2. define(function() { 
  3.   const add = (a, b) => a + b 
  4.   return add 
  5. }) 
  6. // index.js 
  7. require(['./add'], function (add) { 
  8.   add(1, 5) 
  9. }) 

ESM

  1. // add.js 
  2. const add = (a, b) => a + b 
  3. export default add 
  4. //index.js 
  5. import add from './add' 
  6. add(1, 5) 

關于 JavaScript 模塊化出現的背景在上一章(《前端模塊化的前世》)已經有所介紹,這里不再贅述。但是 ESM 的出現不同于其他的規范,因為這是 JavaScript 官方推出的模塊化方案,相比于 CommonJS 和 AMD 方案,ESM采用了完全靜態化的方式進行模塊的加載。

ESM規范

模塊導出

模塊導出只有一個關鍵詞:export,最簡單的方法就是在聲明的變量前面直接加上 export 關鍵詞。

  1. export const name = 'Shenfq' 

可以在 const、let、var 前直接加上 export,也可以在 function 或者 class 前面直接加上 export。

  1. export function getName() { 
  2.   return name 
  3. export class Logger { 
  4.  log(...args) { 
  5.     console.log(...args) 
  6.   } 

上面的導出方法也可以使用大括號的方式進行簡寫。

  1. const name = 'Shenfq' 
  2. function getName() { 
  3.   return name 
  4. class Logger { 
  5.  log(...args) { 
  6.     console.log(...args) 
  7.   } 
  8.  
  9. export { name, getName, Logger } 

最后一種語法,也是我們經常使用的,導出默認模塊。

  1. const name = 'Shenfq' 
  2. export default name 

模塊導入

模塊的導入使用import,并配合 from 關鍵詞。

  1. // main.js 
  2. import name from './module.js' 
  3.  
  4. // module.js 
  5. const name = 'Shenfq' 
  6. export default name 

這樣直接導入的方式,module.js 中必須使用 export default,也就是說 import 語法,默認導入的是default模塊。如果想要導入其他模塊,就必須使用對象展開的語法。

  1. // main.js 
  2. import { name, getName } from './module.js' 
  3.  
  4. // module.js 
  5. export const name = 'Shenfq' 
  6. export const getName = () => name 

如果模塊文件同時導出了默認模塊,和其他模塊,在導入時,也可以同時將兩者導入。

  1. // main.js 
  2. import name, { getName } from './module.js' 
  3.  
  4. //module.js 
  5. const name = 'Shenfq' 
  6. export const getName = () => name 
  7. export default name 

當然,ESM 也提供了重命名的語法,將導入的模塊進行重新命名。

  1. // main.js 
  2. import * as mod from './module.js' 
  3. let name = '' 
  4. name = mod.name 
  5. name = mod.getName() 
  6.  
  7. // module.js 
  8. export const name = 'Shenfq' 
  9. export const getName = () => name 

上述寫法就相當于于將模塊導出的對象進行重新賦值:

  1. // main.js 
  2. import { name, getName } from './module.js' 
  3. const mod = { name, getName } 

同時也可以對單獨的變量進行重命名:

  1. // main.js 
  2. import { name, getName as getModName } 

導入同時進行導出

如果有兩個模塊 a 和 b ,同時引入了模塊 c,但是這兩個模塊還需要導入模塊 d,如果模塊 a、b 在導入 c 之后,再導入 d 也是可以的,但是有些繁瑣,我們可以直接在模塊 c 里面導入模塊 d,再把模塊 d 暴露出去。

模塊關系

  1. // module_c.js 
  2. import { name, getName } from './module_d.js' 
  3. export { name, getName } 

這么寫看起來還是有些麻煩,這里 ESM 提供了一種將 import 和 export 進行結合的語法。

  1. export { name, getName } from './module_d.js' 

上面是 ESM 規范的一些基本語法,如果想了解更多,可以翻閱阮老師的 《ES6 入門》。

ESM 與 CommonJS 的差異

首先肯定是語法上的差異,前面也已經簡單介紹過了,一個使用 import/export 語法,一個使用 require/module 語法。

另一個 ESM 與 CommonJS 顯著的差異在于,ESM 導入模塊的變量都是強綁定,導出模塊的變量一旦發生變化,對應導入模塊的變量也會跟隨變化,而 CommonJS 中導入的模塊都是值傳遞與引用傳遞,類似于函數傳參(基本類型進行值傳遞,相當于拷貝變量,非基礎類型【對象、數組】,進行引用傳遞)。

下面我們看下詳細的案例:

CommonJS

  1. // a.js 
  2. const mod = require('./b'
  3.  
  4. setTimeout(() => { 
  5.   console.log(mod) 
  6. }, 1000) 
  7.  
  8. // b.js 
  9. let mod = 'first value' 
  10.  
  11. setTimeout(() => { 
  12.   mod = 'second value' 
  13. }, 500) 
  14.  
  15. module.exports = mod 
  16. $ node a.js 
  17. first value 

ESM

  1. // a.mjs 
  2. import { mod } from './b.mjs' 
  3.  
  4. setTimeout(() => { 
  5.   console.log(mod) 
  6. }, 1000) 
  7.  
  8. // b.mjs 
  9. export let mod = 'first value' 
  10.  
  11. setTimeout(() => { 
  12.   mod = 'second value' 
  13. }, 500) 
  14. $ node --experimental-modules a.mjs 
  15. # (node:99615) ExperimentalWarning: The ESM module loader is experimental. 
  16. second value 

另外,CommonJS 的模塊實現,實際是給每個模塊文件做了一層函數包裹,從而使得每個模塊獲取 require/module、__filename/__dirname 變量。那上面的 a.js 來舉例,實際執行過程中 a.js 運行代碼如下:

  1. // a.js 
  2. (function(exports, require, module, __filename, __dirname) { 
  3.  const mod = require('./b'
  4.   setTimeout(() => { 
  5.     console.log(mod) 
  6.   }, 1000) 
  7. }); 

而 ESM 的模塊是通過 import/export 關鍵詞來實現,沒有對應的函數包裹,所以在 ESM 模塊中,需要使用 import.meta 變量來獲取 __filename/__dirname。import.meta 是 ECMAScript 實現的一個包含模塊元數據的特定對象,主要用于存放模塊的 url,而 node 中只支持加載本地模塊,所以 url 都是使用 file: 協議。

  1. import url from 'url' 
  2. import path from 'path' 
  3. // import.meta: { url: file:///Users/dev/mjs/a.mjs } 
  4. const __filename = url.fileURLToPath(import.meta.url) 
  5. const __dirname = path.dirname(__filename) 

加載的原理

步驟:

  1. Construction(構造):下載所有的文件并且解析為module records。
  2. Instantiation(實例):把所有導出的變量入內存指定位置(但是暫時還不求值)。然后,讓導出和導入都指向內存指定位置。這叫做『linking(鏈接)』。
  3. Evaluation(求值):執行代碼,得到變量的值然后放到內存對應位置。

模塊記錄

所有的模塊化開發,都是從一個入口文件開始,無論是 Node.js 還是瀏覽器,都會根據這個入口文件進行檢索,一步一步找到其他所有的依賴文件。

  1. // Node.js: main.mjs 
  2. import Log from './log.mjs' 
  3. <!-- chrome、firefox --> 
  4. <script type="module" src="./log.js"></script> 

值得注意的是,剛開始拿到入口文件,我們并不知道它依賴了哪些模塊,所以必須先通過 js 引擎靜態分析,得到一個模塊記錄,該記錄包含了該文件的依賴項。所以,一開始拿到的 js 文件并不會執行,只是會將文件轉換得到一個模塊記錄(module records)。所有的 import 模塊都在模塊記錄的 importEntries 字段中記錄,更多模塊記錄相關的字段可以查閱tc39.es。

模塊記錄

模塊構造

得到模塊記錄后,會下載所有依賴,并再次將依賴文件轉換為模塊記錄,一直持續到沒有依賴文件為止,這個過程被稱為『構造』(construction)。

模塊構造包括如下三個步驟:

  1. 模塊識別(解析依賴模塊 url,找到真實的下載路徑);
  2. 文件下載(從指定的 url 進行下載,或從文件系統進行加載);
  3. 轉化為模塊記錄(module records)。

對于如何將模塊文件轉化為模塊記錄,ESM 規范有詳細的說明,但是在構造這個步驟中,要怎么下載得到這些依賴的模塊文件,在 ESM 規范中并沒有對應的說明。因為如何下載文件,在服務端和客戶端都有不同的實現規范。比如,在瀏覽器中,如何下載文件是屬于 HTML 規范(瀏覽器的模塊加載都是使用的 script 標簽)。

雖然下載完全不屬于 ESM 的現有規范,但在 import 語句中還有一個引用模塊的 url 地址,關于這個地址需要如何轉化,在 Node 和瀏覽器之間有會出現一些差異。簡單來說,在 Node 中可以直接 import 在 node_modules 中的模塊,而在瀏覽器中并不能直接這么做,因為瀏覽器無法正確的找到服務器上的 node_modules 目錄在哪里。好在有一個叫做 import-maps 的提案,該提案主要就是用來解決瀏覽器無法直接導入模塊標識符的問題。但是,在該提案未被完全實現之前,瀏覽器中依然只能使用 url 進行模塊導入。

  1. <script type="importmap"
  2.   "imports": { 
  3.    "jQuery""/node_modules/jquery/dist/jquery.js" 
  4.   } 
  5. </script> 
  6. <script type="module"
  7.  import $ from 'jQuery' 
  8.   $(function () { 
  9.     $('#app').html('init'
  10.   }) 
  11. </script> 

下載好的模塊,都會被轉化為模塊記錄然后緩存到 module map 中,遇到不同文件獲取的相同依賴,都會直接在 module map 緩存中獲取。

  1. // log.js 
  2. const log = console.log 
  3. export default log 
  4.  
  5. // file.js 
  6. export {  
  7.   readFileSync as read
  8.   writeFileSync as write 
  9. from 'fs' 

模塊實例

獲取到所有依賴文件并建立好 module map 后,就會找到所有模塊記錄,并取出其中的所有導出的變量,然后,將所有變量一一對應到內存中,將對應關系存儲到『模塊環境記錄』(module environment record)中。當然當前內存中的變量并沒有值,只是初始化了對應關系。初始化導出變量和內存的對應關系后,緊接著會設置模塊導入和內存的對應關系,確保相同變量的導入和導出都指向了同一個內存區域,并保證所有的導入都能找到對應的導出。

模塊連接

由于導入和導出指向同一內存區域,所以導出值一旦發生變化,導入值也會變化,不同于 CommonJS,CommonJS 的所有值都是基于拷貝的。連接到導入導出變量后,我們就需要將對應的值放入到內存中,下面就要進入到求值的步驟了。

模塊求值

求值步驟相對簡單,只要運行代碼把計算出來的值填入之前記錄的內存地址就可以了。到這里就已經能夠愉快的使用 ESM 模塊化了。

ESM的進展

因為 ESM 出現較晚,服務端已有 CommonJS 方案,客戶端又有 webpack 打包工具,所以 ESM 的推廣不得不說還是十分艱難的。

客戶端

我們先看看客戶端的支持情況,這里推薦大家到 Can I Use 直接查看,下圖是 2019/11的截圖。

Can I use

目前為止,主流瀏覽器都已經支持 ESM 了,只需在 script 標簽傳入指定的 type="module" 即可。

  1. <script type="module" src="./main.js"></script> 

另外,我們知道在 Node.js 中,要使用 ESM 有時候需要用到 .mjs 后綴,但是瀏覽器并不關心文件后綴,只需要 http 響應頭的MIME類型正確即可(Content-Type: text/javascript)。同時,當 type="module" 時,默認啟用 defer 來加載腳本。這里補充一張 defer、async 差異圖。

img

我們知道瀏覽器不支持 script 的時候,提供了 noscript 標簽用于降級處理,模塊化也提供了類似的標簽。

  1. <script type="module" src="./main.js"></script> 
  2. <script nomodule> 
  3.   alert('當前瀏覽器不支持 ESM !!!'
  4. </script> 

這樣我們就能針對支持 ESM 的瀏覽器直接使用模塊化方案加載文件,不支持的瀏覽器還是使用 webpack 打包的版本。

  1. <script type="module" src="./src/main.js"></script> 
  2. <script nomodule src="./dist/app.[hash].js"></script> 

預加載

我們知道瀏覽器的 link 標簽可以用作資源的預加載,比如我需要預先加載 main.js 文件:

  1. <link rel="preload" href="./main.js"></link> 

如果這個 main.js 文件是一個模塊化文件,瀏覽器僅僅預先加載單獨這一個文件是沒有意義的,前面我們也說過,一個模塊化文件下載后還需要轉化得到模塊記錄,進行模塊實例、模塊求值這些操作,所以我們得想辦法告訴瀏覽器,這個文件是一個模塊化的文件,所以瀏覽器提供了一種新的 rel 類型,專門用于模塊化文件的預加載。

  1. <link rel="modulepreload" href="./main.js"></link> 

現狀

雖然主流瀏覽器都已經支持了 ESM,但是根據 chrome 的統計,有用到 <script type="module"> 的頁面只有 1%。截圖時間為 2019/11。

統計

服務端

瀏覽器能夠通過 script 標簽指定當前腳本是否作為模塊處理,但是在 Node.js 中沒有很明確的方式來表示是否需要使用 ESM,而且 Node.js 中本身就已經有了 CommonJS 的標準模塊化方案。就算開啟了 ESM,又通過何種方式來判斷當前入口文件導入的模塊到底是使用的 ESM 還是 CommonJS 呢?為了解決上述問題,node 社區開始出現了 ESM 的相關草案,具體可以在 github 上查閱。

2017年發布的 Node.js 8.5.0 開啟了 ESM 的實驗性支持,在啟動程序時,加上 --experimental-modules 來開啟對 ESM 的支持,并將 .mjs 后綴的文件當做 ESM 來解析。早期的期望是在 Node.js 12 達到 LTS 狀態正式發布,然后期望并沒有實現,直到最近的 13.2.0 版本才正式支持 ESM,也就是取消了 --experimental-modules 啟動參數。具體細節可以查看 Node.js 13.2.0 的官方文檔。

關于 .mjs 后綴社區有兩種完全不同的態度。支持的一方認為通過文件后綴區分類型是最簡單也是最明確的方式,且社區早已有類似案例,例如,.jsx 用于 React 組件、.ts 用于 ts 文件;而支持的一方認為,.js 作為 js 后綴已經存在這么多年,視覺上很難接受一個 .mjs 也是 js 文件,而且現有的很多工具都是以 .js 后綴來識別 js 文件,如果引入了 .mjs 方案,就有大批量的工具需要修改來有效的適配 ESM。

所以除了 .mjs 后綴指定 ESM 外,還可以使用 pkg.json 文件的 type 屬性。如果 type 屬性為 module,則表示當前模塊應使用 ESM 來解析模塊,否則使用 CommonJS 解析模塊。

  1.   "type""module" // module | commonjs(default

當然有些本地文件是沒有 pkg.json 的,但是你又不想使用 .mjs 后綴,這時候只需要在命令行加上一個啟動參數 --input-type=module。同時 input-type 也支持 commonjs 參數來指定使用 CommonJS(-—input-type=commonjs)。

總結一下,Node.js 中,以下三種情況會啟用 ESM 的模塊加載方式:

  1. 文件后綴為.mjs;
  2. pkg.json 中 type 字段指定為 module;
  3. 啟動參數添加 --input-type=module。

同樣,也有三種情況會啟用 CommonJS 的模塊加載方式:

  1. 文件后綴為.cjs;
  2. pkg.json 中 type 字段指定為 commonjs;
  3. 啟動參數添加 --input-type=commonjs。

雖然 13.2 版本去除了 --experimental-modules 的啟動參數,但是按照文檔的說法,在 Node.js 中使用 ESM 依舊是實驗特性。

“Stability: 1 - Experimental

不過,相信等到 Node.js 14 LTS 版本發布時,ESM 的支持應該就能進入穩定階段了,這里還有一個 Node.js 關于 ESM 的整個計劃列表可以查閱。

文章發表時,Node.js 14 已經正式發布。

參考

nodejs/modules

Module specifiers: what’s new with ES modules?

 

圖說 ES Modules(ES modules: A cartoon deep-dive)

本文轉載自微信公眾號「 更了不起的前端」,可以通過以下二維碼關注。轉載本文請聯系 更了不起的前端公眾號。

 

責任編輯:武曉燕 來源: 更了不起的前端
相關推薦

2022-09-05 09:01:13

前端模塊化

2019-12-02 16:05:10

前端模塊化JavaScript

2020-09-17 10:30:21

前端模塊化組件

2013-08-20 15:31:18

前端模塊化

2022-03-11 13:01:27

前端模塊

2023-05-24 10:35:11

Node.jsES模塊

2014-04-27 10:16:31

QCon北京2014Andrew Bett

2019-08-28 16:18:39

JavaScriptJS前端

2016-09-23 11:08:35

前端Javascript模塊化

2013-03-19 10:50:38

2013-03-11 10:00:13

前端模塊化

2018-12-18 11:20:28

前端模塊化JavaScript

2016-10-09 11:03:41

Javascript模塊化Web

2013-03-11 10:10:03

2022-09-21 11:51:26

模塊化應用

2015-10-10 10:01:28

前端模塊化webpack

2017-05-18 10:23:55

模塊化開發RequireJsJavascript

2015-10-10 11:29:45

Java模塊化系統初探

2010-05-28 10:31:28

模塊化IT

2021-07-14 09:26:51

UPS電源模塊化
點贊
收藏

51CTO技術棧公眾號

人人玩人人添人人澡欧美| 国产大学生校花援交在线播放| 99热在线成人| 欧美成人三级在线| 免费高清在线观看免费| 欧美成人xxx| 成人国产精品视频| 国产精品久久久久久久久久小说 | 久久久精品三级| 国产乱色在线观看| 91社区在线播放| 91在线观看免费高清| 日韩女同强女同hd| 天天操综合网| 精品亚洲一区二区三区四区五区| 日本中文字幕影院| 综合另类专区| 亚洲国产成人高清精品| 亚洲人成网站在线播放2019| 亚洲精品无遮挡| 久热成人在线视频| 91精品国产乱码久久久久久蜜臀| 日韩精品久久久久久久的张开腿让| 在线综合色站| 欧美精选在线播放| av免费在线播放网站| 免费网站在线观看人| 国产精品卡一卡二卡三| 久久精品丝袜高跟鞋| 国产aⅴ一区二区三区| 日本美女一区二区| 欧美综合第一页| 国产午夜精品无码| 欧美另类综合| 久久精品成人欧美大片古装| 亚洲一级中文字幕| 精品综合久久88少妇激情| 欧美一区二区三区系列电影| 婷婷丁香激情网| 欧美特黄aaaaaaaa大片| 精品国产乱码久久久久久天美| 粉嫩av一区二区三区天美传媒| 91精品国产综合久久久久久豆腐| 久久久久88色偷偷免费| 国产精品一区在线观看| 亚洲精品字幕在线| 国产高清成人在线| 3d动漫精品啪啪一区二区三区免费 | 欧美三级不卡| 欧美日韩国产成人在线观看| 特一级黄色录像| 久久久久国产精品| 久久精品国产一区| 久草综合在线视频| 一区二区电影| 欧美黑人极品猛少妇色xxxxx| 黄色a级片在线观看| 在线成人直播| 九九热在线精品视频| 国产盗摄一区二区三区在线| 欧美日本亚洲韩国国产| 欧美老肥婆性猛交视频| 欧美人妻一区二区| 亚洲成色精品| 国产va免费精品高清在线观看| 人妻丰满熟妇av无码区| 久久综合五月| 国产精品小说在线| 一级久久久久久久| 国产精品白丝av| 成人91视频| 天天在线女人的天堂视频| 99精品视频在线播放观看| 欧美亚洲精品日韩| 日韩三级影院| 亚洲午夜免费福利视频| 1024av视频| 国产精品videossex撒尿| 欧美精品久久一区| 欧美性生交xxxxx| 蜜桃成人av| 久久精品视频中文字幕| 久久精品欧美一区二区| 久久免费国产| 成人国产在线激情| 日本精品久久久久| 国产午夜精品福利| 米仓穗香在线观看| 日韩av影片| 欧美日韩国产综合一区二区| 无码国产精品一区二区高潮| 欧美人妖视频| 日韩视频免费在线观看| 久久免费公开视频| 丝袜亚洲精品中文字幕一区| 成人在线精品视频| 日本人妖在线| 亚洲另类中文字| 欧美啪啪免费视频| 欧美天堂一区| 日韩av综合中文字幕| 国产wwwwxxxx| 久久国产精品毛片| 97人人澡人人爽| 成人在线播放视频| 污片在线观看一区二区| 污污的视频免费| 欧美三级自拍| 欧美成人午夜激情视频| 成人黄色免费网| 成人av网站在线| 亚洲三区四区| 国产精品一区二区av影院萌芽| 欧美精品丝袜久久久中文字幕| 亚洲成人av免费在线观看| 国产精品99一区二区三| 韩国福利视频一区| 国产欧美一级片| 国产欧美精品一区aⅴ影院| 亚洲国产成人精品无码区99| 日韩美女在线| 国产一区二区三区在线免费观看| 久久免费视频播放| 国产经典欧美精品| 正在播放91九色| 朝桐光一区二区| 亚洲精品在线不卡| 日韩三级视频在线| 国产成人免费av在线| 欧美aaa在线观看| 国产成人免费精品| 亚洲日韩第一页| 中日韩黄色大片| 成人深夜在线观看| 久久久久久久香蕉| 麻豆精品久久| 久久国产精彩视频| 国产又粗又猛又爽又黄的| 国产蜜臀av在线一区二区三区| 免费黄色日本网站| 卡通动漫精品一区二区三区| 欧美精品videosex牲欧美| 国产精品国产一区二区三区四区| 国产日韩欧美精品在线| 熟妇人妻va精品中文字幕| 曰本一区二区三区视频| 2019中文在线观看| 香蕉视频成人在线| 精品久久久久久久久久久久久久| 亚洲色偷偷色噜噜狠狠99网| 国产精品大片| 国产综合动作在线观看| 阿v视频在线| 日韩电影大全免费观看2023年上| 国产女同在线观看| 91麻豆免费在线观看| 一女被多男玩喷潮视频| 欧美女优在线视频| 国产精品九九九| av国产在线观看| 5858s免费视频成人| 希岛爱理中文字幕| 久久国产精品99久久久久久老狼 | 色美美综合视频| 无码 人妻 在线 视频| 奇米精品一区二区三区在线观看| 亚洲国产婷婷香蕉久久久久久99| 国产亚洲人成a在线v网站 | 欧美gv在线| 亚洲欧美日韩天堂| 伊人精品一区二区三区| 亚洲人精品一区| 国产精品成人无码专区| 美女网站久久| 艳母动漫在线免费观看| aiai久久| 国产91九色视频| 久久国产精品一区| 亚洲第一福利网站| www.日韩一区| 亚洲精品日产精品乱码不卡| 国产精品手机在线观看| 久久婷婷亚洲| 亚洲五码在线观看视频| 欧美美女在线直播| 成人精品久久av网站| 里番在线播放| 一区二区在线免费视频| 99久久夜色精品国产亚洲| 亚洲成人av福利| av在线播放中文字幕| 国产91高潮流白浆在线麻豆 | 国产丝袜视频一区| 一二三区在线播放| 精品成人在线视频| 日本一级特级毛片视频| 99国产精品久久久久久久久久 | 亚洲网一区二区三区| 欧美一区二区三区图| 成人免费网站在线观看视频| 日韩电影中文字幕av| 国产精品久久久久久久免费看| 亚洲不卡一区二区三区| 日韩免费av一区| 91亚洲精品乱码久久久久久蜜桃| 中文字幕剧情在线观看| 另类av一区二区| 僵尸世界大战2 在线播放| 青青草原综合久久大伊人精品| 国产乱码精品一区二区三区中文| 78精品国产综合久久香蕉| 亚洲91av视频| 伊人手机在线| 中文字幕视频在线免费欧美日韩综合在线看 | 中国一级免费毛片| 亚洲乱码精品一二三四区日韩在线| 亚洲一区二区三区蜜桃| www.99精品| 免费人成视频在线播放| 麻豆精品视频在线观看| 免费在线观看的av网站| 亚洲精品综合| 国产91沈先生在线播放| 亚洲精品888| 亚洲日本欧美在线| 精品久久国产| 欧美精品久久久| 日韩精品导航| 国产视频99| 成午夜精品一区二区三区软件| 亚洲一区美女视频在线观看免费| 日韩av一级| 国产91免费观看| 在线黄色的网站| 国产91成人在在线播放| 丝袜老师在线| 8050国产精品久久久久久| free性欧美| 欧美大片大片在线播放| 中文国产字幕在线观看| 免费不卡欧美自拍视频| 国产黄色小视频在线| 久久久精品一区二区| 里番在线观看网站| 综合国产在线视频| 蜜桃视频在线观看免费视频网站www| 在线观看国产欧美| 中文字幕在线观看日本| 日韩中文字幕免费视频| 秋霞影院午夜丰满少妇在线视频| 中文字幕在线精品| 老司机免费在线视频| xxx一区二区| 91在线中文| 欧美黑人性视频| 成人免费观看在线观看| 51精品国产黑色丝袜高跟鞋| 亚洲淫成人影院| 国产精品观看在线亚洲人成网| 欧美香蕉视频| 国产在线高清精品| 亚洲视频国产精品| 久久99精品久久久久久久久久| 蜜臀91精品国产高清在线观看| 日本视频一区二区不卡| 日韩精品一卡| 一二三在线视频| 中日韩男男gay无套| 蜜臀久久99精品久久久酒店新书| 久久精品国产在热久久| 日本一本在线视频| 99re66热这里只有精品3直播 | 亚洲欧美国产毛片在线| 精品人妻在线播放| 欧美色播在线播放| 中文字幕777| 日韩午夜av电影| 深夜福利视频在线免费观看| 中文字幕久久久| 日本一本在线免费福利| 国产91久久婷婷一区二区| 国产一区二区视频在线看| 精品产品国产在线不卡| 精品国产一区探花在线观看| 久久av高潮av| 日韩中文字幕不卡| 国产a√精品区二区三区四区| 91视视频在线直接观看在线看网页在线看| 91l九色lporny| 一区av在线播放| 天堂av免费在线观看| 日韩欧美美女一区二区三区| 欧美日韩在线中文字幕| 成年人精品视频| 高清电影一区| 不卡一区二区三区视频| 精品久久不卡| 黄色一级在线视频| 国产在线播放一区三区四| 亚洲天堂视频一区| 亚洲香肠在线观看| 亚洲永久精品视频| 日韩激情片免费| 在线三级电影| 国产精品永久免费| 亚洲区小说区| 欧美久久在线观看| 理论片日本一区| 亚洲永久精品ww.7491进入| 亚洲制服欧美中文字幕中文字幕| 免费一级a毛片| 日韩av中文在线| hd国产人妖ts另类视频| 1区1区3区4区产品乱码芒果精品| 超碰成人久久| 日韩av片在线看| 成人激情黄色小说| 精品人妻伦九区久久aaa片| 91福利国产成人精品照片| 欧日韩在线视频| 欧美另类老女人| 视频欧美精品| 亚洲欧洲精品在线观看| 久久亚洲影院| 魔女鞋交玉足榨精调教| 亚洲第一久久影院| 国内精品久久久久久久久久久 | 欧美伦理一区二区| 极品中文字幕一区| 国产精品一级无码| 一区二区三区在线看| 一区二区日韩视频| 日韩一区二区三区国产| 视频在线日韩| 婷婷精品国产一区二区三区日韩| 老鸭窝91久久精品色噜噜导演| 国产福利短视频| 粉嫩av一区二区三区免费野| 欧美 日韩 人妻 高清 中文| 欧美激情视频一区二区| 久久精品免视看国产成人| mm131午夜| 国产精品一区在线观看你懂的| 51精品免费网站| 91精品欧美久久久久久动漫 | 手机免费看av网站| 中文字幕在线免费不卡| 亚洲系列第一页| 久久精品青青大伊人av| 欧美专区一区| www污在线观看| eeuss国产一区二区三区| 日本一级淫片免费放| 亚洲精品中文字幕有码专区| 神马电影网我不卡| 亚洲国产一区二区在线| 久久97超碰色| 福利所第一导航| 亚洲国产精品成人一区二区| 国产自产自拍视频在线观看| 久久青青草原一区二区| 日韩黄色小视频| 日本一二三区在线观看| 日韩精品一区国产麻豆| gogo久久| 日韩中文一区二区三区| 九色综合国产一区二区三区| 青青草原国产视频| 日韩av在线电影网| 最新日韩一区| 91精品国产毛片武则天| 99r国产精品| 中文字幕黄色av| 欧美日韩成人在线视频| 欧美亚洲色图校园春色| xx欧美撒尿嘘撒尿xx| 一区二区三区在线看| 香蕉视频911| 成人亲热视频网站| 在线观看日韩av电影| 国产sm调教视频| 日韩精品专区在线影院重磅| 毛片电影在线| 夜夜春亚洲嫩草影视日日摸夜夜添夜 | 亚洲午夜久久久久久久久电影网| 亚洲av成人无码网天堂| 国产精品色午夜在线观看| 欧美日本精品| 日本一卡二卡在线播放| 日韩欧美国产小视频| 国产精品高清乱码在线观看 | 极品久久久久久久| 日韩免费一区二区| 日韩电影免费观看高清完整版| 中文字幕人成一区| 久久奇米777| 国产黄a三级三级看三级| 日韩免费观看视频| 欧美日韩爆操| 娇小11一12╳yⅹ╳毛片|