整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          javy:將 JavaScript 轉化為 WebA

          javy:將 JavaScript 轉化為 WebAssembly如此簡單!

          家好,很高興又見面了,我是"高級前端?進階?",由我帶著大家一起關注前端前沿、深入前端底層技術,大家一起進步,也歡迎大家關注、點贊、收藏、轉發!

          高級前端?進階

          前言

          本文主要和大家介紹將 JavaScript 轉化為 WebAssembly的工具鏈 javy。在年初,我也確實使用 WebAssembly 將客戶端應用成功移植到了 Web,這也是為什么我一直對 WebAssembly 充滿好奇的原因。我甚至在頭條上開了一個合集《WebAssembly 前沿技術》來專門探討 WebAssembly ,并將持續關注 WebAssembly 的最新動態。

          下面是已發布部分文章傳送門:

          • 《 2023 年讓 WebAssembly 大火的 10+應用!》
          • 《 萬字長文!2023 年 WebAssembly 各個運行時性能對比!》
          • 《 讓 JavaScript 在 WebAssembly 上加速運行!》

          正如大家所看到的,當我們還在遲疑是否要在日常開發中引入 WebAssembly 的時候,很多優秀的應用、工具已經開始吃 WebAssembly 的紅利了,而且取得了不錯的成就,這可能也是為什么各個瀏覽器廠商、開發者如此熱衷 WebAssembly 的原因吧。

          WebAssembly 中的 JavaScript 是最近技術圈發展的產物,但是將 JavaScript 編譯成 WebAssembly 不同于使用 JavaScript 與 WebAssembly 模塊通信。本文重點介紹如何獲取 JavaScript 代碼并將其構建到 WebAssembly 模塊中。

          話不多說,直接開始進入正題!

          1.如何將 JavaScript 編譯為 WebAssembly

          1.1 構建環境準備

          • rustup
          • 穩定的 Rust 環境(rustup install stable && rustup default stable)
          • wasm32-wasi,可以通過 rustup target add wasm32-wasi 安裝
          • cmake,根據操作系統和體系結構,默認情況下可能不會安裝它。 在 Mac 上,可以通過 brew install cmake 與 homebrew 一起安裝
          • Rosetta 2 如果在 Apple Silicon 上運行 MacOS,可以通過 softwareupdate --install-rosetta 安裝
          • 通過運行 make download-wasi-sdk 安裝 wasi-sdk

          1.2 開發環境準備

          • wasmtime-cli,可以通過 cargo install wasmtime-cli 安裝(cargo-wasi 需要)
          • cargo-wasi,可以通過 cargo install cargo-wasi
          • 安裝 wizer,可以通過 cargo install wizer --all-features 安裝

          1.3 開始使用 Javy

          安裝所有依賴項后運行 make,現在應該可以訪問 target/release/javy 中的可執行文件?;蛘呖梢赃\行 make && cargo install --path crates/cli, 運行命令后,將獲得可執行文件的全局安裝。

          Javy 底層基于 QuickJS, 用于在 WebAssembly 上運行 JavaScript 代碼。 Javy 獲取 JavaScript 代碼,并在 WebAssembly 嵌入式 JavaScript 運行時中執行它。下面是官方對 Javy 的定位:

          Javy: A JavaScript to WebAssembly toolchain

          Javy 生成的模塊僅設計為 WASI 并遵循命令模式, 任何輸入都必須通過 stdin 傳遞,任何輸出都將放在 stdout 中,這在從自定義嵌入調用 Javy 模塊時尤為重要。

          在像 Wasmtime 這樣的運行時中,wasmtime-wasi 可用于設置輸入和檢索輸出。比如下面的 JS 代碼:

          //從標準輸入讀取輸入
          const input=readInput();
          //使用輸入調用函數
          const result=foo(input);
          // 將結果寫入標準輸出
          writeOutput(result);
          // 入口函數
          function foo(input) {
            return { foo: input.n + 1, newBar: input.bar + '!' };
          }
          // Read input from stdin
          function readInput() {
            const chunkSize=1024;
            const inputChunks=[];
            let totalBytes=0;
          
            //讀取所有可用字節
            while (1) {
              const buffer=new Uint8Array(chunkSize);
              // 標準輸入文件描述符
              const fd=0;
              const bytesRead=Javy.IO.readSync(fd, buffer);
              totalBytes +=bytesRead;
              if (bytesRead===0) {
                break;
              }
              inputChunks.push(buffer.subarray(0, bytesRead));
            }
            // 將輸入組裝成單個 Uint8Array
            const { finalBuffer }=inputChunks.reduce(
              (context, chunk)=> {
                context.finalBuffer.set(chunk, context.bufferOffset);
                context.bufferOffset +=chunk.length;
                return context;
              },
              { bufferOffset: 0, finalBuffer: new Uint8Array(totalBytes) }
            );
            return JSON.parse(new TextDecoder().decode(finalBuffer));
          }
          //將輸出寫入標準輸出
          function writeOutput(output) {
            const encodedOutput=new TextEncoder().encode(JSON.stringify(output));
            const buffer=new Uint8Array(encodedOutput);
            // 標準輸出文件描述符
            const fd=1;
            Javy.IO.writeSync(fd, buffer);
          }

          通過以下方式從 JavaScript 創建 WebAssembly 二進制文件:

          javy compile index.js -o destination/index.wasm

          然后,可以使用 WebAssembly 引擎執行 WebAssembly 二進制文件:

          $ echo '{ "n": 2, "bar": "baz" }' | wasmtime index.wasm
          {"foo":3,"newBar":"baz!"}%

          2. 創建和使用動態鏈接模塊

          在某些情況下,開發者可能希望或需要使用 Javy 生成更小的 Wasm 模塊。 在調用 Javy 時使用 -d 標志將創建一個動態鏈接模塊,該模塊的文件大小比靜態鏈接模塊小得多。 靜態鏈接模塊將 JS 引擎嵌入模塊內部,而動態鏈接模塊依賴 Wasm 導入來提供 JS 引擎。 動態鏈接模塊有特殊要求,靜態鏈接模塊沒有也不會在不滿足這些要求的 WebAssembly 運行時中執行。

          要成功實例化和運行動態鏈接的 Javy 模塊,執行環境必須提供一個 javy_quickjs_provider_v1 命名空間,用于導入該鏈接到 javy_quickjs_provider.wasm 模塊提供的導出。 在不提供此導入的環境中無法實例化動態鏈接的模塊。

          動態鏈接的 Javy 模塊與 QuickJS 綁定,因為它們使用 QuickJS 的字節碼表示。

          javy_quickjs_provider.wasm 模塊在使用的 Javy 版本中作為資產提供,也可以通過運行 javy emit-provider -o <path> 將模塊寫入 <path> 來獲取。

          $ echo 'console.log("hello world!");' > my_code.js
          $ javy compile -d -o my_code.wasm my_code.js
          $ javy emit-provider -o provider.wasm
          $ wasmtime run --preload javy_quickjs_provider_v1=provider.wasm my_code.wasm
          hello world!

          3.使用 quickjs-wasm-rs 構建自己的工具鏈

          作為該項目一部分的 quickjs-wasm-rs crate 可以用作針對 Wasm 的 Rust crate 的一部分,以自定義 Rust crate 如何與 QuickJS 交互。

          當嘗試在 Wasm 模塊中使用 JavaScript 而 Javy 不滿足您的需求時,這可能很有用,因為 quickjs-wasm-rs 包含序列化程序,可以更輕松地在主機代碼和 Wasm 代碼之間發送結構化數據(例如,字符串或對象)。

          4.其他相關討論

          • 《知乎:JavaScript 能不能編譯成 WebAssembly ?》
          • 《使用 Javy 和 msgpack-tools 將 JavaScript 編譯為 WebAssembly》
          • 《讓 JavaScript 在 WebAssembly 上加速運行!》

          5.本文總結

          本文主要和大家介紹將 JavaScript 轉化為 WebAssembly的工具鏈 javy。因為篇幅有限,文章并沒有過多展開,如果有興趣,可以在我的主頁繼續閱讀,同時文末的參考資料提供了大量優秀文檔以供學習。最后,歡迎大家點贊、評論、轉發、收藏!


          參考資料

          https://www.fermyon.com/wasm-languages/javascript

          https://blog.csdn.net/tzllxya/article/details/90675984

          https://github.com/Shopify/javy

          https://www.wasm.builders/gunjan_0307/compiling-javascript-to-wasm-34lk

          https://surma.dev/things/compile-js/

          https://www.wasm.builders/deepanshu1484/javascript-and-wasi-24k8

          https://github.com/ludocode/msgpack-tools

          https://www.linkedin.com/pulse/differences-between-static-dynamic-libraries-sergio-monroy

          封面圖:Navdeep Singh Gill | 13 October 2022的《WebAssembly vs JavaScript | The Ultimate Guide》

          下將以Linux為例

          一、Linux安裝chrome

          獲取安裝包

          # wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm

          安裝依賴

          # yum install -y lsb

          # yum install -y libXScrnSaver

          # yum install liberation-fonts

          # yum install vulkan

          本地安裝

          # yum localinstall google-chrome-stable_current_x86_64.rpm

          命令執行完成以后可通過以下命令查看chrome的版本

          # google-chrome -version

          如果正常顯示chrome版本號表示我們的chrome已經安裝完成

          二、生成圖片和PDF文件

          1、生成圖片


          #通過URL地址生成

          google-chrome --headless --disable-gpu --screenshot=/data/app-server/google/2.png --window-size=630,1100 --hide-scrollbars --no-sandbox https://resource.xgjk.info/form/1660635773921_1973.html


          #通過本地文件生成

          google-chrome-stable --no-sandbox --headless --disable-gpu --screenshot=test.png -run-all-compositor-stages-before-draw --window-size=400,1200 /data/app-server/google/chufang.html


          2、生成PDF


          #通過URL地址生成

          google-chrome --headless --disable-gpu --no-sandbox --print-to-pdf-no-header --print-to-pdf=/data/app-server/google/18.pdf https://resource.xgjk.info/form/1660635773921_1973.html


          #通過本地文件生成

          google-chrome --headless --disable-gpu --no-sandbox --print-to-pdf-no-header --print-to-pdf=/data/app-server/google/18.pdf /data/app-server/google/chufang.html


          --screenshot 圖片位置

          --window-size 圖片寬高

          --print-to-pdf PF文件位置

          者 | kate holterhoff(RedMonk)

          譯者 | 核子可樂

          策劃 | Tina


          隨著整個軟件行業正逐漸轉向以打包、托管與抽象解決方案為主體的新形態,后端與基礎設施帶來的麻煩正越來越少,而立足堆棧頂部的前端工程師開始成為施展空間最大的時代寵兒。甚至不只是他們,如今無論是前端、后端還是運維開發者,他們在描述自己的工作流程時普遍表示,會盡可能將底層問題交給托管服務商打理。


          換句話說,前端開發已經不再是系統生命周期中的輔助性要素。


          關于前端未來圖景的討論目前頗為流行。雖然有觀點強烈反對 AI 崛起意味著“前端開發既消亡”的判斷,但也有人認為 AI 及無代碼/低代碼將增強前端開發者群體、而非直接將其取代。但縱觀這種種意見交鋒,我發現人們普遍忽略了一個重要問題:隨著抽象解決方案不斷改善后端與運營層面的工作難度,前端開發者在采購決策中的話語權將持續增長。

          從 Baas 到 PartyKit

          讓我們先從專為前端工程師提供服務的供應商說起,包括如何利用云抽象確立自身市場地位。



          初次測試 @partykit_io


          我喜歡構建實時應用程序,所以很高興終于親自嘗試了一回。我是 @threepointone 的忠實粉絲**pic.twitter.com/JX1SR5CX7c


          — nader dabit (@dabit3)2023年11月30日


          PartyKit 公司 CEO Sunil Pal 受邀參加了 Changelog 前端播客 JS Party。Pai 不僅在 React、JavaScript 和 CSS 領域負有盛名,PartyKit 還專門面向前端工程師群體。Pai 的最新項目憑借對實時同步的顯著簡化而受到廣泛關注——長久以來,這個問題一直困擾著希望允許多位用戶同時工作的多人協作類應用開發者們(包括 Figma、Google Docs 還有 Deplit)。


          PartyKit 代表著前端崛起的又一個令人信服的案例。PartyKit 不僅證明 JS 領域仍在醞釀創新,也表明了前端買家市場的穩健性。供應商們注意到專門針對前端開發者的平臺能夠獲得成功,因此渴望推出自己的方案來滿足需求。JS Party 播客聯席主持人 Kevin Ball 表示:


          我喜歡 PartyKit 說過的一句話:“它就像是 Vercel 或者 Netlify,只是采取實時構建?!盫ercel 和 Netlify 模式都很偉大,它們的亮點就在于能把前端開發者的很多任務承接過來,不但讓部署更加輕松易行、而且能夠輕松與其他方案對接。而多人協作卻長期做不到這一點。Ball 認為,這些為了消除后端運營管理而誕生的平臺在市場上開創了先河。除了前提提到的 Vercel 和 Netlify 之外,還包括 Supabase、谷歌 Firebase、MongoDB Atlas、亞馬遜云科技的 Amplify 以及 Appwrite 等 BaaS 公司。另外還有 Zephyr Cloud 之類的廠商,這是一家由微前端容器化技術 Module Federation 的締造者及維護者建立的云服務商,旨在降低微前端的開發和管理難度。


          總之,越來越多的科技大廠和初創公司都開始將前端開發者視為消費力強、規??捎^的目標受眾。人們也都意識到,自托管運營與基礎設施會帶來沉重的認知負荷,更不用說數據庫、安全性、身份驗證和可觀察性等帶來的巨大挑戰?,F在,前端開發者可以把這一切都交給服務商負責,不再需要內部處理。

          抽象度持續提升


          越抽象越好……


          — Betty Junod (@BettyJunod)2019年9月6日


          隨著云托管抽象的興起,一系列軟件開發趨勢也由此成形,讓前端開發者獲得了更具份量的話語權。抽象解決方案簡化并擴展對原語的訪問,降低了原語管理難度。仍然以 PartyKit 為例,其中包括 Cloudflare 設計的 Durable Objects 持久對象,它們本質上就是具有內存狀態的 Cloudflare 工作線程。可以看到,這些原語正逐步讓位給托管服務,而由此掀起的趨勢正給前端開發帶來深遠影響。


          首先,軟件開發行業的抽象化進程正在服務和語言層面有所體現。程序員們花在裸機和低級語言編程上的時間越來越少。盡管 C、Assembly 和 Fortran 等人類可讀性較差的語言仍具有一定生命力,而且 Rust 支持者陣容也在不斷擴大,但大多數日常開發工作都集中在為堆棧頂部編寫高級代碼。


          GitHub 發布的 2023 年 Octoverse 現狀報告也體現出這一趨勢。根據相關研究,在“2020 萬開發者”(指擁有 GitHub 賬戶的個人)當中,“過去一年間開發者數量增長了 21%”,其中 JavaScript 仍是最受歡迎的語言。RedMonk 公布的語言排名也符合這一發現,自 2015 年以來,JavaScript 每年都穩居最流行編程語言榜首。事實上,在排名前七位的語言中,有六種純位于堆棧頂部,而且有三種為客戶端語言(分別是 JS、CSS 和 TypeScript)。我們從這些調查中可以得出結論,即隨著軟件領域繼續迅速發展,領域內的大部分新人都集中在了前端開發層面。



          老實說,身為一名開發者,最讓我興奮的就是能在短短幾天內就構建一個項目。


          我熱愛 Next.js、Vercel 和 Tailwind 堆棧讓我能夠快速完成開發的感覺,特別是在跟 @replicatehg 和 @OpenAI 配合使用來開發酷炫 AI 應用的時候。


          除了開發者使用的編程語言之外,現代軟件開發還高度依賴于將繁瑣部分和復雜性服務抽象出來。雖然一部分系統管理員仍在以尖銳的言語對這種趨勢提出批評,但客觀事實表明,將運營部分剝離出來的作法已經越來越普遍。畢竟運營很難、基礎設施很貴,安全性與合規性的風險也很高。

          API 經濟與云原生

          前端開發者江湖地位的提升,源自抽象機制的迅速增加,而且這種趨勢仍將長期持續。托管服務能夠將復雜且耗時的任務(例如用戶身份驗證)以及高監管要求的服務(例如 POS 系統)留給領域專家,以省時省力的方式提高安全性。如此一來,企業就能專注于處理用例中特有的業務邏輯。特別是在前端工具與生態系統配置層面,這種面向抽象的整體轉變也與此前全?;绷鞯氖∮嘘P。全棧工程師的出現雖然對企業雇主有利,但卻受到開發者群體的嚴厲譴責,因為指望開發者承擔一切必然給他們帶來過重的認知負擔。正如 Laurie Voss 所說:


          如果不能把細節都抽象出去,我們根本無法在堆棧中生存下來。下面我們重新審視所有 API 經濟,深入探討抽象這個主題。自云計算誕生以來,API 就一直扮演著重要角色。Salesforce 和 eBay 早在 2000 年就開放了其 Web API 的訪問權限,之后通過提供 API 來擴大市場份額的理念開始“吞噬整個世界”,在現代軟件開發中地位日顯,并為前端工程師們帶來了巨大助益。Couchbase 聯合創始人、目前供職于 Fireproof 公司(一家針對前端開發者的數據庫初創企業)的 J Chris Anderson 表示:


          API 正被全面集成進前端,這也是前端開發者能獲取話語權并掌控采購決策的根本原因。最近,API 驅動開發也開始在大語言模型(LLM)領域全面開花。開發者無需訓練自有模型或在本地進行托管,而可以使用 OpenAI 提供的 ChatGPT、谷歌的 Gemini 或者 Anthropic Claude 等選項輕松創建聊天機器人,使用這些廠商面向開發者提供的直觀無縫 API 集成功能。事實上,OpenAI 的定制化 GPT 還提供個性化體驗,消除了訓練和自托管大模型的復雜挑戰。他們還在認真優化開發者體驗,提供豐富的技術文檔、快速入門指南與 SDK 資源。


          除了通過 API 給前端工程師提供的便利之外,技術廠商還為這部分用戶提供云原生形式的抽象方案。Begin 公司聯合創始人 Brian LeRoux 就對前端開發者群體的前景抱樂觀態度,認為該領域更能發揮云優勢。從技術提供商的角度來看:


          前端工程師是初創公司進軍云市場的絕佳切入點。 由于前端開發者在構建動態及交互式網站時必須考慮后端流程,因此會敏銳地意識到無服務器及云托管方案的重要性。事實上,服務器/客戶端二分模式中仍存在一系列挑戰,往往會占用優秀開發者們大量的時間和精力。

          抽象問題

          當然,對這些高度抽象解決方案的采用同樣需要權衡。抽象產品和服務通常以 API 和庫的形式交付,也就是將他人編寫的代碼移植到開發者自己的項目當中。這既是它的核心賣點,也會帶來巨大風險。抽象解決方案迫使項目呈現出特定形態,因此往往難以擴展。


          大家應該都聽過這個經典案例,就是 Twitter 被迫將后端從 Ruby on Rails 重寫成 Scala(基于 Java 構建)的形式,原因就是像 Java 這樣的低級語言擴展性更好。在涉及繁重的進程與緩存層處理時,像 Java 這樣的語言仍然擁有不可替代的價值。然而,像 Twitter 這樣的大型應用程序屬于極端案例,并非普遍情況。也就是說,這種成長的煩惱并不會阻礙眾多開發者繼續使用 JavaScript 和 TypeScript。順帶一提,Java 22 還采用了高度簡化的語法,因此在提交體驗方面甚至勝過不少其他高級語言。



          看看這簡潔的 @java 22(也可能是 23)語法!


          這樣的更新讓 Java 看起來更類似堆棧頂部的語言。這絕對會吸引到更多全棧工程師。@redmonk pic.twitter.com/9Qmuos5ltW


          — Dr. Kate Holterhoff (@KateHolterhoff)2024年2月26日


          除了擴展問題之外,將復雜性抽象出去的服務和產品在托管時往往成本更高。Vercel 通過將 AWS 原語打包在零配置簡單構建流程中來簡化部署,而用戶則為這樣的便利性體驗付費。這確實導致部分開發者抱怨 Vercel 的使用成本高到離譜,但很多公司還是發現,盡管托管成本愈發夸張,但由于不必聘請工程師來管理基礎設施,所以這仍然物有所值。Branch Insurance 聯合創始人兼 CTO Joe Emison 就提出了利用云服務配合純前端初級開發者推動業務運營的案例:


          由于我們擁有更優質、更強大的云服務可供選擇(包括亞馬遜云科技、Google Cloud Platform、Azure、Netify、Twilio 以及 Stripe),所以能更多將開發者精力集中在界面設計上。換句話說,通過將運營移交給托管提供商,Branch 的工程部門得以專注于開發 UI 與前端界面。盡管 Branch 的例子有點極端,但軟件開發的未來確實正朝著 Emison 描述的方向發展。


          下面,咱們再來聊聊眾多開發者高度依賴抽象與托管服務之后,可能帶來的最糟糕的后果:整個行業都將面臨生存威脅。之前行業中就存在類似的刻板印象,認為這種趨勢會令前端工程師“無腦化”并最終徹底被業務不過關的初級開發者所充斥。也確實有人在認真分析這種刻板印象,認為前端主導的開發圖景意味著軟件工程將徹底消亡。沿著這樣的思路推進,前端工程師最終將趨同于純粹依賴低代碼與無代碼解決方案的非技術類開發者。如果說這波 AI 加低代碼/無代碼真能取代軟件工程師群體,那么“技術正日漸衰落”的判斷似乎也并非危言聳聽。


          但我倒不覺得前端驅動軟件開發的前景就真有這么悲觀。相反,我覺得這正是前端領域迸發出創新能量的新機會。那幫想以前端工程師“無腦化”為前提,在市場上兜售嚴重溢價的黑盒解決方案的廠商,最終都將慘遭失敗。

          前端未死,只是換了新樣貌

          這也引出了我關于前端工程師話語權的最后一點分析。與任何其他技術轉變一樣,這波以前端為重點的過渡同樣不會是均勻的。結合軟件開發的特殊背景,這必然伴隨著角色的重新分配以及傳統上涇渭分明的前端與后端、客戶端與服務器,乃至靜態與交互之間界限的逐漸模糊。其實不少資深從業者,長期以來一直在批評前端和后端這樣的表述,認為“十多年來這種硬性劃分一直脫離實際,但時至今日卻仍然存在。”Reddit 用戶 n9iels 就此做出回應:


          根據個人經驗,我發現前端領域正從純 HTML/CSS/JS 轉化為同時包含前端和后端。特別是對完全使用 React 或 Angular(SPA)構建的網站來說,前端與后端之間的界限已經越來越模糊。由于前端、后端以及全棧之類的術語無法準確反映當今的系統生命周期,所以終將被新的開發者類型所取代。雖然我估計前端這種說法還會持續一段時間,但就現實世界的實踐方式而言,這個領域必然會持續轉變。新一代工程師將取代前端開發人員,嘗試利用 API 和云服務來構建起高性能的交互式 UI。這批開發人員將跨堆棧進行運營,而不再像之前的全棧工程師那樣號稱能玩轉一切。他們只是在利用一切可以利用的工具,并著眼現實問題開展創新改進。


          總而言之,前端的江湖地位日益興盛,而作為一門學科其仍在探索途中。盡管 AI 技術繁榮與宏觀經濟萎靡帶來了種種不確定性,但廠商們必須意識到,身處堆棧頂部的開發人員的確處于更加有利的位置。行業與市場正變得愈發復雜和成熟,而前端領域的開發人員正在直面這些挑戰。在我看來,所謂技術大牛對于無數細節的沉迷并非正確的前進方向,客戶端與 UI 體驗的全面改進(包括緩存、WebAssembly、水合以及容器化微前端)才是正道。我們之所以看到許多最耀眼的人物和最具開拓性的開發者愿意投身于前端,恰恰是因為前端匯聚了他們最關注的前沿技術。

          原文鏈接:前端未死,只是換了新樣貌_工程化_kate holterhoff(RedMonk)_InfoQ精選文章


          主站蜘蛛池模板: 91精品国产一区| 精品国产一区二区三区AV性色| 麻豆一区二区99久久久久| 少妇精品久久久一区二区三区| 亚洲一区二区三区91| 一区二区三区电影网| 亚洲福利秒拍一区二区| 国产内射在线激情一区| 亚洲国产一区二区三区| 国产人妖视频一区二区破除| 国产99久久精品一区二区| 日韩精品无码中文字幕一区二区 | 国产免费伦精品一区二区三区| 亚洲精品色播一区二区| 2022年亚洲午夜一区二区福利 | 日韩精品在线一区二区| 国产一区二区三区在线影院| а天堂中文最新一区二区三区| 精品一区二区三区视频在线观看 | 久久一区不卡中文字幕| 精品国产一区二区三区久久 | 中文字幕日韩一区二区三区不卡| 亚洲熟女一区二区三区| 中文字幕日本一区| 亚洲日韩精品一区二区三区无码| 国产在线精品一区二区三区不卡| 精品人妻少妇一区二区| 色噜噜AV亚洲色一区二区| 精品国产免费一区二区三区香蕉| 亚洲一区无码中文字幕| 亚洲国产精品无码久久一区二区 | 国产成人无码一区二区三区在线 | 精品少妇人妻AV一区二区三区| 精品一区二区三区在线播放视频 | 久久国产午夜一区二区福利| 亚洲福利视频一区| 波多野结衣一区二区| 波多野结衣一区二区免费视频| 国产精品区AV一区二区| 久久久久一区二区三区| 在线欧美精品一区二区三区|