亚洲有码Av一区二区三区_国产高清啪啪免费视频_69色视频国产_国产成人人人爆出白浆_国产精品自在线拍国_一本久久伊人热热精品无码_午夜性刺激在线看免费带字幕_助力高品质欧美狂喷水_亚洲精品日韩无码_精品无码一区二区三区蜜臀_麻豆高清国产AV_熟妇人素无码中文字幕_亚洲a级片在线观看_国产欧美日韩三区_99国产成人高清在线观看

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運營的一線實戰(zhàn)洞察。

基于Vue3與Vite從零構(gòu)建前端通用工具庫

基于Vue3與Vite從零構(gòu)建前端通用工具庫 你有沒有經(jīng)歷過這種場景項目里有個 utils 文件夾里面的 isMobile 函數(shù)有三四種實現(xiàn)有的用正則有的拿 navigator.userAgent 去判斷還有的是三年前從舊項目里直接 copy 過來的。當你想抽個公共模塊統(tǒng)一一下時發(fā)現(xiàn)這些實現(xiàn)之間還有各種微妙的差異根本不敢隨便動。這種“重復(fù)造輪子”的混亂狀態(tài)我忍了很長時間最后下定決心干脆自己從零搭一套可復(fù)用的前端通用工具庫把常用的函數(shù)、組合式 API、通用組件都規(guī)范化讓以后的新項目能直接裝上用不用再到處翻歷史代碼。這篇文章我會基于 Vue3 JavaScript配合 Vite 的庫模式從 0 開始搭建這樣一個工具庫完整展示項目的目錄結(jié)構(gòu)、核心代碼實現(xiàn)、打包配置、單元測試和發(fā)布流程。全程用 JS 而不是 TypeScript主要照顧到團隊里很多工程還是純 JS 技術(shù)棧不想為了一個工具庫額外引入類型編譯成本。適合那些想把手頭零散的 utils 方法沉淀成正式 npm 包的開發(fā)者也適合想搞懂 Vite 庫模式到底怎么用的人。讀完你不僅能跑通整個流程還能避開我在實際搭建中踩過的幾個坑。1. 先想清楚通用工具庫究竟要解決誰的什么問題1.1 工具庫解決的是“重復(fù)成本”而非“炫技”很多同學(xué)一提到自建工具庫第一反應(yīng)是“我要把 lodash 重新寫一遍”其實不是這么回事。工具庫的核心價值是降低重復(fù)成本這個成本包括三部分寫代碼的時間、找代碼的時間、維護代碼的時間。我見過一個團隊內(nèi)部有三個不同的項目都寫了 formatDate 函數(shù)每個函數(shù)的輸出格式還不完全一樣有的支持傳入連字符有的只支持斜杠。后來產(chǎn)品要求統(tǒng)一日期展示格式負責的老兄花了整整一個下午去改三套實現(xiàn)改完還不敢保證邊界情況全部覆蓋。如果當初有一個統(tǒng)一維護的工具函數(shù)這個問題就是改一個文件、發(fā)一個新版、所有項目升級依賴這么簡單。但自建工具庫也不是毫無成本你需要配置構(gòu)建、測試、文檔、發(fā)布還要持續(xù)維護。所以正確的姿勢是先判斷“值不值得做”。我的判斷標準很簡單只要存在一個函數(shù)或組件連續(xù)出現(xiàn)在三個以上項目里并且它們的行為基本一致就值得沉淀進工具庫。如果只是當前項目一處用到就先忍住別抽等第二次需要時再抽也不遲。1.2 什么代碼適合放進通用工具庫適合放進通用工具庫的代碼有這幾個共同特征無業(yè)務(wù)上下文、依賴外部環(huán)境少、可以獨立測試、結(jié)果可預(yù)期。以純函數(shù)為例日期格式化、千分位轉(zhuǎn)換、URL 參數(shù)解析、uuid 生成都非常適合。組合式 API 方面useWindowSize、useLocalStorage、useEventListener 這類也是天然的工具庫素材。通用組件就更多了比如可定制的高亮文本、懶加載圖片、防重復(fù)點擊按鈕等。不適合的典型例子是封裝了特定后端接口的 request比如帶了某個接口的鑒權(quán)頭、綁定業(yè)務(wù)權(quán)限的指令、只服務(wù)于當前頁面布局的巨型組件。這些代碼一旦脫離當前業(yè)務(wù)環(huán)境就廢了硬塞進工具庫只會讓維護者為了抽象這些業(yè)務(wù)邏輯而頭疼。還有一個容易忽略的判斷維度團隊成員的使用習(xí)慣。如果你建了一個工具庫但其他項目的人根本不用那就是在自娛自樂。所以我在動手之前專門拉了一個清單把日常代碼里重復(fù)出現(xiàn)的小函數(shù)都列出來先統(tǒng)計使用頻率再決定首批放哪些工具。這一步看起來簡單實際決定了工具庫后續(xù)的活躍度。另外說一下為什么選 Vue3 JS 而不直接上 TS。我自己項目里有相當一部分是遺留的 JS 代碼如果工具庫用 TS 寫雖然能提供類型聲明但構(gòu)建鏈路會復(fù)雜一截而且會讓不愿意碰 TS 的同事產(chǎn)生距離感。Vue3 的組合式 API 本身對 JS 的友好度很高很多邏輯根本不需要類型系統(tǒng)就能表達得很清晰。當然如果你的團隊全員 TS那直接用 TS 寫會更好——工具庫的選型永遠跟著團隊現(xiàn)狀走不是跟著技術(shù)潮流走。2. 工程化骨架用 Vite 的庫模式搭出可發(fā)布的包2.1 初始化項目與基礎(chǔ)依賴新建一個工具庫項目最省事的方式是用 Vite 的腳手架保留 Vue3 模板。我用的命令是這樣的npm create vitelatest my-utils -- --template vue模板帶上的 React 之類的東西都可以刪掉我們只需要一個干凈的 Vite Vue3 環(huán)境。因為這個工具庫不是業(yè)務(wù)應(yīng)用所以入口不再是 index.html而是一個倉庫入口文件這點后面會重點說。依賴安裝上除了 vue 和 vite我還會加這幾個運行時無關(guān)的工具npm install -D vitest vue/test-utils eslint prettier husky lint-staged這里稍微解釋一下為什么需要這些。vitest 用來跑單元測試因為它是 Vite 生態(tài)的測試框架可以復(fù)用同一個 vite.config不用單獨配一套vue/test-utils 是 Vue 組件測試的官方工具庫測組件必用eslint 和 prettier 統(tǒng)一代碼風(fēng)格husky 和 lint-staged 負責在提交前攔截不規(guī)范代碼。對一個公共工具庫來說質(zhì)量門禁是必須的因為代碼一旦發(fā)布出去被多個項目依賴任何低級錯誤都會被無限放大。2.2 Vite 的 lib 模式配置解析Vite 默認構(gòu)建的是應(yīng)用會從 index.html 出發(fā)生成一堆靜態(tài)資源。工具庫要的是“庫模式”——從一個 JS 入口開始把內(nèi)容編譯成可被其他代碼 import 的包。配置核心就落在build.lib上。我最終的 vite.config.js 是這樣寫的import { defineConfig } from vite import vue from vitejs/plugin-vue export default defineConfig({ plugins: [vue()], build: { lib: { entry: src/index.js, name: MyUtils, formats: [es, cjs, umd], fileName: (format) format es ? my-utils.esm.js : my-utils.${format}.js }, rollupOptions: { external: [vue], output: { globals: { vue: Vue } } } }, test: { environment: jsdom } })這里面的關(guān)鍵點值得好好說說。entry指向的是包入口工具庫所有對外暴露的能力都從這個文件導(dǎo)出。formats我選了 es、cjs、umd 三種ESM 適合現(xiàn)代打包器可以觸發(fā) tree-shakingCJS 是為了兼容舊版 Node 環(huán)境和老式構(gòu)建器UMD 則是給那些直接在 script 標簽里引用的人用的雖然現(xiàn)在已經(jīng)很少見但加上總沒壞處。rollupOptions.external: [vue]是一個特別重要的配置。它告訴 Vite“vue 這個依賴不要打包進我的產(chǎn)物里?!币驗楣ぞ邘炖锏慕M件、組合式 API 都依賴 Vue但 Vue 應(yīng)該由使用方項目提供而不是工具庫重復(fù)打包一份。如果這里不排除發(fā)布出去的包體積會大很多而且可能導(dǎo)致使用方項目里同時存在兩份 Vue 實例觸發(fā)各種奇奇怪怪的問題。這點我在后面第 6 部分還會專門強調(diào)。2.3 目錄結(jié)構(gòu)設(shè)計JS 工具、組合式函數(shù)、組件分開維護工具庫不是把所有代碼堆在一個文件里就完事目錄結(jié)構(gòu)直接決定了后續(xù)的可維護性。我采用的是一套簡單清晰的分層模式my-utils/ ├── src/ │ ├── index.js # 入口統(tǒng)一導(dǎo)出 │ ├── funcs/ # 純函數(shù)工具 │ │ ├── formatDate.js │ │ ├── debounce.js │ │ └── ... │ ├── composables/ # 組合式 API │ │ ├── useWindowSize.js │ │ ├── useLocalStorage.js │ │ └── ... │ └── components/ # 通用 Vue 組件 │ ├── HighlightText/ │ │ ├── index.js │ │ └── HighlightText.vue │ └── ... ├── test/ # Vitest 測試用例 ├── dist/ # 構(gòu)建產(chǎn)物gitignore ├── package.json ├── vite.config.js └── ...為什么把純函數(shù)、組合式 API、組件分成三個目錄因為它們的用法和構(gòu)建路徑完全不同。純函數(shù)是普通 JS 模塊可以直接被任何環(huán)境加載組合式 API 依賴 Vue 的運行時但不需要渲染組件則必須有 Vue 的渲染器配合。分開后后續(xù)做按需引入時非常方便使用者可以精確地只加載一個模塊。入口文件src/index.js的作用是把所有能力匯總到一處方便全量引用。同時我也在 package.json 里配好了子路徑導(dǎo)出讓使用者既能import { debounce } from my-utils全量引入也能import debounce from my-utils/funcs/debounce精準引入這其實就是按需加載的另一種手段后面詳細講。這樣一個骨架搭完你就有了一個干凈的起點。接下來最核心的事情就是往里面填充真正有用的代碼。3. 通用函數(shù)、組合式 API、組件三類能力的實現(xiàn)與設(shè)計思路3.1 純函數(shù)以 formatDate 和 debounce 為例純函數(shù)是工具庫的基本盤。寫這些函數(shù)的核心原則是輸入可預(yù)期、輸出穩(wěn)定、不做意外的事。我拿兩個最常見的例子展開。第一個是formatDate。很多項目都用 date-fns 或 dayjs但為了一個兩個格式化的需求去引整個庫其實有點重。自己寫一個針對常用格式的輕量函數(shù)就夠了// src/funcs/formatDate.js export function formatDate(date, fmt YYYY-MM-DD HH:mm:ss) { const d date instanceof Date ? date : new Date(date) if (Number.isNaN(d.getTime())) { throw new TypeError(formatDate received an invalid date) } const pad (n) String(n).padStart(2, 0) const map { YYYY: d.getFullYear(), MM: pad(d.getMonth() 1), DD: pad(d.getDate()), HH: pad(d.getHours()), mm: pad(d.getMinutes()), ss: pad(d.getSeconds()) } return fmt.replace(/YYYY|MM|DD|HH|mm|ss/g, (match) String(map[match])) }我特意沒有做很復(fù)雜的令牌解析只覆蓋了最常見的年月日時分秒為什么這么克制因為工具庫的代碼要盡可能容易被后續(xù)的人讀懂功能越多、邊界情況越多潛在的風(fēng)險就越大。當實際需求超出這個范圍時直接按 dayjs 或者 date-fns 更合理不要試圖自己架一個完整的日期引擎。一個容易被忽略的細節(jié)入?yún)⒍x成date instanceof Date ? date : new Date(date)。這樣字符串日期、時間戳都能兼容并且當傳入非法值時會顯式拋錯而不是返回一個又難看又難排查的NaN/NaN/NaN。顯式拋錯是工具代碼里值得推崇的做法——寧可讓調(diào)用方在開發(fā)階段就發(fā)現(xiàn)錯誤也不要把錯誤吞掉。第二個例子是debounce這個函數(shù)幾乎每個項目都自己寫過一版但很多版本在“取消”和“立即執(zhí)行”這兩個能力上是缺失的。工具庫里的 debounce 應(yīng)該更完整// src/funcs/debounce.js export function debounce(fn, wait 300, immediate false) { if (typeof fn ! function) { throw new TypeError(expected a function as first argument) } let timer null let result null const debounced function (...args) { return new Promise((resolve) { const later () { timer null if (!immediate) { result fn.apply(this, args) resolve(result) } } const callNow immediate !timer clearTimeout(timer) timer setTimeout(later, wait) if (callNow) { result fn.apply(this, args) resolve(result) } }) } debounced.cancel () { clearTimeout(timer) timer null } return debounced }這里有兩個設(shè)計點是我從實際項目里總結(jié)出來的。第一用 Promise 包一層讓調(diào)用方可以用await debounced()拿到函數(shù)返回結(jié)果這對手寫版 debounce 來說是不常見的但實際在某些需要等待結(jié)果入庫的場景特別好用。第二保留.cancel方法這樣在組件卸載時能優(yōu)雅地清理掉還未觸發(fā)的任務(wù)避免在異步回調(diào)里觸發(fā)對已卸載組件的操作。3.2 組合式 API封裝一個 useWindowSizeVue3 的組合式 API 非常適合做工具庫因為它能把響應(yīng)式狀態(tài)、副作用生命周期都管理起來。我用useWindowSize來示范一個標準寫法// src/composables/useWindowSize.js import { ref, onMounted, onUnmounted } from vue export function useWindowSize() { const width ref(window.innerWidth) const height ref(window.innerHeight) const update () { width.value window.innerWidth height.value window.innerHeight } onMounted(() { window.addEventListener(resize, update) }) onUnmounted(() { window.removeEventListener(resize, update) }) return { width, height } }為什么用ref而不是reactive因為返回的是一個雙成員對象用 ref 包裹后使用方可以優(yōu)雅地解構(gòu)const { width, height } useWindowSize()同時這兩個值在模板里可以直接渲染不會丟失響應(yīng)性。而如果用 reactive 包裝解構(gòu)后響應(yīng)性就斷了。監(jiān)聽事件一定要放在onMounted里嗎不一定如果你的工具庫只會在組件實例中調(diào)用那么 onMounted 是安全的。但如果你希望這個函數(shù)也能在普通 JS 環(huán)境沒有組件上下文下使用那就需要做一些兼容處理比如直接用const update () {...}然后立即初始化再返回一個手動銷毀的方法。我這里的寫法是為絕大多數(shù) Vue 單文件組件場景設(shè)計的簡單可靠。需要額外說明的是組件的onUnmounted保證了 resize 監(jiān)聽器在組件銷毀時被移除這能避免大多數(shù)內(nèi)存泄漏問題。再多說一點工具型的 composable 最重要的是“副作用可控”。類似useWindowSize這種監(jiān)聽一個全局事件就必須在合適時機解綁絕不能讓使用方背著內(nèi)存泄漏的債。3.3 通用組件從最簡單的高亮文本組件開始通用組件是工具庫里比較容易“膨脹”的部分因為 UI 設(shè)計千差萬別強行做成通用往往兩頭不討好。我建議從沒有視覺綁定的功能型組件開始比如高亮文本。它負責接收關(guān)鍵詞把匹配到的片段用mark或其他標簽包起來至于樣式直接由使用方的項目控制。用 Vue3 的 SFC 和 JS 實現(xiàn)如下!-- src/components/HighlightText/HighlightText.vue -- template span classmy-utils-highlight-text template v-for(part, index) in parts :keyindex {{ part.text }}slot v-ifpart.match namehighlight :partpart{{ part.text }}/slot /template /span /template script setup import { computed } from vue const props defineProps({ text: { type: String, required: true }, keyword: { type: String, default: }, caseSensitive: { type: Boolean, default: false } }) const parts computed(() { if (!props.keyword || !props.text) { return [{ text: props.text || , match: false }] } const flags props.caseSensitive ? g : gi const regex new RegExp((${escapeRegExp(props.keyword)}), flags) return props.text .split(regex) .filter((segment) segment ! undefined) .map((segment, index) ({ text: segment, match: regex.test(segment), index })) }) function escapeRegExp(str) { return str.replace(/[.*?^${}()|[\]\\]/g, \\$) } /script組件可以配合插件式注冊實現(xiàn)全量引入// src/components/HighlightText/index.js import HighlightText from ./HighlightText.vue export default HighlightText然后在主入口里注冊// src/index.js export { default as HighlightText } from ./components/HighlightText/index.js組件本身不綁定任何樣式由使用方項目用樣式覆蓋這是保持通用性的關(guān)鍵。如果你在組件里寫死了背景色和字體到每個項目里都會有人抱怨“顏色對不上”。這里的關(guān)鍵詞匹配我特意用正則做了轉(zhuǎn)義避免用戶輸入*或.等正則特殊字符導(dǎo)致匹配行為異常。高亮文本組件規(guī)模不大但它演示了工具組件最基本的設(shè)計思路props 傳入數(shù)據(jù)、不依賴業(yè)務(wù)狀態(tài)、支持插槽做擴展、無內(nèi)置樣式。后續(xù)要擴展其他組件時都可以參考這個模式。4. 質(zhì)量保障ESLint Prettier Vitest 讓工具庫少踩坑4.1 ESLint 與 Prettier 配置要點工具庫代碼會被很多人依賴代碼風(fēng)格不統(tǒng)一會直接導(dǎo)致合并沖突和 review 效率低下。我在項目里集成了 ESLint 和 Prettier配置比較簡單但夠用。// .eslintrc.cjs module.exports { root: true, env: { browser: true, node: true, es2022: true }, extends: [ eslint:recommended, plugin:vue/vue3-essential, prettier ], parserOptions: { ecmaVersion: 2022, sourceType: module }, rules: { vue/multi-word-component-names: off } }vue/multi-word-component-names這個規(guī)則默認要求組件名必須是多個單詞但對于工具庫來說很多通用組件就是HighlightText、DebounceButton這種兩詞名字也有個別像Button這種基礎(chǔ)組件所以關(guān)掉比較省心。Prettier 簡單配置一個.prettierrc{ semi: false, singleQuote: true, trailingComma: none, printWidth: 100 }因為主要是 JS 文件行寬設(shè) 100 足夠。把 ESLint、Prettier、Vite 同時跑通的好處是代碼風(fēng)格不再需要人工 review機器幫你兜底。4.2 給工具庫補上單元測試Vitest工具庫是純邏輯居多不測一下說不過去。Vitest 和 Vite 深度集成跑測試直接用vitest命令就行。我寫幾個典型測試// test/formatDate.test.js import { describe, it, expect } from vitest import { formatDate } from ../src/funcs/formatDate describe(formatDate, () { it(formats date correctly, () { const date new Date(2024, 0, 15, 9, 30, 45) expect(formatDate(date)).toBe(2024-01-15 09:30:45) }) it(throws on invalid date, () { expect(() formatDate(not-a-date)).toThrow(TypeError) }) })debounce 的測試需要依賴 fake timersVitest 同樣支持// test/debounce.test.js import { describe, it, expect, vi } from vitest import { debounce } from ../src/funcs/debounce describe(debounce, () { it(waits until wait time passes before invoking, () { vi.useFakeTimers() const fn vi.fn() const debounced debounce(fn, 200) debounced() vi.advanceTimersByTime(100) expect(fn).not.toHaveBeenCalled() vi.advanceTimersByTime(100) expect(fn).toHaveBeenCalledTimes(1) vi.useRealTimers() }) })組合式 API 的測試稍微復(fù)雜一點需要提供一個宿主環(huán)境。Vitest 開了environment: jsdom后我們可以用vue/test-utils掛載一個小組件來驗證// test/useWindowSize.test.js import { describe, it, expect, vi } from vitest import { mount } from vue/test-utils import { defineComponent, h } from vue import { useWindowSize } from ../src/composables/useWindowSize describe(useWindowSize, () { it(returns window dimensions, async () { const Comp defineComponent({ setup() { const size useWindowSize() return () h(div, ${size.width.value}x${size.height.value}) } }) window.innerWidth 1024 window.innerHeight 768 const wrapper mount(Comp) expect(wrapper.text()).toBe(1024x768) window.innerWidth 1280 window.dispatchEvent(new Event(resize)) await wrapper.vm.$nextTick() expect(wrapper.text()).toBe(1280x768) wrapper.unmount() }) })這種測試的意義是保證核心函數(shù)的行為回歸可控。工具庫一旦發(fā)布任何一次升級都可能影響很多項目沒有測試誰敢隨便升版本所以我個人的建議是工具庫里的每個函數(shù)至少一個主流程測試加一個邊界測試每個 composable 至少測掛載和銷毀組件至少測 props 渲染。4.3 lint-staged husky 攔截不規(guī)范的提交有了 ESLint 和測試還需要把它們卡在提交前否則總有人跳過檢查。簡單搭一個 husky 鉤子npx husky init然后配置lint-staged在 package.json 里{ lint-staged: { *.{js,vue}: [eslint --fix, prettier --write] } }同時.husky/pre-commit里寫npx lint-staged這樣每次提交只會檢查暫存區(qū)里的文件速度很快也不會逼著大家把所有測試跑一遍。更嚴謹點的團隊可以在 pre-push 階段跑全量測試但工具庫代碼量不大所以我在 commit 前直接跑了npm test npm run lint也行。質(zhì)量門禁的意義不在于設(shè)置多少關(guān)卡而在于讓團隊所有人都保持一致的習(xí)慣。5. 打包與發(fā)布從本地工具庫到 npm 公共包5.1 多格式產(chǎn)物與 Tree ShakingVite 庫模式在build后會在 dist 目錄下生成三個文件my-utils.esm.js、my-utils.cjs.js、my-utils.umd.js。ESM 文件內(nèi)部使用 ES Module 語法現(xiàn)代打包器Vite、webpack 5、Rollup在解析 import 時可以靜態(tài)分析導(dǎo)出成員從而剔除未使用的代碼這就是 tree-shaking 的基礎(chǔ)。要讓 tree-shaking 真正生效package.json 里必須明確sideEffects: false意思是這個包里的模塊都沒有副作用。但組件文件可能包含樣式副作用所以如果你有 CSS需要單獨處理。我的做法是把組件樣式內(nèi)聯(lián)到組件里用style scoped這樣 Vite 在編譯后會把 CSS 抽離成單獨的 CSS 文件在 package.json 里通過sideEffects指定 CSS 文件有副作用其他模塊沒有。目前我們先不引入 CSS保持sideEffects: false是最省心的。5.2 package.json 的關(guān)鍵字段構(gòu)建產(chǎn)物出來后發(fā)布配置是重中之重。我最終的 package.json 關(guān)鍵字段長這樣{ name: my-utils, version: 0.1.0, description: A collection of Vue3 JS utilities, composables and components, type: module, main: ./dist/my-utils.cjs.js, module: ./dist/my-utils.esm.js, unpkg: ./dist/my-utils.umd.js, exports: { .: { import: ./dist/my-utils.esm.js, require: ./dist/my-utils.cjs.js }, ./funcs/*: ./dist/funcs/*.js, ./composables/*: ./dist/composables/*.js, ./components/*: ./dist/components/*.js }, files: [dist, README.md], peerDependencies: { vue: 3.2.0 }, sideEffects: false, scripts: { build: vite build, test: vitest run, lint: eslint src test --fix } }幾個字段解釋一下。main指向 CJS 產(chǎn)物是為了兼容還沒有切換到 ESM 的舊 Node 環(huán)境。module指向 ESM 產(chǎn)物現(xiàn)代打包器會優(yōu)先讀取。exports字段是 Node.js 12 和現(xiàn)代打包器的新標準它比 main/module 更精細能限制外部訪問包內(nèi)未聲明的路徑防止別人import my-utils/src/xxx這種奇怪的引用方式。files決定發(fā)布時哪些文件會被打進 npm 包這里只包含 dist 和 README能有效避免把源碼、測試文件全部發(fā)布出去既縮小包體積也避免暴露未編譯的內(nèi)部細節(jié)。peerDependencies用來聲明這個包依賴的宿主版本——Vue 3.2 及以上但不會把 Vue 安裝進來。在發(fā)布前建議先本地驗證一下npm pack這會生成my-utils-0.1.0.tgz你可以解開看看里面有什么再或者用一個臨時項目npm install /path/to/my-utils-0.1.0.tgz實際引用一下確保發(fā)布到 npm 后不會出現(xiàn)“裝回來發(fā)現(xiàn)缺文件”的尷尬。5.3 版本號與更新日志別讓發(fā)布變成災(zāi)難工具庫的版本管理我強烈建議走語義化版本SemVer也就是MAJOR.MINOR.PATCH。新增一個向后兼容的函數(shù)升 MINOR修復(fù)原有函數(shù)的 bug升 PATCH如果你改了函數(shù)入?yún)?、調(diào)整了組件 props 的必填項這類破壞性變化一定要升 MAJOR。配合 conventional commits可以在每次提交時自動生成 CHANGELOG。比如feat: add useLocalStorage會被識別為 feature 更新fix: correct formatDate timezone offset會被識別為 bug 修復(fù)。我在項目里用了standard-version這個工具來根據(jù)提交記錄自動生成版本號和 changelog執(zhí)行npx standard-version就會自動修改 version、生成 CHANGELOG.md、打上 git tag非常省事。不過版本生成的粒度還是要自己控制。工具庫的發(fā)布頻率不宜太高我一般會在一次功能迭代完成后集中發(fā)布一版而不是每次 commit 都發(fā)。多個項目共用一個工具庫的好處也體現(xiàn)在這里——只有你的版本規(guī)劃做得足夠清晰下游項目才能放心地跟進升級。6. 實戰(zhàn)中繞不開的坑記住了能省下半天時間6.1 Vue 外部化后別忘了開發(fā)依賴里的 vue前面說了打包時要把 Vue 設(shè)為 external但很多新手會掉進另一個坑既然 vue 是 peerDependencies是不是項目里就不用裝 vue 了不是的。你本地開發(fā)工具庫時仍然需要 vue 作為 devDependency因為組件和測試都要實際運行。peerDependencies 解決的是“使用方要自己裝 vue”而 devDependencies 解決的是“你在開發(fā)這個庫時需要 vue 可用”。我見過一個例子某位同事把 vue 從 devDependencies 里刪掉認為發(fā)布時會自動帶上結(jié)果本地跑測試直接報“Cannot find module ‘vue’”。正確的習(xí)慣是vue 同時出現(xiàn)在 peerDependencies 和 devDependencies 里peer 里寫寬松范圍如3.2.0dev 里寫一個明確的版本保證本地開發(fā)環(huán)境可控。6.2 Tree Shaking 對組件并沒有想象中那么靈組件跟純函數(shù)不一樣。如果你在主入口 index.js 里一次性導(dǎo)出了 10 個組件然后使用方通過import { Button } from my-utils這樣的方式按需引用現(xiàn)代打包器確實可以通過 tree-shaking 把沒用到的組件代碼丟掉。但這里有個前提組件內(nèi)部不能被任何模塊級副作用觸發(fā)比如組件文件頂部直接插入全局 CSS 或執(zhí)行console.log。更讓人頭疼的是如果使用方項目用 webpack 4 這類對 tree-shaking 支持不完善的老構(gòu)建器一個入口導(dǎo)出很多組件反而可能導(dǎo)致全部被打進 bundle 里。這時候你就需要子路徑導(dǎo)出讓使用方可以import Button from my-utils/components/Button這樣的精確引用繞開 tree-shaking 的機制限制。這也是我在 package.json 里配置 exports 子路徑的初衷——為老舊項目留一條后路。6.3 發(fā)布前務(wù)必先本地聯(lián)調(diào)最好用 npm link 或 yalc我最后一次發(fā)布的教訓(xùn)是“發(fā)布一時爽打完臉就腫”。那次我更新了一個組件里的 prop 默認值本地構(gòu)建和測試都通過了直接npm publish結(jié)果有個項目升級后組件的樣式全亂了。原因是我漏改了另一處相關(guān)代碼但本地沒有實際業(yè)務(wù)場景測試也沒有覆蓋到所有 CSS 組合。從那以后我養(yǎng)成了發(fā)布前先用npm link或者yalc把包鏈接到實際項目里做冒煙驗證的習(xí)慣。npm link的用法很簡單在工具庫目錄里執(zhí)行npm link再在目標項目里執(zhí)行npm link my-utils這樣目標項目引用的就是本地源碼產(chǎn)物改動后的效果能立即看到。但 npm link 會改變 node_modules 的符號鏈接結(jié)構(gòu)偶爾會觸發(fā) vite 緩存問題所以我個人更喜歡 yalc——它會把本地發(fā)布文件“推”到目標項目的 node_modules 里更接近真實依賴情況也不會因為符號鏈接導(dǎo)致某些工具無法解析。說到底工具庫開發(fā)的完整閉環(huán)是“編碼 - 測試 - 構(gòu)建 - 本地聯(lián)調(diào) - 發(fā)布”。前四步走得越扎實最后一步就越穩(wěn)。每當我偷懶跳過本地聯(lián)調(diào)時幾乎都會在下一次發(fā)布后收到一個“有問題”的反饋。所以現(xiàn)在我的出包流程里npm pack和本地冒煙這步已經(jīng)成了肌肉記憶。從我這次搭建工具庫的經(jīng)歷來看最耗時間的不是寫那幾十個函數(shù)而是讓整個項目變得干凈、可信、可維護的過程。工具庫的本質(zhì)是給未來的自己和其他項目“預(yù)寫”代碼如果你的包發(fā)布一次就要讓下游項目改一次配置那這個工具庫就失去了意義。如果你也打算動手我的建議是從一個最小的函數(shù)庫開始先跑通打包發(fā)布流程再逐步加入組合式 API 和組件別一開始就想面面俱到。最后再分享一個小技巧每次構(gòu)建之后進 dist 目錄隨便打開一個產(chǎn)物文件看看里面有沒有意外的殘留代碼比如過期的注釋、調(diào)試用的 console 語句——有一次我就在產(chǎn)物里發(fā)現(xiàn)了一段被誤加到純函數(shù)里的 console.warn還好發(fā)的是預(yù)發(fā)布版本沒有影響線上項目。這種細節(jié)點滴積累起來就是工具庫和其他人的隨手分享之間最大的區(qū)別。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
性欧美精| 亚洲男人天堂网久久| www. 男人天堂成人在线| 日韩无码专区| 人人摸人人叼| 手机在线视频国内精品| 自拍偷拍 日韩欧美| 大香交| 色五月69夫妻| 噜噜噜狠狠色综合| 国产精品极品美女视频| 日韩欧美福利视频看看| 俞拍久久国应视频| 超碰欧美97资源| 蜜臀99久久精品久久久懂爱| 97欧美日韩| 天美传媒一二三区永久网站| 亚洲一区中文字幕一区| 亚洲国产一级黄色视频| 国产精品不卡av免费在线观看| 色偷偷超碰亚洲| 欧亚第一综合网| 丁香五月久久| 亚洲成av人片色午夜乱码| 中国人高清www色视频免费| 插插综合网天天影视网| 亚洲欧美清纯| 91日韩网站| 大香蕉92| 欧美,亚洲,日韩,v,天堂,手机在线观看| 久久欧洲| 九一性生活免费视频| 国产传媒1234区| 色性荡荡荡荡视频| 蜜桃在线观看一区二区三区| 国产污视频麻豆传媒一区二区| 国产11页| 夜夜嗨AV蜜臀av| 国产精品女同| 国产精品网站免费| 精久久久| 97综合激情| 超碰色大香蕉| 中文字幕久久婷婷丁香五月天| 亚洲无线观看久久| 亚洲日韩视频二区| 乱伦AVxx| 亚洲,欧美,春色,另类| 精品久久久久久亚洲| 亚洲一区二区三区久久 亚洲一区二区| 亚欧高清v| www.色婷婷.com| 日韩成人网址| 欧美色66| av橘色网站| 亚洲高清欧美总合| 中文字幕一区二区韩| 国产高清无码一区三区二区| 婷婷丁香五月天综合东京热| 熟女啪啪视频| 亚洲中字慕不卡| 99少妇| 久久这里只精品| 欧美亚洲手机在线| 亚洲无码太久| 亚洲激情四射| 色眯眯av| 老妇女91| 日本污ww视频网站| 91精品又粗又猛又爽| 超碰九九| 中文字幕一区二区三区高清| 麻豆国产原创AV色哟哟| 国产AV人人夜夜澡人人爽麻豆| 91欧美巨乳| 97色碰| 91精品女厕偷拍视频| 国产亚州高清国产拍精| 中文字幕文字幕无码一区二区三区电影99| 蜜臀久久99精品久久久久久酒店| gogogo免费高清看中国国语| 深爱激情五月天| 少妇一区二区三区在线观看| 日韩九九九| 日本一区二区三区免费观看| 嗯啊不要啊在线 | 变态综合色| 人人干黄色| 99热色精品| 日韩欧美中文字| 91制服丝袜| 欧美成人四级在线播放| 91 丝袜在线| 国产强奸乱伦第1页| 亚洲最大网站av| 91人妻视频在线| 丝袜美腿91| 国产精品毛片?v一区二区三区 | 91色情黑丝搞鸡在线观看一区二区三区三州 | 920日本午夜免费| 91 综合 色| 黄片免费日韩| 天天综合日韩网| 吖在线不卡一区二区国产剧情 | 国产精品午夜福利视频| 日韩AV一起草| 日韩av情韩国爱禁区av一区二区| 亚洲一区二区三区不卡国产欧美| 一区二区三区日韩欧美| 国产精品高潮久久久无码| 再深点灬舒服灬太大了好硬好爽| 亚洲精品黑丝| 亚洲天堂7777| 久久华人网| 日本操逼视频导航| 色制服丝袜夫妻av一区| 免费看国产曰批40分钟怎么下载| 亚洲性感丝袜诱惑在线观看| 亚洲图片欧美在线视频| 99少妇| 国产无码一二三区| 91综合色噜噜| 99综合自拍| 色欲久久久久综合网| 男人亚洲91首页在线| 夜夜黄| 久操热| 久久风骚城市人| 无套内射性感少妇视频| 日本加勒比无码专区| 精品国产网站| 成人 日本A片无码8888| 亚州大图综合色图| 欧美啪啪女女| 欧美大片91| www.97在线| 在线免费观看高清无码视频| 欧美日韩淫加| 岛国黄| 国产免费一区| 九九九九九九亚洲| 亚洲无码一二三区| 欧美九九九| 按摩中文字幕| 三级特黄60分钟播放| 青草影院内射高潮| 国内精品不卡无毒99999| 欧美日韩黄片精品在线| 国产精品97超碰| 婷婷五月av| 亚洲精品久久久久毛片A片拉屎| 欧中日成人免费影视| 18禁中文字幕| 男人的天堂99| 久男人久久| 丁香激情网| 亚洲欧洲日本精品中文a∨| 久久伊人青青草| 成人免费不卡在线视频| 无码人妻精品酒店| www.成人无码| 天海翼久久| 天天综合网国产| blacked精品一区国产| 青青草原伊人网| 男女91| 久久神马影院| 色五月网址| 麻豆国产97在线| 精品九九九九九九九九九| 综合久| 狠狠色伊人亚洲综合网站色| 97超碰国产亚洲精品| 国产精品一区二区三区在线密挑| 2021久久国产综合精品青草 | 色五月综合网| 狠狠中文字幕| 男女做爰猛烈动高潮A片免费应用 少妇厨房愉情理伦片bd在线观看 不卡中文字幕aⅴ在线 | 在线观看A啊啊啊| 色五月综合网| 国产精品久久久久久久久AV大片 | AV老汉| 色婷婷久久| 91丨豆花丨熟女| 欧美中文综合| 欧美 色 亚洲| 成人开心网在线视频| 日本啊啊啊啊啊视频| 亚洲熟妇极品| 欧洲色| 免費黃色視頻觀看一| 国产精品一区午夜福利| 国产狂喷潮在线精品| 快播久久人人aV| 欧美一二级| 久久超碰免费的| 中文字暮97| 大香蕉亚洲中文| 日本黄 R色 成 人网站| 婷婷五月天基地| 日韩精品黄片免费观看| 久久91视频| 性饥渴少妇av无码毛片| 八戒午夜福利理论片| 无码人妻一区二区三区免费九色| 精品一区二区三区蜜桃| 色综九九九一区| 97超碰色中文字幕| 激情文学亚洲| 青青草原成人| 丝袜美腿丝袜| 久操免费在线| 超碰精品日韩欧美国产| 精品国产一区二区三区香蕉欧美 | 亚洲国产精品久久久男人的天堂| 美女淫穴| 九一性生活免费视频| 亚洲青青草| 51一区二区三区| 中文字幕av一区二区三区人妻少妇| 天堂亚洲精品久久老牛| 欧美一区二区三区成人性生活| 超碰综合色| 欧美黑人极品高潮喷吹熟女黑人性暴力日韩在线欧美极品一区二区老师 | 99色在线| 少妇同性| 一级AAA片一区二区三区| 精品对白久久不卡| 亚洲国产精品V?在线播放| 激情 欧美 亚洲 小说| 色就色综合| 國產尤物AV尤物在線觀看| 国产偷拍自拍在线视频| AV九九| 久久色激情一区二区三区| 精品视频97| 1.igao73.com 加入收藏 免费专区 国产精品 中文字幕 日韩精品 欧美精品 精彩 | 伊人久久大香大香线蕉中文| 97色碰| 天天添天天干电影| 嗯嗯嗯啊啊啊干死我吧| 青青在线视频免费| 亚洲国产一区二区日韩专区| 日本午夜久久电影| 北京美女一区二区| 激情综合网亚洲| 在线岛国新天堂8| 亚洲美女自拍偷拍视频| www.久久| 欧美 熟女 日韩| 啊啊啊慢点| 丁香九月 婷婷| 大香蕉丝袜一级片| 啊啊啊97视频| 精品国产乱码久久久久久网站入口| 极品销魂美女一区二区| 日韩999| 婷婷精品国产一区二区三区日韩| 肥佬影院91| 日本操逼视频不卡直接放| 在线看免费无码AV天堂的| 蜜臀久久99精品久久久久久久久| 久久综合av| 欧美中文字幕精品人妻| 美女国产一区二区久久| 亚洲AV无码久久精品蜜桃小说| 国产AV天美传媒一区二区三区 | 啊啊啊在线观看| 操逼片中文| 青青草啪啪网| 秋霞成人一级在线观看| 免费看毛片操穴| 蜜臀th| 韩国一级做a久久久久| 爱媛媛久久国产福利| 狠狠搞 亚洲91| 清纯唯美第一页| 黄色高清无码无码破解免费暗网| 中文字幕十五区| 97超碰香蕉| 六月丁香啪啪| 欧洲站一级二级三级h| 草莓精品视频在线免费观看| 男人天堂久久日韩| 91一区二区三区蜜桃| 婷婷五月天小说| 97国产精品在线观看| 亚洲最新av无码成人精品区| 久久久久久久久久久999| 久操精品| 久久久久久久一级黄色打同平台| 九九九九AV| 天天射影院| 欧美一级久久久丰满| 小少妇| 男人综合网| 亚洲夜夜欢无码一区二区| 蜜臀无码一区二区| 欧美日韩中文亚洲v在线综合| 香蕉久久精品| 亚洲无吗在线视频| 色婷婷A V一二三四区麻豆综合| 91人妻做a观看视频| 99热在线不卡| 精品视频免费在线一区| 美女网站黄页| 开心五月天激情网| 欧美裸体美女日麻屄| 久久9 9 9精品| 久久日韩精品一区二区| 精品综合久久久久久97| 超碰成人国产| 男人的天堂 在线一区| 亚洲欧洲美腿丝袜| 欧美五十路熟| 久久精品国产97欧美精品亚洲| 欧美一级黄片免费播放| 日日超碰亚洲| 超碰免费欧美7| 女同性恋久久| 成人性爱免费播放| 日韩综合色网| 亚洲精品 大香蕉| 国产精品 视频| 亚洲淫乱骚妇AV| 丝袜熟女一区二区三区| 青青青青青手机视频| 日韩97超碰中文字幕| 久久中文字幕不卡人妻| 插B在线观看| 欧美色三级片91| 91精品亚洲内射孕妇| 精人妻无码一区二区三区伊人直播 | 五月丁香综合激情| 亚洲av噜噜噜噜噜噜| 天天操人人操骚逼网站| 日韩精品 资源| 一级婬片120分钟试看| 丰满丝袜少妇AV| 国产欧美美女免费观看视频| 久久国内| 上海一级黄片| 2021国产成人精品久久| 97 国产精品| 久久久久久性爱视频| 国精精品无码一二三区水多多| 亚州欧美在线| 是还免费视频1727我| 超碰99在线| 999精品国产高清一区二区| 国产精品另类| 亚洲爱爱视频一区二区| 日韩紧密久久| 91丨九色丨熟女高潮| 国产无码精品高清| 亚洲毛片基地专区| 亚洲色图 欧美| 亚洲啪啪啪啪视香蕉| 色狠狠综合噜一二三区| 日日日日日| 爱媛媛久久国产福利| 翔田千里AⅤHD无码| 最新中文字幕精品在线| 最新无码国产| 天美精品原创av片国产| 美欧色综合| AV天黑人| 色色九区| 啊啊啊水好多| 夜夜无码| 极品出轨视频网站| 校园春色美腿丝袜 | 丁香六月婷婷| 久久九操在线观看| 日本123区操B视频| 2020中文字幕在线观看| 夜夜嗨一区| 久久久久久久性爱| 超碰97国产欧美| 后入福利| 我爱操| 中日韩熟女| 日韩精品-原创伙伴| 啊嗯嗯啊好大好爽| 蜜桃午夜视频一区二区| 骚熟女AV网| 国产熟码AV| 人人九九精| 欧美第二页午夜| 91综合国产精品| 91激情网| 亚洲做性| 超碰2017| 一个色导综合| 岛国黄| 色久桃花影院在线观看| 无码逼| 粉嫩绯色AV一区二区在线| 欧日a| 日韩午夜啪啪视频| 麻豆60秒| 亚洲熟女乱熟乱熟妇综合网二区| 久久超碰av在线| 超碰9 7女人| 久久精品国产97欧美精品亚洲| 尤物AV免费网站| 欧美综合第一页| 国产操逼网站亚洲一级黄色| 8x福利精品第一福利视频导航 | 国产白领连续中出在线观看| 91爰爱欧美| 中文字幕二区| 精品无吗m| 永久免费av无码网站国产app| 中文字幕人成乱码熟女香港| 色官网在线| 精品国产乱码久久久久久影片| 久久久久久久九九九九九九| 欧美日韩国产人人| 97碰碰色| 国产探花精品在线| 9久综合网| 丝袜视频一区二区在线播放国产中文| 5252色欧美在线男人的天堂| 精品亚洲| 亚洲AV无码乱码在线观看性色| 欧美嫩性色| #NAME?| 午夜经典| 日本狂喷奶水在线播放212| 精品国产一级久久| 亚洲免费97免费| 国产伊人精品在线| 天天干天天燥| 日本一区二区三区欧美日韩中文字幕| 黄色十八禁| 在线视频97| 精品人妻美妇91job| 在线天堂999| 97超碰人人模人人拍人人| 欧美黄色大片在线观看| 五月天黄色av| 麻豆精品.欧美精品.日韩精品.| 精品人妻中文字幕4399| 99.色网| 欧美亚洲丝袜人妻制服中文99| 久久首页| 91殴美大片| 91欧美经典| 婷婷视频在线免费观看| 96AV久久久| 91性感在线| 91精品无码人妻系列| 欧美色图亚洲色图成人在在线| 久久久免费视频18| 国产精品久久久久久久黄无码| 色性荡荡荡荡视频| 一区二区高清视频| 日日干夜夜干| 一二三区精品视频| 亚洲nv男人的天堂网| 少妇色综合| 天天射夜夜操| 日本少妇va7777| 91色插| 婷婷五月天在线观看| 欧美激情 一区| 91狼人| 青青草AV色| 午夜无码精品免费看性色| 好看的91视频| 亚洲欧洲中文日韩女优乱码| 男人的天堂激情| 男人午夜天堂| 人妻AV 中文字幕的| 精品欧美乱码久| 99热婷婷| 香蕉视频欧美一卡二卡| 日韩97超碰中文字幕| 超碰97护士| 久久久久国产亚洲一区欧美色图日韩| 秋霞Av理论一级在线| 黑丝91视频| AV乱伦专区| 久啪| 手机看片1024你懂的国产| 国产91丝袜在线播放蜜月| 丰满人妻一区二区三区大胸懂色| 久久这里只精品| 亚州伊人色综台| 男人天堂电影院| 国产性感骚丝袜在线| 日韩欧美操逼xxx| 欧美在线l亚洲| 岛国黄色大片网站| 大香蕉综合网| 美女主播色欲91抠b在线播放| 香蕉欧美| 天天内射| 九九热AV| 欧美在线永久天堂| 夜夜嗨一区| 激情一区二区三区在线观看| www.亚洲成人一区| 欧美色交| 2025亚洲男人天堂| 亚洲国产成人精品无码专区| 欧美综合天堂| 91网18| 精品超碰国产| 男女无套 免费网站| 欧美国产一区二区三区麻豆传媒 | 丰满人妻一区二区三区在线| 九九热免费国产视频婷婷伊人| 91无码西班牙视频在线| 久久久精品中文字幕麻豆| 五月婷婷六月丁香| 一区二区三区黄色片a| 亚洲国产97在线精品一区| 大香蕉 222| 久久男女激情视频网站| 2017av无码免费无线播| 97色操| 日本久久综合| 中文字幕第页| 综合欧美日本三级| 啪啪啪精品| 蜜臀久久久99久久久久 | 国产精品国产精品国产| 欧美丝袜美女电影一二三四区| 久久,精品一二三| 国产精品一级毛片不卡视| 国产传媒av天美传媒在线| 青青操视频在线| 欧美日韩人人精品| 丁香五月性| 黄页视频网站野外| heyZO天然素人无码AⅤ专区| 97在线观| 97伦综合| 精品中文一区二区| 天天内射| 一区二区不卡| 97干天天| 综合网欧| 屌妞视频久久久久久久| 小草三级久久观看| 九九99久久| 亚洲美女自拍偷拍视频| 在线无码视频| 国内精品久久人妻性色av| 天美传媒婬乱在| 性生活性生大爱77AV国产| 久9久精品视频| 91亚州欧美| 日韩内射视频| 久久久9品一区二区三区| 久久xxxx| 色五月婷婷麻豆在| 啊啊啊啊嗯嗯嗯用力好爽| 留下AⅤ黄色片| a天堂视频| 日韩亚洲中文有码视频| 国产一进一出视频网站| 岛国网址国产| 精品v日韩欧美国产| 亚洲天堂中文字| 女人被男人桶爽视频网站| 国产精品麻豆成人av| 中国操逼无码| 伊人精品久久网站| 五月婷网站| 丝袜剧情| 天天日天天干天天整| 国产剧情AV不卡在线观看| 亚洲日韩精品一区视频在线| 激情综合网五月婷婷五月天| 玖玖玖玖精品国产剧情| 人人透人人操| 亚洲色图久久成人| 偷拍亚洲高清图片| 999 久久久| 我想要啊 啊 啊| 人妻91少妇| 搡老女人老91妇女老熟女| 国产强奸乱伦第1页| 你懂的在线观看区国产| 亚洲成人一区二区精品| 九月丁香| 96AV久久久| 久热大香蕉网站| 麻豆天美在线| 国产精品内射婷婷一级二| 国产在线激情视频| 99啪啪视频| 精品视频123区小说区| 99在线观看无大码| 99久在线精品99re8| 97天天操| 久久久久久久国产视频| 一道本久久棕合爱| 国产偷人妻精品一区二区在线| 人伦四五区| 精品国模无码| 超碰人人干| 超碰在线人妻不卡| 欧美色干| 日韩精品 视频一区二区| 丁香五月激情综合| 久久久久久波多野吉衣高潮| 日本精品加勒比海一区| 亚洲色图尤物视频| 成人夜夜爽| 天堂精品| 亚洲精品国产无码高清| 中文字幕一区av| 9ⅰ久久久天天| 大香蕉免费3| 婷婷丁香成人| 校园春色宗合网| 狠狠爱综合| 中文字幕版| 无人区高清电影免费观看一区二区三 www.qmcai2.com | 91大神精品长腿在线观看网站| 日本日皮视频逼| 欧美一区二区成人一卡| 黄片www视频免费| 色五月激情综合网| 91男女| 强奸乱伦大香蕉| 色鬼在线综合| 国产亚洲色婷婷久久99精品91 - 百度| 人人透人人操| 久久华人网| 日韩亚洲精品一区二区| 亚州色图狠狠干| 亚欧免费观看视频| 69精品在线| 黄页av| www.狠狠操| 亚洲激情在线| www99热| 色狠狠一区二区三区香蕉| a天堂视频| 岛国不卡超碰护士AV在线播放| 豆花视频操逼网址| 久久婷婷在线观看视频| 激情熟女12P| 超碰97色色| 天天射天天| 亚洲男人天堂2012| 国产日韩手机视频在线| 精品然女一区二区| 欧美日韩国产三级黄色| 日日摸日日碰| 天天干天天操天天干天天操| 超碰综合97在线| 无码视频黄色网战| 成年在线视频日本亚洲在线视频区精品江靖宇公司 | 天天爽天天| 一区二区影视| 精品无码一区二区| 少妇一区二区三区高速| 4虎在线视频| 99热最新| 香蕉视频欧美一卡二卡| 毛片17S| 国产精品ⅴ无码大片在线看.| 亚洲一区二区 麻豆传媒| 亚洲一欧洲中文字幕在线| 久久超碰av在线| 91狠狠综合久久久久久| 国产成人亚洲精品无| 大香蕉在线视频重口味毛片在线| 久久久一二三四区| 国产乱伦亚洲| 中出20p| 女人爽到高潮久久久| 操操操五月天婷婷丁香影院| 亚洲成人色情五月天丁香花| 一区三区啪啪| 熟女人妻一区二区三区| 日韩情色AV| www.av在线观看| 亚洲加勒比久久日本道| 亚洲精品 欧美精品| 久久性爱免费送| 国产91影院| 97超碰中文字幕| 麻豆2区1区天美| 十八岁啪啪视频免费看| 九九九九九九九九九国产精品| 色婷婷成人综合| 3D污黄视频在线观看| 91人人| 天天激色| 欧美日韩人人精品| 国产精品亚洲美女久久久久| 91精品国产91久久福利| 少妇精品久久久八区九区| 日韩一级二级| 韩国一级做A片免费的| 欧美岛国精品在线观看| 91在线丝袜| 亚洲综合影视| 国产精品交换一区二区| 在线中文字幕极品av| 亚洲巨爆乳一区二区三区四季网| 好一吊区二区| 欧美成人综合| 宅男91视频在线播放| www.激情| 国产精品久久久久久 百度| 青娱乐老司机视频| 加勒比综合88| 亚洲双插| 天天日熟妇| 神马久久69| 亚洲综合网电影91| 国产成人久久久精品免费AV| 亚洲欧美中文日韩视频中国语| 国产黄色影片在线观看| 91爱| 久久高潮妇女视频| 天天情欲宗合网| 国产人妻一区二区三区欧美毛片| 黑操B| 亚洲色婷婷| 人人爱人人操人人性| A级毛片在线看免费| 国产强奸乱伦无码视频| 久久久96| 国产免费一区2区3区| 国产伊人精品在线| 欧美桃色网| 高清孕妇孕交 交孕妇| 亚州九九九精品视频| 91在线丝袜视频| 亚洲性猛交| 又摸又舔在线观看网站| 人妻社区男人天堂| 少妇69中文| 亚洲影院小综合| 熟女一区二区| 青青操少妇| A啊啊在线观看| 一区二区视频你懂的| 大香蕉在线免| 蜜臀AV成人精品蜜臀| 自拍视频大全亚洲专媒视频/一区二区三区| Julia在线播放亚洲久久| 久久九九网| 色婷婷在线视频| 69人妻人人揉人人躁人人精品| 精品人人| yazhousetuoumei| 日本东京热大香蕉a片| 丝袜亚洲91| 久久精品99| 一级AAA片一区二区三区| 欧美高清色| 大香久久| 1000部熟女视频在线观看| 激情天天视频| 333kkkk·亚洲com久久| 乱伦3P视频| 久久久久久亚洲精品不卡人乳| 97超碰国产精品| 亚洲精品骚逼| 国产精品动态一区二区三区四四| 91丝袜人妻| 欧美性xxxxx狂欢| 青青操综合网| av资源在线观看少妇| 午夜免费视频1000| 啊啊啊好舒服好爽啊啊啊视频| 99re这里| 久久一区二区蜜桃| 在线观看不卡一区二区三区| 美中日韩无码| 九九AV| 四季AV一区二区凹凸精品小说| 国产情色第一第二页在线观看| 91高清欧美| 欧美日韩国产一区二区小黄片大全| 99re国产精品视频| 99视频精品| 亚洲美欧999| 尤物AV免费网站| 久久国产逼| 午夜一区| 97碰碰日本乱偷人妻中文的| 999精品女人| 人妻中文字幕精品无码| 这里只有精品视频在线| 中文字幕版| 欧美春色| 韩国午夜理伦三级好看| 国产天天骚| 伊人9| 国产极品粉嫩馒头一线天av| 色噜噜综合网| 亚洲欧洲第二视频在线观看色图| 日夜精品| 91精品伊人久久久大香线蕉91| 成人影 天天操 亚洲| 人妻 欧美亚洲| 思思热在线视频免费| 国产免费一区在线观看| 成人一区二区三区四区| 91春色| 大香蕉人妻| 久久精品高清无码一区| 操啊国产| 天天综合AV| 久久精品无码一区二区三区| 日本熟妇人妻中出视频| 欧美72网页| 日本阿v天堂在线观看| 九九碰九九爱97| 欧美手机在线综合| 约操熟妇| 久久99精品九九久久久婷婷| 国产精品美女久久久久久网站| 午夜免费福利视频一区| 久久久久921| 隔壁邻居波多野结衣中文字幕 | 亚洲综合97中文网| 久夜操| 免费一级视频特黄色大片| 91成人久久| 国产精品探花视频| 国产免费久久精品99re韩国| 岛国成人av在线播放网址| 久久爽爽精品| 麻豆综合一区av| 在线 亚洲 网爆 自拍| 亚洲在线a| 丁香五月成人| 色九久| 亚洲无码色| 色五月av| 9/A片| 日韩视频中文字幕| 蜜桃中文字日产乱幕4区| 秋霞 色色| 国产农村妇女精品1区二区| 亚洲无992tv| 日少妇亚洲版| 亚洲一区二区三区不卡国产欧美| 亚洲淫色网中文| 秋霞久久亚洲精品成人| 都市激情人妻一区二区青青操视频 | 香一区二区三区| 国产精品成久久久久午夜午夜| 黄色成品网站| 国产最火爆久久国产网站网站 | 亚洲精品xxx| 少妇丝袜在线观看AV| 91小视频| 中文字幕在线免费观看 | 国产精品白丝www| 亚洲欧美激情另类色图| 超碰免费人妻人人| 吉川爱美亚洲二区在线| 人人操人人uiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii | 成人无码专区精品视频| 性爱网站一区二区| 亚洲涩图欧美| 久久思思热| 亚洲中文字幕在线视频一区二区| 伊人操操| 噜噜吧,噜噜色,噜噜| 亚州综合色| surenchaopeng| 久久久久9| 欧美v日韩v亚洲v最新在线| 91/欧美| 婷婷亚洲天堂| 国产无码精品成人| 加勒比久久av| 欧美三级不卡| 国产极品99热在线播放69| 欧美亚洲天天| 日韩99神马视频播放| 韩国三级理论在线| 天天看天天日| 人妻大香蕉| 国产青一二三| 超碰成人最新最好看| 91综合网站| 中文字幕人乱码中文字的预防方法 | 国产男女边吃边摸视频网站| 日本五区不卡| 97亚洲国产影视| 亚洲av无线观看| 亚洲自拍偷拍视频在线 | 青娱乐日韩无码| 欧美v亚洲v综合v国产v妖精| 玖色av| 青青草乱入乱欲视频在线观看| 麻豆这里只有精品| 26uuu偷拍亚洲欧洲综合| 欧洲精品二区| 欧洲性人爱视频| 人妻精品一区二区全免费| 色欲天天综合网| 国产精品久久久久亚洲av| 夜夜躁狠狠躁日日躁av| 91欧美巨乳| 色天使大香蕉| 亚洲熟妇自偷自拍另欧美| 亚洲αv一区二区三区| 国产一级舔足在线观看| 国产久久天堂资源| 无码人妻丰满熟妇区毛片| 中文字幕超碰CAO| 久久亚州高清| 97在线免费看| 婷婷五月天基地| 亚洲最大无码中文字幕网站| av无码av无码专区| 亚洲一曲日韩精品| 精品无码一二三四区| 色婷婷国产精品一区在线观看| 国产区在线| 打av高清| 蜜桃久久综合视频| 婷婷久久综合久| 欧美视频中文字幕区| 艹少妇网站| 香蕉久久AⅤ...| 特级特黄一级毛片免费| 国产一区二区三区高清视频| 日本二三四区| 欧美性高潮| 天堂亚洲精品| 人妻夜爽夜夜爽| 亚州,欧美在线| 啊啊啊轻点在线观看| 日本熟妇色熟妇在线视频播放| 国产精品午夜成人福利| 九月丁香婷婷| 欧美日韩国第一区| 国产农村妇女精品1区二区| 九九精品美女高溯喷水| 97午夜剧场日韩| 国产不卡精品91| 麻豆区99999| 啊啊啊啊啊啊好湿好爽视频| 好吊色一区| 国产久久一区二区| 日韩不卡一二三四| 日韩BBN| 国产精品乱码久久久久久久久| 日天天九九天堂666| 国产熟女无套内射| 男啪女色黄无遮挡免费观看| yaouchengrenav| 天堂俺去俺来也www久久婷婷| 伦伦成年午夜免费视频| 少妇高潮对白在线观看| 亚洲AV成人在线| oumeisetu综合| 欧美午夜色妇色鬼| 白丝在线一区| 人妻精品一区一区三区蜜桃91| 日韩在线观看AV| 国产97视频| 人人操人人大香蕉| 婷婷五月综合在线| 亚洲天堂性爱| 亚洲天堂日本| 91n处女在线观看| 91丨人妻丨国产丨丝袜| 色翁荡息又大又硬又粗又爽| 黄片aaaaa一区| 色情婷婷| 女同性恋一区二区三区精品视频| 欧美青青视频| 欧洲精品二区| 人妻一二三区| 九九AV| 韩国女主播青草福利视频| 秋霞一区二区三区四区五区六区七区| 中出20p| 日本韩国国产精品一区| 欧美成人一区二区三区在线播放| 情色AV电影| 人妻天天爽| 亚洲色人| 亚洲精品亚洲人成在线麻豆| 五月天黄色av| 一级免费精品| 视频一区二区三区精品| 亚洲超碰在线| 人人搡人人肉久久精品| 可乐操亚洲蜜911| 国产日韩区| 欧美精品成人亚洲| 岛国999| 最新无码国产| 九九久久综合| 秋霞鲁丝午夜无码一区二区三| 熟女精品日韩一区二区三区 | 日日黄色三级网站| 欧美性高潮| 中国zzijzzijzzwww精品| 欧美日韩99精品麻豆传媒| 人妻熟女一区二区| 最新av中文字幕高清| 婷婷五月天激情小说| 久久 久久国内精品亚洲| 日韩一级性爱无码| 亚洲激情网一二三四区| 久热99999| 久久精品中文字幕观看| 96AV久久久| 97亚洲欧美| 亚洲精品三| 碰人碰碰人人开房人肉| 欧美探花网| 少妇国产不卡| 欧美熟妇精品黑人巨大91| 午夜福利免费福利视频| 亚洲色资源| 国产精品免费1区2区视频| 色哟哟国产精品免费网址| 欧美 色 亚洲| 丁香五月婷婷基地| 精品人妻一区二区蜜桃视频| 人妻 中文 日韩| 日本精品性生活久久久| 可以免费看黄片的视频| 久久综合日韩亚洲欧美| 大学生美女口爆| 久久天天性久久伊人| 999精品乱码| 青青草视频久久| 亚洲中文字幕熟女少妇一区二区| 色婷视频| 日韩精品一二三| 色九九九九久| 中文字幕欧美丝袜07资源| 亚洲中文字幕97久久精品少妇| 伊香蕉综合久久久久久久噜噜噜 | 91在线丝袜| 亚洲一本大道中文字幕无码在线| 亚洲精品白丝| 欧美刺激色黄片免费看| 9.1小视频| 中文字幕成人| 91伊人| 国精品一区二区三| 久久久久久久久久va| 99re这里| 国产第25页在线观看| 羞答答AV中文字| 亚洲欧美国产日本一区二区三区| 97操B| 97久精品| 性爱视频无打码在线观看| 丝袜亚洲91| 一区在线国产播放| 日天天九九天堂666| 久操九九九九| 最新三级网址| 欧美色图99| 91欧美高清| 大香蕉免费3| 夜夜免费视频| www.久久| 日韩成人高清一区二区| 欧美伦乱爱| 黄片在线免费在线观看| 亚洲欧美另类小说| 狠狠操一区二区| 国产人妻天天干精品| 国产精品自拍视频| 北京美女一区二区| 九九性爱网| 日韩成年人性爱视频| 亚热日本熟女| 综合婷婷| 中文字幕日韩专区精品系列| 97在线资源| 激情99| 99老司机精品视频在线观看| 人妻大香蕉| 91逼逼女人91| 日韩成人大片一区二区| 97干色| 久久偷偷色综合蜜桃| 日韩人体偷拍| 欧美日韩香蕉| 91精品国产91久久青草 | 最近的最新的中文字幕视频| 亚洲一级黄色毛片| 一本大道久| 久久超碰免费的| 97综合在线| 交换娇妻呻吟声不停中文字幕| 久久尹人大香焦视| 福利在线视频一区二区| 亚洲精品 大香蕉| 五月天婷精品激情| 黑人免费福利视频| 东京热91| 天天综合网~91入口| 欧美成人精品一区二区三区| 日韩中文字幕在线视频观看| a片 xxxx受爽视频| 嗯嗯不要 视频| 日日日大屁股骚女人精品| 亚洲免费精品一区| 婷婷五月天丁香| 中国一区二区亚洲人妻| 国模无码人体一区二区三| 97资源亚洲| 中文字幕午夜精品久久久| 怡春苑东京热| 九九九久千久久激情蜜桃在线看 | 337p大胆噜噜噜噜噜91Av| 少妇啪啪自拍| 日本成人免费一区二区三区| 最新制服中文第一页| 日本亚欧爱爱| 91女优在线观看| 亚洲欧洲第二视频在线观看色图| 91 丝袜在线| 91男女啊啊啊| 男人天堂2012| 色色无码| 另类图片五月天| 亚洲五月婷婷| 91久久久久久久久18| 日韩精品在线观看网站| 草草网站影院白丝内射| 日韩中文字幕视频| 亚洲欧洲中文日韩女优乱码| 农村女一级毛卡片| 91中文字幕| 91天天综合| 精品欧美老熟女一二区| 任我爽在线视频免费观看| 俄罗斯及免费在线看| 婷婷爽人人婷婷爽视频| 国产成人五月天丁香花| 国产精品农村妇女精品| 超碰97综合网| 国产中文字幕在线观看| 夜夜精品视频一区二区| 天天影视91看看| 亚洲综合伊人无码久久| 北约熟女超碰| 成人精品久久久午夜福利| 日韩操逼性鲍| 约操熟妇| 欧亚免费视频| 久久乐|