欧美成人午夜精品久久久,国产?V天堂一区二区三区,欧美精品va在线观看,亚洲一区二区三区免费在线观看,av无码精品一区二区久久,欧美性爱视频不卡一区三区,欧美乱人伦视频在线观看,国产一级牲交高潮

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 過來的。當(dāng)你想抽個公共模塊統(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)一日期展示格式負(fù)責(zé)的老兄花了整整一個下午去改三套實現(xiàn)改完還不敢保證邊界情況全部覆蓋。如果當(dāng)初有一個統(tǒng)一維護的工具函數(shù)這個問題就是改一個文件、發(fā)一個新版、所有項目升級依賴這么簡單。但自建工具庫也不是毫無成本你需要配置構(gòu)建、測試、文檔、發(fā)布還要持續(xù)維護。所以正確的姿勢是先判斷“值不值得做”。我的判斷標(biāo)準(zhǔn)很簡單只要存在一個函數(shù)或組件連續(xù)出現(xiàn)在三個以上項目里并且它們的行為基本一致就值得沉淀進工具庫。如果只是當(dāng)前項目一處用到就先忍住別抽等第二次需要時再抽也不遲。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ù)于當(dāng)前頁面布局的巨型組件。這些代碼一旦脫離當(dāng)前業(yè)務(wù)環(huán)境就廢了硬塞進工具庫只會讓維護者為了抽象這些業(yè)務(wù)邏輯而頭疼。還有一個容易忽略的判斷維度團隊成員的使用習(xí)慣。如果你建了一個工具庫但其他項目的人根本不用那就是在自娛自樂。所以我在動手之前專門拉了一個清單把日常代碼里重復(fù)出現(xiàn)的小函數(shù)都列出來先統(tǒng)計使用頻率再決定首批放哪些工具。這一步看起來簡單實際決定了工具庫后續(xù)的活躍度。另外說一下為什么選 Vue3 JS 而不直接上 TS。我自己項目里有相當(dāng)一部分是遺留的 JS 代碼如果工具庫用 TS 寫雖然能提供類型聲明但構(gòu)建鏈路會復(fù)雜一截而且會讓不愿意碰 TS 的同事產(chǎn)生距離感。Vue3 的組合式 API 本身對 JS 的友好度很高很多邏輯根本不需要類型系統(tǒng)就能表達(dá)得很清晰。當(dāng)然如果你的團隊全員 TS那直接用 TS 寫會更好——工具庫的選型永遠(yuǎn)跟著團隊現(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 負(fù)責(zé)在提交前攔截不規(guī)范代碼。對一個公共工具庫來說質(zhì)量門禁是必須的因為代碼一旦發(fā)布出去被多個項目依賴任何低級錯誤都會被無限放大。2.2 Vite 的 lib 模式配置解析Vite 默認(rèn)構(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 標(biāo)簽里引用的人用的雖然現(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精準(zhǔn)引入這其實就是按需加載的另一種手段后面詳細(xì)講。這樣一個骨架搭完你就有了一個干凈的起點。接下來最核心的事情就是往里面填充真正有用的代碼。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)險就越大。當(dāng)實際需求超出這個范圍時直接按 dayjs 或者 date-fns 更合理不要試圖自己架一個完整的日期引擎。一個容易被忽略的細(xì)節(jié)入?yún)⒍x成date instanceof Date ? date : new Date(date)。這樣字符串日期、時間戳都能兼容并且當(dāng)傳入非法值時會顯式拋錯而不是返回一個又難看又難排查的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來示范一個標(biāo)準(zhǔn)寫法// 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è)計千差萬別強行做成通用往往兩頭不討好。我建議從沒有視覺綁定的功能型組件開始比如高亮文本。它負(fù)責(zé)接收關(guān)鍵詞把匹配到的片段用mark或其他標(biāo)簽包起來至于樣式直接由使用方的項目控制。用 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ī)則默認(rèn)要求組件名必須是多個單詞但對于工具庫來說很多通用組件就是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ū)里的文件速度很快也不會逼著大家把所有測試跑一遍。更嚴(yán)謹(jǐn)點的團隊可以在 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)代打包器的新標(biāo)準(zhǔn)它比 main/module 更精細(xì)能限制外部訪問包內(nèi)未聲明的路徑防止別人import my-utils/src/xxx這種奇怪的引用方式。files決定發(fā)布時哪些文件會被打進 npm 包這里只包含 dist 和 README能有效避免把源碼、測試文件全部發(fā)布出去既縮小包體積也避免暴露未編譯的內(nèi)部細(xì)節(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ā)依賴?yán)锏?vue前面說了打包時要把 Vue 設(shè)為 external但很多新手會掉進另一個坑既然 vue 是 peerDependencies是不是項目里就不用裝 vue 了不是的。你本地開發(fā)工具庫時仍然需要 vue 作為 devDependency因為組件和測試都要實際運行。peerDependencies 解決的是“使用方要自己裝 vue”而 devDependencies 解決的是“你在開發(fā)這個庫時需要 vue 可用”。我見過一個例子某位同事把 vue 從 devDependencies 里刪掉認(rèn)為發(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 默認(rèn)值本地構(gòu)建和測試都通過了直接npm publish結(jié)果有個項目升級后組件的樣式全亂了。原因是我漏改了另一處相關(guān)代碼但本地沒有實際業(yè)務(wù)場景測試也沒有覆蓋到所有 CSS 組合。從那以后我養(yǎng)成了發(fā)布前先用npm link或者yalc把包鏈接到實際項目里做冒煙驗證的習(xí)慣。npm link的用法很簡單在工具庫目錄里執(zhí)行npm link再在目標(biāo)項目里執(zhí)行npm link my-utils這樣目標(biāo)項目引用的就是本地源碼產(chǎn)物改動后的效果能立即看到。但 npm link 會改變 node_modules 的符號鏈接結(jié)構(gòu)偶爾會觸發(fā) vite 緩存問題所以我個人更喜歡 yalc——它會把本地發(fā)布文件“推”到目標(biāo)項目的 node_modules 里更接近真實依賴情況也不會因為符號鏈接導(dǎo)致某些工具無法解析。說到底工具庫開發(fā)的完整閉環(huán)是“編碼 - 測試 - 構(gòu)建 - 本地聯(lián)調(diào) - 發(fā)布”。前四步走得越扎實最后一步就越穩(wěn)。每當(dāng)我偷懶跳過本地聯(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ā)布版本沒有影響線上項目。這種細(xì)節(jié)點滴積累起來就是工具庫和其他人的隨手分享之間最大的區(qū)別。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
国产美女无遮挡裸体毛片A片| 99热精品在线| 久久婷婷五月综合| 青青草五月天| 色婷婷综合久色AV五色最新| 成人做爰A片免费看视频| 91丨九色丨43老版熟女| 色色操| 婷婷伊人久久| 五月丁香色婷婷| 丁香五月天激情婷婷丁香六月| 天天日,天天干,天天操| 激情综合婷婷| 毛v一区二区视频| 婷婷丁香在线播放| 色综合久久综合中文综合网| 六月婷婷色综合| 婷婷五月 丁香六月| 人人草人人舔| 亚洲一色色色色色色色色| 亚洲无AV在线中文字幕| 婷婷社区五月天| 超碰在线观看9| 亚洲AV网站在线观看| 久久伊人大香蕉| 免费视频无码| 大香蕉久久婷婷| 日本啪啪网| 人人摸人人摸| www.色色色色| 久久久com| 色色激情| 五月丁香淫淫婷婷婷| 婷婷九月丁香天堂丁香天堂| 99综合网| 在线只有精品| 婷婷五月天va| 黄网在线免费播放| 天天爽天天| 九月婷婷综合八月丁香在线观看| 亚洲免费av观看| 中文字幕视频在线播放| 五月婷婷伊人在线| 99婷婷五月天| 五月叮香啪| 激情綜合W W W,激情五月天| 久久免费婷婷视频| 日韩一区二区在线播放| 人人操操| 7777国产盗摄农村女人| 五月婷av| 丁香五月天激情视频| WWW,五月天| 久久看九九90| 久热免费视频| 久草五月婷婷| 亚洲色在线观看| 欧美婷婷丁香五月社区| 天天操天天干天天射| 九九色图| 激情婷婷五月天日本系列| 国产.亚洲.欧洲视频在线| 久久综合婷婷| 婷婷九月丁香| 第一区久久网站| 丁香五月婷婷偷拍| 亚洲正能量欧美| 婷婷五月天色色| 久草久青福利| 五月丁香六月激情综合网| 99热精品6| 丁香六月婷| 99久操视频| 丁香五月自拍| 丁香五月婷婷大香蕉| 丁香花五月天| 久久五月激情综合| 丁香五月ⅤA久久久| 色爱五月天| 99在热线免费视频| 新99思思视频| 五月丁香久久| 久综合| 五月天婷婷综合色| 五月婷婷六月丁香在线| 97精品自拍| 可以免费看AV网站| 欧美三级级99久久| 玖玖九九超碰| www婷婷色| 综合色情网| 色婷婷色五月天| 久热这里只有精品在线观看 | 久草五月天| 国产资源91在线| 婷婷成人网五月天| 成人色五月天婷婷| 婷婷五月激情网站| 久久只有这里精品免费| 丁香五月影院| 99色色爰| 丁香五月婷婷欧美激情-中文天堂最新版在线观看 | 亚洲婷婷欧美婷婷| 天天骑天天操| 久久激情五月婷婷| 天天摸天天舔| 亚洲无码99| 国产一级婬片毛片| 狠狠狠狠操| 青青草a在线| 亚洲人妻电影| 色情五月| 色九九九九| 成人AV播放| 五月天成人在线| 婷婷色五月噜噜| 丁香婷婷六月激情文学 | 日韩精品AV一区二区三区| 久操综合| 五月丁香六月激情欧美综合| 激情五月婷婷视频一区二区三区| 色综合伊人网| 婷婷五月花| 日本三级韩三级99久久| 六月婷久久| 五月丁香色婷婷色| www,色色色网站| 亚洲综合热| 开心五月深爱五月丁香五月激情五月| 黄色激情五月天| 婷婷激情丁香六月| 五月的色婷婷高潮| 五月激情综合网| 深爱五月天| 开心激情网五月天| 五月丁香婷婷欧美| 91精品久久久久久77777| 97色色网| 色综合色色| 九九激情网| WWW、99热| 色色亚洲无码| 久99视频| 五月婷丁香在线视频在线| 五月丁香少妇A| 五月丁香六月激情网| 国产高潮A片羞羞视频涩涩| 91操片| 蜜桃婷婷丁香综合久久开心亚洲| 先锋影音男人的天堂AV| 久久五月婷婷丁香| 99热欧美在线观看| 色婷婷丁香五月综合| 99热在线观看精品| 综合色情网| 欧美激情综合色综合啪啪五月| 99精品在线| 欧美电影在线观看| 亚洲av无码精品色午夜| 国产精品久久99| 99成人网站| 伊人五月网| 天天干com| 久久色五月天激情小说| 午夜一区| 五月婷婷色| 97超碰婷婷五月天| 久久婷婷国产| 婷婷五月久久| 久久五月网| 激情网五月天| 91日综合欧美| 影音先锋色婷婷| 噜噜操操| 婷婷欧美色| 99色在线观看| www夜夜操comwww| 中文av网| 亚洲精品又粗又大又爽A片| 丁香五月婷婷综合啪啪| 97干免费视频| 婷婷五月天偷拍| 99国产精品久久久久久久久久久| 搡BBBB搡BBB搡18| 日本三级99人妇网站| 激情綜合網址| 开心综合激情综合| 色播五月丁香| 婷婷人妻激情| 久久丁香五月婷婷激情综合网| 五月婷婷天天色| 国产综合网在线| 99性视频| 亚洲无码黄色| 婷婷深爱五月丁香网| 色色五月天丁香婷婷| 99色在线| 99精品久久久久久久婷婷| 亚洲综合丁香五月| 91久久1118| 五月天丁香婷婷网| 人妻爽爽爽久久久久久久久| 人人视频人人干人人做| www.9操| 丁香五月手机在线| 婷婷丁香激情综合色情| 九九99久久| 日韩高清久久| 日韩av一区二区在线/日产精品久久久| 丁香五月婷婷总啪啪| 亚洲一级色电影| 五月丁香青草综合啪啪| 婷婷久久五月| 99视频九九热| 五月丁香成人视频| 在线免费视频caop| 日日噜噜久久婷婷五月天| 久久99网| 免费观看欧美成人AA片爱我多深| 色色九九五月天 | 色色色色色网站| 永久精品| 丁香蜜臀黄色婷婷五月天| 一级A片天天操夜夜操| 99re6久热只有精品6在线直播| 久久性爱视频| 亚洲成人网站在线观看| 五月婷婷激情综合网| 极品少妇高潮啪啪AV无码| 99热99美国在线观看| 日本无码专区| 五月丁香六月婷婷久久久综合| 激情婷婷五月| 精品人妻在线| 提提热五月天婷婷| 婷婷五月天堂| 丁香五月婷婷综合啪啪| 色婷婷五月天天天做| 超碰免费99| 婷婷五月娱乐在线| 啪啪干伊人婷婷| 成人av在线网址| 精品婷婷丁香五| 亚洲啪| 色色影院aaaav| 综合激情站| 91丨九色丨白浆秘| 99精品在线观看视频| 超碰国产一区| 久久思思精品| 99热只有精品在线| 五月天色不卡| 丁香蜜臀黄色婷婷五月天| 久热9热| 丁香婷婷视频一区二区| 九九九九九九热| 2025天天爽天天摸| 嫩BBB槡BBBB搡BBBB| 久久婷五月| 大香蕉中文| 婷婷色五月天色| 激情小说视频图片| 夜色综合网| 五月丁香啪啪| 久热AA| 99久久99久久| 我爱大香蕉| 9久视频| 99视频35精品视频在线观看| 天天天天干| 无语停婷丁香网| 五月天激情婷婷小说| 玩熟女五十AV一二三区| 五月婷婷天| 五月色婷丁香| 无码人妻激情| 婷婷四月 成人 狠狠干| 少妇高潮呻吟A片免费看软件 | 婷婷丁香成人| 97婷婷丁香五月| 国产免费一区二区在线A片视频| 九九综合视频在线观看| 国产精品久久久久久久久久免费| 精品少妇蜜臀91| 色五月婷婷777| 丁香五月婷婷骚视屏| 伊人婷婷大香蕉在线| 亚洲小视频免费观看| 天天日天天舔| 五月婷婷丁香在线视频| 婷婷五月天丁香综合网| 婷婷五月天综合AV| 91丨九色丨43老版熟女| 欧美人与性动交CCOO| 亚洲九区| 99热这里只有精品3| 亚洲激情无码久久| 九九综合色| 欧美啪啪五月天| 五月天四色房丁香亭亭| 久久婷婷久久| 国产毛片精品一区二区色欲黄A片| 色五月丁香五月五月婷婷| 97色色网| 一级性爱视频| 婷婷五月色情天| 丁香五月婷婷啪啪| 淫水导航| 久久人人九| 婷婷五月天色播| 五月丁香婷婷综合激情基地| 色五月丁香A欧美com| 五月婷婷色激情| 色婷婷偷拍| 99久久网站| 日本九九热| 五月丁香五月丁香五月丁香五月丁香91| 欧洲亚洲免费视频9| 啪啪 综合网| 99久久久久| 99爱精品视频| 99久久婷婷国产综合精品青桔| 色色99| 热久久77777| 婷婷六月偷拍| www.色五月| Www.狠狠| 另类图片激情五月天| 丁香五月婷婷婷桃花影院| 九九热精品在线| 日韩色色视频| 五月丁香欧美综合| 操人妻90p| 97碰91| 久久激情综合| 九九热国产| 婷婷综合久久| 丁香五月婷综合| 欧美激情VA永久在线播放| 五月开心婷婷中文字幕| 成年视频免费观看| 在线中文AV| 婷婷久热| 99热这里只有精彩| 婷婷色激情网| 激情五月婷婷| 婷婷五月天精品| 丁香六月天之亚州热女 | 97se视频在线| 五月婷婷 六月丁香| 97色婷婷在线观看| yjzz亚洲国产| 久久思思热| 天天爽免费视频| 无码九九| 天天操无码| 四川操逼站| 99热9| 噜噜色婷婷| 日韩一66精品| 久久9视频| AV在线二十六页| 国产精品美女久久久久AV超清| 色欲午夜无码久久久久久张津瑜| 激情五月少妇| 丁香婷停五月激情综合深爱| 五月综合视频在线| 激情综合五月丁香| 99亚洲视频| 色情网综合| 天天舔天天摸天天透| 色色精品色| 日本99色| 丁香香蕉婷婷| 久9热插入| 人人干人人看| 五月天精品视频| 5五月综合网亚洲| 五月综合精品| 国产精品A片| 涩综合网| 色婷婷久久综合久色综| 偷偷操99| 婷婷五月日本| 丁香五月激情久久麻豆| 少妇高潮呻吟A片免费看软件| 狠狠色综合网站久久久久| 91婷婷五月天嫩女| 99在线视频精品| 欧美大奶熟女噜噜噜噜| 欧洲永久精品| 天堂婷婷五月在线| 激情五婷精品网在线观看网址| 婷婷五月天综合AV| 亚洲免费av在线| 五月天婷婷激情在线色图| 99婷五月| 九月色婷婷婷| 色一情一乱一伦一区二区三区| 99热超碰| 天天骑天天操| 欧美日韩91| 超碰日日操| 色综合99| 秋霞成人毛片一级A片| 色五月婷婷很很操| 色播丁香婷婷五月激情| 天天激情视频| 99久久综合精品五月天| 五月天,激情四射,婷婷频道| 九九热在线99| 9月色婷婷| 久热亚洲| 国产精品美女| 五月天播播综合| 婷婷性爱综合| 五月天婷婷情色| 婷婷久久丁香五月| 5月激情天| 秋霞黄色一级久久| 色色色综合视频| 色婷婷丁香五月天在线视频| 99久久99热这里只有精品| 777.色色| 色综合综合色| 思思久久精品| 婷婷五月天影院| 79精品视频在线观看,| 激情小说五月天| 99九九热在线观看| 色婷婷久久综合| www.狠狠| 欧美69久成人做爰视频| 天色色综合网| 亚洲操逼网| 久久丁香五月婷婷激情综合网| 丁香五月婷婷六月婷| 久久机热这里只有 | 97色视频网| 色很久综合| 99九九综合久久九九| 色10月婷婷视频| 亚洲综合网激情小说| 97人人干人人操| 婷婷丁香高潮了| 六月丁香成人网| 97久久香草精品视频| 激情的五月| 日屌日日操日日色| 亚洲免费观看高清完整版AV线| 色色色网站| 亚洲激情网| 色色99| 天天操天天国产三级片处女学生妹| 精品国产a| 日本三级日本三级三级人妇四虎| 狠狠搞综合色| www99热| 九九热99热| 婷婷成人综合| 久婷婷视平| 91色吧网| 99无码视频| .肏屄视频一区二区| 91色在线 | 日韩| 夜夜躁婷婷AV| 久久狠狠色| 婷婷狠狠操| 五月开心网| www.ywav| 伊人五月综合网| 91人妻人人操人人爽| 六月色伊人婷婷| 人人爱国产| 天天做天天爱天天爽| 五月天天综合网色婷婷| 激情四射五月天偷偷看婷婷| 五月婷婷中文字幕| 大地9中文在线观看免费高清| 综合激情四射一theav| 铁牛TV人妻| 日本五月丁香| 香蕉久久国产AV一区二区| 91chinese在线| 亚洲五月天色色| 日韩免费乱轮网站| 久久色亭亭五月天| 99精品免费| 99热69| 五月婷婷黄色视频| 少妇综合网| 日曰躁夜夜躁2026| 欧日美女Va| 丁香五月六月激情久久| 91丨九色丨大屁股| 国产精品91抖高| 九九99精品| 婷婷五月六月丁香| 五月丁香婷婷伊人| 婷婷五月欧美综合| 丁香五月六月综合欧美| 色亭亭影园| 婷婷激情肏屄网| 成人丁香| 色偷偷AV亚洲男人的天堂| se.久久视频在线观看| 六月婷婷色五月| 91日韩在线| 99久在线精品99re8| 色五月情| 久久五月天合网| 五月婷婷熟女| WWW·色色色·COM| 色色色色色色色色综合网| 裸体做A爰片毛片A片免费| 久久综合干| 激情九九综合网| 专区无日本视频高清8| 99自拍视频网站| 五月天亚洲综合网| 潮汕成人AV片在线| 亚洲婷婷开心五月| 婷婷天堂站| 亚洲AV在线免费看| 婷婷五月天受日本法律保护| 色婷婷狠狠爱| 成年人夜夜喷水| 五月天成人在线视频网站| www天堂99| renre人人操国产超碰在线| 五月婷婷九九热| 欧洲区自拍| 久久HD| 色99热| 九月久久婷婷| 影音先锋天天日| 性爱七区| 五月激情天| 天堂久久大香蕉| 欧美色六月婷婷| 久久er99热精品一区二区| 五月开心婷婷网| 超碰成人在线观看| 久久婷婷内射| 五月婷婷 激情五月| 青吴乐视频| www·五月天| 欧美内射AAAAAAXXXXX| 久久精品婷婷| 婷婷五月天婷婷| 桃色五月婷婷| 婷婷丁香五月综合激情视频| 东京热五月婷婷| 超碰五月婷婷五月天| 5月婷婷性视频| 天天做天天爱天天高潮| 婷婷激情五月综合基地| 五月丁香久久久| 五月丁香婷在线| 国产人妻人伦精品一区二区| 婷婷色五月久久| 国产乱妇无乱码大黄AA片| 开心深爱五月天| 白人荫道BBWBBB大荫道| 九九这里有精品视频| 日本猛少妇色XXXXX猛叫| 五月婷久久| a网站免费观看| 激情WWW| 91呦呦呦| 超碰人人99| 九九综合九九| 日本欧美成人片AAAA| 96性爱视频| 日本欧美成人片AAAA| 丁香五月婷婷激情123| 婷婷丁香91综合| 九九在线这里只有精品视频| WWW,五月| 婷婷五月天久久久| 五月香蕉婷婷| 一级韩国产精品毛| 色丁香五月天| 狠狠草婷婷| 99热这里只有精品3| 99精品久久久久久久婷婷| 五月婷婷丁香六月| 六月天丁婷婷| 欧美三级级99久久| 婷婷狠狠操| 奸逼视频| 丁香五月色激情| 激情五月天啪啪| 五月天天天操天天爽夜夜操| 青青草国产亚洲精品久久| 欧美成人精品老美女噜噜噜| 激情综合色网| 很很干在线视频| 亚洲婷婷丁香五月| 五月婷中文字幕| 色国产五月| 黄色三级毛片中字| 免费黄色AV| 午夜大香蕉| 日韩AV中文在线观看| 噜噜狠狠色| 婷婷色五月综合丁香| 99精品视频免费观看近期发布| 婷婷五月婷婷| 欧美色骚婷婷五月天| 丁香六月激情国产| 丁香六月激情综合| 色色热| 精品婷婷五月视| 久久色9| 91婷婷丁香| 久久成人天| 亚洲激情综合网| 久婷狼色诱惑在线| 青青草成人网| 激情五月婷婷综合| 婷婷激情蜜桃玖玖丁香| 97在线精品视频| 久九色| 色婷婷九月| 色色色欧美| 99激情视频| 五月天婷婷久色| 国产精品日日躁夜夜躁| www.色色色com| 九九色色| 五月天激情国产综合婷婷| www.精品99| 婷婷五月综合色拍| 丰满少妇猛烈A片免费看观看| 久久色五月天| 日日干夜夜撸夜夜骑| www.91婷婷| 天天干天天干天天干| 无码橾| 日本老女人黄页在线播放| 超碰在线超碰| 嫩草AV久久伊人妇女超级a| 激情综合五月| 丁香婷婷超碰 | 日日色五月天| 亚洲国产婷婷色五月| 婷婷五月色播天| 五月婷色| 99精在线| 五月婷精品| 婷婷五月六| 亚洲精品五月| 丁香婷婷人妻| 久婷| 丁香婷婷天堂| 国产午夜精品AV一区二区麻豆 | 五月丁香啪啪啪啪| www一区二区三区| 看黄的网站18禁| 美女激情综合| 九九色大香蕉| 九九十99视频| 色爱爱综合网| 久久综合首页| 九九热99免费视频| 91五月花丁香| 色五月综合激情网| 91中文狠狠综合| 99在线精品免费视频| 97久久久| 97精品欧美91久久久久久久| 怕怕av| 免费国产VA国产免费| 久久九九精彩| 久久小视频| 久久与婷婷| 激情六月婷| 五月综合影院| 天天操天天爽天天爱| 亚洲永久四色| 秋霞免费三级片| 99热超碰在线| 人人亚洲| 秋霞黄色一级久久| 色婷婷91| AV无码免费| 日本婷久久| 4399成人黄A片| 六月丁香久久| 久久五月天婷婷| 性色99| 这里只有精彩亚洲视频推荐| 婷婷五月丁香综合激情小说| 色狠狠六月| 欧美色色色| 色色色.COM| 久久久这里有精品| 色九月婷婷丁香| 精品久久9| 久久五月婷婷丁香| 99久久婷婷国产综合| 99精品在这里| 精品一二三区久久AAA片| 99色视频| 高清一区二区三区日本久| 性按摩玩人妻HD中文字幕| 激情五月丁香五月| 另类少妇人与禽zOZZ0性伦| 免费看欧美成人A片无码| 99久久97| 婷婷欧美激情| 大香蕉人人网| 九九黄色网| 色五月开心五月激情五月| 天天爽人人爽| 五月天久久91| pacopacomama 070722_670 素人奥様初撮りドキュメント 103 大久保純子 | 久久婷婷国产| 亚洲黄网在线| 一区二区传媒视频| 超碰在线播放免费观看| 婷婷综合亚洲| 亚洲九九免费| 五月丁香人人婷婷在线观看| 噜噜网免费视频| 色婷婷九月综合| 丁香五月天之婷婷影院| 三级毛片视频| 亚洲黄网在线| 日本色色网| 五月激情丁香久久综合网| 播播网色播播| 99自拍网| 五月天亭亭俺也| 婷婷六月网| 久久伊人大香蕉| 色婷久久| 99久久婷婷五月天| 色五月五月丁香| 成人丁香五月天Av| 九九av| 亚洲啪啪自拍| 99热成人精品| www999日韩精品| 欧洲亚洲免费视频9| 婷婷热婷婷色| 2025天天日爽| 色色无码| 婷婷丁香综合| 亚洲天堂亚洲色色色| 免费观看的婷婷五月视频在线| 超碰在线视屏| 亚洲激情四射色| 色欲影香| 99人妻碰碰碰久久久久视| 看黄的网站18禁| 色狠狠六月| 五月天激情四射网站| 六月婷婷激情| 99精品丰满| 99色久| 九九热a| 99久久99热| 五月丁香网站| 亚洲网视屏| 久热精彩视频98| 人人爽在线视频综合网| 影音先锋偷偷色男人站| 婷婷性爱| 97精品综合久久内射| 色五月婷婷婷婷婷婷婷婷婷婷| 五月丁香天堂网| 色区久久| 超碰在线caop| 色色色激情| 日本婷色| 97人人操人人插| 久久99热这里只有精品首| 99色免费视频| 五月天婷婷色| 色色色干| 99这里只有精品99| 内射人妻视频国内| 99久热在线精品| 丁香五月婷婷亚洲综合精品在线| 日韩另类| www.久久爱.c n| 99 热| 国产婷婷五月色情综合| www.色五月| 丁香五月电影院在线观看| 综合激情五月综合激情五月激情1| www.jiujiujiu| 99久高清视频| 天天插天天很| 99视频只有精品| 五月婷婷色综图片| 蜜臀嫩草| 欧美激情综合五月色丁香| 五月天丁香综合在线| 五月婷婷丁香五月亚洲色| 色婷婷五月视频| 婷婷五月天开心网| 99热综合网| 激情五月天小说网| 操逼五月婷婷| 五月丁香久久激情网| 涩涩五月天| 大香蕉视频婷婷| 涩涩五| 被男人添B超爽视频| 五月婷婷三级| 青青福利网| 久久人妻熟女一区二区| 永久99免费视频网站| 91丨九色丨熟女|老版| 精品九九网| 四虎婷婷五月天| 专区无日本视频高清8| 71在线精品视频一区| 天天日日人| 五月天国产| 久久五月天激情美女| 深爱五月激情| 日韩小视频在线99| 狠狠五月天婷婷| 五月天婷婷影院| 99热99热在线观看| 激情丁香五月婷婷| 国产资源在线视频| 99在热线免费视频| 高清国产一级婬片a免费| 丁香八月综合激情| 开心激情站| 五月天婷婷激情小说| 日本熟妇乱妇熟色A片蜜桃| 立川无码av| 嫩草AV久久伊人妇女超级A| 99色这里| 欧美槡BBBB槡BBB少妇| 色亚洲视频| 99精品偷自拍| dingxiangtingtingliuyue| www.色五月| 色婷五月| 五月黄色婷婷| 91视频综合网| 五月丁香激情四射综合| 四月婷婷丁香| 婷婷九月在线| 伊人AV五月婷| 黄色aa观看aaguochan| 夜夜骑天天操| 久久大香蕉同僚| 五月婷婷亚洲| 色久女| 五月天婷婷综合网| 狠狠夜夜五月丁香| 色综合99无码| 色亚洲无码| 日日干日日| 九九热99re8热免费观看| 欧美性生交XXXXX无码小说| 熟女五月天久久综合| 伊人婷婷99热精品| WWW五月天| 久久五月丁香综合| 五月激情婷婷丁香| 日本久久高清| 丁香五月综合| 激情婷婷狠狠干| 婷婷99视频在线| 色婷婷亚洲五月天| 久久久九九九 99| 久婷五月| 九九综合伊人| 啪啪一区| 人人干AV| 色天使色婷婷| 婷婷五月在线视频| 婷婷成人丁香色情基地30| 中文字幕按摩做爰| 亚洲色色色色| 99免费热视频在线| 日本精品人妻无码77777| 99视频这里只有久久精品| 91av色色乱视频| 综合五月婷婷| 狠狠色激情综合| 99久久国产宗和精品1上映| 99亚洲精品视频| 99热乎| 91综合网| 婷婷激情图片| 另类综合婷婷五月天欧美视频| 91色综合网站在线| 99在线69| 色欲五月婷婷| 久久99久久久久久| 中文AⅤ大全| 婷婷涩涩网| 97超级操操| 涩五月婷婷| 五月草影视| 三级三久久线久久99久目本WW| 在线只有精品| 99热免费| 婷婷五月天激情小说网站| 99干日本| 狠狠色综合图片| 亭亭五月色男人| 五月六月婷婷| 丁香婷婷五月天校园春色| 天天插天天插| 婷婷六月色开| 婷婷五月天伊人在线| 激情丁香久久久久久| 香蕉久久av一区二区三区| 亚洲丁香婷婷丁香五月天激情| 亚洲第一色色色色| 久久人人九| 成人性生活免费观看。| 狠狠操综合| 色色国产| 天天弄天天爽| 9999热在线免费观看| 99热这里只有精品99| 久青操| 97亚洲色 torrent magnet| 五月花激情网| 97干干干丁香| 夜夜撸日日操| 色九月国产| 亚洲精品又粗又大又爽A片| 亚洲在线操| 一起草性爱不卡视频| 美女100%露全身无挡网站| 九九久久五月天| 韩日AV片| 懂色av粉嫩av蜜臀av| 小视频久久久aaa| 桃色五月天| 免费久久这里只有精品99| 婷婷丁香五月天婷婷| 国产乱子轮XXX农村| 99乱视频| 这里只有精品免费视频在线观看| 99久久国产成人精品| 精品9久| 午夜精品人妻无码一区二区三区| 超碰99在线| 成人电影AV在线观看| 99这里都是精品6| 五月激情网综合| 玖玖资源网站最新站| 天天色丁香| 9伊人网| 中文字幕成人| 开心综合激情综合| 一级片无码| 少妇AB又爽又紧无码网站| 99色热视频在线| 色色色色色色97| 国产综合激情五月久久| 思思热天天看| 啊V视频在线观看| 色哟哟www| 九九久久色| 中文字幕日本最新乱码视频| 无码免费人妻A片AAA毛片西瓜| 丁香五月天堂网| 天天狠天天叉| 99性视频| 99热在这里只有精品| 婷婷操逼| 婷婷五月丁香超碰| 深爱激情网五月天| 色综合久久综合| 国产肥白大熟妇BBBB视频| 色色国产| 精品国产AV色一区二区深夜久久| 99热这里有精品| 成人精品视频99在线观看免费| 日日夜夜狠狠| 免费视频WWW在线观看网站| 国产精品扒开腿做爽爽爽A片唱戏| 日韩成人无码人妻| 成人在线精品| 天天精品视频免费观看| 99热最新网址| 91人碰| 婷婷五月丁香六月| 亚洲午夜成人av电影网| 超碰在线观看caop| 人人色婷婷五月天| 婷婷丁香五月亚洲| 人人操AV| 91亚洲天堂| 色情丁香五月婷婷精品| 九九亚洲小视频| 色婷婷AV在线| 青青草青青草五月天| 九九人人看| 亚洲射激情| 婷婷八月丁香激情综合| 国产AV一区二区三区最新精品 | 51精品国自产在线| 色玖玖爱| 五月丁香人人婷婷在线观看| 午夜亚洲国产精品av一区二区| 久久婷婷丁香花综合网| 婷婷五月天丁香社区| 久香草视频在线观看| 99热精品在线播放| WWW、日本色丁香、co m| 午夜理论片最新午夜理论剧| 日韩久久这里只有精品| 任你草| 九色亚洲| 深情六月婷婷综合久久| 国产激情在线| 婷婷五月综合性爱| 五月花婷婷在线精品视频| 99这里只有精品| 亚洲精品又粗又大又爽A片 | 五月天大香蕉| 91色综合久久| 精品视频99看在线视频| 九九热欧美| www.久久| 狠狠穞A片一區二區三區| 日韩精品成人在线| 亚洲激情97五月天| 精国产品一区二区三区A片| 激情五月天色网站| 在线只有精品| 久久加勤综合| 婷丁香五月天| 婷婷五月天开心网| 久久久久网站| 天天操人人干| 91夫妻网站九色| 丁香婷婷六月激情文学| 男人天堂99| 亚洲人人操| www.亭亭五月天| 中国女人内射6XXXXX| 丁香婷婷综合激情五月色,开心五月丁香花综合网,激情综合五月亚洲婷婷,五月天 | 天天肏视频| 九九精品亚洲| 深情五月天| 丁香五月婷婷av影院| 五月婷婷激情色情网| 国产67194| 超碰91在线| 人妻AV在线观看| 天天操天天曰天天射| 五月婷婷中文字幕| 天色色综合网| 五月的丁香六月的婷婷| 97色在线| 久碰视频| 丁香五月性| av久热| 亚洲成人中心| 色五月婷婷自拍| 五月停停丁香| 男人的天堂婷婷色五月| 色色色色色色色色色999| 成人综合网站| 狠狠色激情在线| 天天爱天天爽| 俺也去在线久久精品23欧美综合视频网站,丰满人妻一区二区三区在线视频53,丰满 | 激情综合一| 五月婷婷xxx| 啊V视频在线观看| 人人妻人人澡| 色婷婷www| 射区导航| 婷婷色啪| 成人一级片| 六月婷婷av| pom538精品视频| 天天做天天爱天天高潮| 另类 在线| 天天搞天天色综合| 超碰日日操| 五月婷婷三级| 亚洲操人| 色香欲综合| 99在线爽| 亚洲日韩一页精品发布| 秋霞电影理论| 色五月色综合| 婷婷六月激情丁香| 精品欧美性爱超级爽| 天天狠狠色| 182无码| 天天天久久人人人合| www.亭亭五月天| 国产永久一二一起草| www.久久| 九九视频免费| 欧美韩国日本| 色五月天网| 婷婷WWW久久| 色五月av| 色碰碰| 另类图片五月天| 丁香婷婷少妇| 美女被操一区二区| 五月婷婷在线视频观看| 丁香五月婷婷亚洲色图| 狠狠操综合| 激情综合5月| 无码人妻少妇色欲AV一区二区| 九九热这里只有精品12| 久久大香蕉丁香| 五月丁香免费看| 玖玖婷婷综合| 国产日日操夜夜操的肉棒视频| www.ywav| 丁香六月婷婷综合在线| 五月婷婷黄网站大全| 久久丁香五月婷| 色五月婷婷777| 婷婷五月天论坛| 婷婷酒色网| 免费视频这里只有精品| 五月色婷丁香| 一级性感毛片| 色婷婷基地| 日本三级韩三级99久久| 天天日天天舔天天摸| 99国产精品久久久久久久久久久| 这里只有精9| 久久R激情| 五月丁香在线看| 久99综合婷婷| 99视频内射三四| 熟女重口味αV| 97干在线免费| 天天干天天爽天天爽| 九九热99在线视频| 性 色 婷婷| 91人在线观看| 五月婷婷中文字幕| 婷婷五月天论坛| 色色五月丁香婷婷综合| 日本色天堂| 婷婷玖玖丁香| 国产超碰在线| 99热这里只有精品最新网址| 久久婷婷视频| 色综合色色色| 69激情小说| 亚洲无码AV片| 色婷婷五月网| 五月婷婷综合在线视频| 九九色图| 亚洲XX日本| 超碰在线94| 亚洲中文字幕av| 久久婷婷色情7777网站| 婷婷五月六月| 伊人婷婷激情| 欧美久人人| 婷婷的久久网站| 日韩AAA| 综合玖玖偷拍| 色色色9| 五月婷在线视频免费看| 欧美极品999| 日本韩国视频在线观看社区免费的9| 97极品在线| 婷婷啪啪| 久久综合最新网址| 99精品久久| 丁香五月婷在线观看| 色欲天天综合网| 人人操人人妻| 久热99| 亚洲成人乱码av网站| 第四色五月婷婷| 久热一区| 丁香五月激情综合| 婷婷久久六月天| 一起草av在线观看| 欧美性色A片免费免费观看的| 中文成人在线| 成人九九视频| 丁香蜜臀黄色婷婷五月天| 播丁香五月婷婷欧美| 97福利视频| 九玖欧洲亚洲| 五月丁香| 国产亚洲网站在线| 婷婷丁香五月综合| 亚欧州精品视频| 五月精品免费XXX| 婷婷成人网五月天| 99色五月| 另类国产欧美视频| 天天干夜晚夜操| 激情五月天网页| 久久人妻久久久久| 91男人操女人视频| 激情综合网址| 五月丁香六月综合基地| 99久视频| 久人操| 西西4r午夜剧场| av大香蕉| 亚洲综合五月天婷婷丁香| 亚洲欧美999| 综合性视频99| 婷婷伊人| 大香蕉狼人久久| 激情五月九九九| 久久caop| 亚洲精品视频在线播放| 色婷婷综合久久久久| 综合五月婷婷| 国际国外精品欧洲南美洲专区无码不卡| 亚洲黄色影视| 久久久久久久久久久44| 9热在线| 久久精品99国产精品日本| 久草五月天| 激情五月天免费视频| 丁香婷五月天| 超碰成人在线观看| chaopeng在线人人| 成人做爰高潮A片免费视频| 91色噜噜狠狠狠狠色综合| 五月天深爱激情网| 天天干天天 亚洲| 97热这里精品在线视频| www.久99| 在线视频区| 怡红院AV亚洲一区二区三区H| 色播五月婷婷| 二色AV| 另类图片色五月| 久9久成人精品视频| 亚洲另类婷婷五月综合| 婷婷五月天亚洲色| 深爱五月婷婷开心中文字幕| 噜噜色天天开心| 久久性视频| 99色色| 色综合狠狠色| 九九人人看| 亚洲色五月婷婷| 91人人妻人人操人人爽| 九月停停| 97超级碰人人| 国产69精品久久久久999小说| 国外亚洲成AV人片在线观看| 日日干日日| 91无码高清| 色玖玖综合| 五月婷啪| 91九色国产| 日韩成人电影AV|