日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

webpack基础学习,各个loader和plugin的具体配置

發布時間:2023/12/29 编程问答 75 豆豆
生活随笔 收集整理的這篇文章主要介紹了 webpack基础学习,各个loader和plugin的具体配置 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、邂逅Webpack

Webpack是什么

webpack是一個靜態的模塊化打包工具,為現代的JavaScript應用程序;

  • 打包bundler:webpack可以將幫助我們進行打包,所以它是一個打包工具

  • 靜態的static:這樣表述的原因是我們最終可以將代碼打包成最終的靜態資源(部署到靜態服務器);

  • 模塊化module:webpack默認支持各種模塊化開發,ES Module、CommonJS、AMD等;

  • 現代的modern:我們前端說過,正是因為現代前端開發面臨各種各樣的問題,才催生了webpack的出現和發展;

二、webpack配置和css處理

webpack配置文件

1、出口、入口的配置

我們可以在根目錄下創建一個webpack.config.js文件,來作為webpack的配置文件:

module.exports = {entry: " 指定入口路徑",output: {filename:"bundle.js", // 出口名字path: '出口路徑'} }

2、css-loader的使用

loader是什么

  • loader 可以用于對模塊的源代碼進行轉換;

  • 我們可以將css文件也看成是一個模塊,我們是通過import來加載這個模塊的;

  • 在加載這個模塊時,webpack其實并不知道如何對其進行加載,我們必須制定對應的loader來完成這個功能;

module.rules的配置如下:

  • test屬性:用于對resource(資源)進行匹配的,通常會設置成正則表達式;

  • use屬性:對應的值時一個數組:[UseEntry]

    • UseEntry是一個對象,可以通過對象的屬性來設置一些其他屬性

      • loader:必須有一個loader屬性,對應的值是一個字符串;

      • options:可選的屬性,值是一個字符串或者對象,值會被傳入到loader中;

      • query:目前已經使用options來替代;

    • 傳遞字符串(如:use: [ 'style-loader' ])是loader 屬性的簡寫方式(如:use: [ { loader: 'style-loader'} ])

  • loader屬性:Rule.use: [ { loader } ] 的簡寫。

module.exports = {entry: " 指定入口路徑",output: {filename:"bundle.js", // 出口名字path: '出口路徑'},module: {rules: [{test:/\.css$/,// loader:"css-loader" // 寫法一// use:["css-loader"] ? //寫法二// 寫法三use:[{loader:"css-loader"}]}]} }

3、style-loader

當我們通過css-loader來加載css文件時,代碼沒有生效。這是因為css-loader只是將.css文件進行解析,并不會將解析之后的css插入到頁面中,而style-loader將完成插入style的操作

注意:因為loader的執行順序是從右向左(或者說從下到上,或者說從后到前的),所以我們需要將styleloader寫到css-loader的前面

? ? ? ?use:[{loader:"style-loader"},{loader:"css-loader"}]

4、less-loader

? ? ? use:[{loader:"style-loader"},{loader:"css-loader"}{loader:"less-loader"}]

5、瀏覽器的兼容性

認識browserslist工具

  • Browserslist編寫規則一:

    • defaults:Browserslist的默認瀏覽器(> 0.5%, last 2 versions, Firefox ESR, not dead)。

    • 5%:通過全局使用情況統計信息選擇的瀏覽器版本。>=,<和<=工作過。

    • dead:24個月內沒有官方支持或更新的瀏覽器。現在是IE 10,IE_Mob11,BlackBerry 10,BlackBerry 7,Samsung 4和OperaMobile12.1。

    • last 2 versions:每個瀏覽器的最后2個版本。

配置browserslist

  • 方案一:在package.json中配置;

    "browserslist": ["last 2 version","not dead","> 0.2%" ]

  • 方案二:單獨的一個配置文件.browserslistrc文件;

    last 2 versionnot dead> 0.2%

6、認識postCss工具

PostCSS是一個通過JavaScript來轉換樣式的工具,這個工具可以幫助我們進行一些CSS的轉換和適配,比如自動添加瀏覽器前綴、css樣式的重置;

如何使用

安裝工具:postcss、postcss-cli

npm install postcss postcss-cli -D

插件autoprefixer

添加瀏覽器前綴需要安裝autoprefixer

npm install autoprefixer -D

直接使用使用postcss工具,并且制定使用autoprefixer

npx postcss --use autoprefixer -o end.css ./src/css/style.css

postcss-loader

  • 借助構建工具進行css處理

npm install postcss-loader -D {loader:"postcss-loader",options: {postcssOptions: {plugins: [require('autoprefixer')]}}},
  • 單獨的postcss配置

在跟目錄下創建postcss.config.js

module.exports = {plugins: [require('autoprefixer')] }
  • postcss-preset-env

在項目中配置postcss-loader時,我們一般不使用autoprefixer。而是使用另一插件postcss-preset-env

  • postcss-preset-env也是一個postcss的插件;

  • 它可以幫助我們將一些現代的CSS特性,轉成大多數瀏覽器認識的CSS,并且會根據目標瀏覽器或者運行時環境添加所需的polyfill;

  • 也包括會自動幫助我們添加autoprefixer(所以相當于已經內置了autoprefixer);

安裝

npm install postcss-preset-env -D

使用

module.exports = {plugins: [require('postcss-preset-env')] }

三、加載和處理其他資源

1、file-loader

用來處理jpg、png等格式的圖片

  • file-loader的作用就是幫助我們處理import/require()方式引入的一個文件資源,并且會將它放到我們輸出的文件夾中;

安裝

npm install file-loader -D

配置:

{test:/\.(png|jpe?g|svg|gif)$/i,use: {loader: "file-loader"} ?}

1、文件名稱規則

對處理后的文件名稱按照一定的規則進行顯示,一般使用PlaceHolders來完成,webpack給我們提供了大量的PlaceHolders來顯示不同的內容:

介紹幾個最常用的placeholder:

  • [ext]:處理文件的擴展名;

  • [name]:處理文件的名稱;

  • [hash]:文件的內容,使用MD4的散列函數處理,生成的一個128位的hash值(32個十六進制);

  • [contentHash]:在file-loader中和[hash]結果是一致的(在webpack的一些其他地方不一樣,后面會講到);

  • [hash:<length>]:截圖hash的長度,默認32個字符太長了;

  • [path]:文件相對于webpack配置文件的路徑;

2、設置文件名稱和存放路徑

{test:/\.(png|jpe?g|svg|gif)$/i,use: {loader: "file-loader"options: {name: "img/[name].[hash:8].[ext]",outputPath: "img"}} ?}

2、url-loader

將較小的文件轉換為base64的URI

安裝:

npm install url-loader -D

配置:

{test:/\.(png|jpe?g|svg|gif)$/i,use: {loader: "url-loader"options: {name: "img/[name].[hash:8].[ext]",outputPath: "img"}} ?}

打包之后的顯示結果跟file-loader一樣,但是在打包好的dist文件夾中,看不到圖片文件,而是轉換為base64格式存儲。

limit屬性

限制轉換base64格式的圖片大小(比如小于100kb)

{test:/\.(png|jpe?g|svg|gif)$/i,use: {loader: "url-loader"options: {limit:100 * 1024,name: "img/[name].[hash:8].[ext]",outputPath: "img"}} ?}

3、asset module type

1、介紹

  • webpack5之前,加載這些資源我們需要使用一些loader,比如raw-loader 、url-loader、file-loader

  • webpack5之后,我們可以直接使用資源模塊類型(asset module type),來替代上面的這些loader;

資源模塊類型(asset module type),通過添加4 種新的模塊類型,來替換所有這些loader

  • asset/resource發送一個單獨的文件并導出URL。之前通過使用file-loader 實現

  • asset/inline導出一個資源的data URI。之前通過使用url-loader 實現;

  • asset/source導出資源的源代碼。之前通過使用raw-loader 實現;

  • asset在導出一個data URI 和發送一個單獨的文件之間自動選擇。之前通過使用url-loader,并且配置資源體積限制實現;

2、使用

? ? {test: /\.(png|jpe?g|svg|gif)$/i,type: "asset/resource",},
  • 如何自定義文件的輸出路徑和文件名

方式一:修改output,添加assetModuleFilename屬性; ?output: {filename: "bundle.js", // 出口名字path: "出口路徑",assetModuleFilename:"img/[name].[hash:6][ext]"}, 方式二:在Rule中,添加一個generator屬性,并且設置filename; ? ? ? ? ? ? ? {test: /\.(png|jpe?g|svg|gif)$/i,type: "asset/resource",generator: {filename: "img/[name].[hash:6][ext]",},},
  • url-loader中的limit限制圖片大小效果

? ? ? ? ? {test: /\.(png|jpe?g|svg|gif)$/i,type: "asset", ? // 注意generator: {filename: "img/[name].[hash:6][ext]",},parser: {dataUrlCondition: {maxSize: 100 *1024}}},

4、加載字體文件

處理特殊字體或者字體圖標的使用

我們可以選擇使用file-loader來處理,也可以選擇直接使用webpack5的資源模塊類型來處理;

{test: /\.(woff2?|eot|ttf)$/,type: "asset/resource",generator: {filename: "img/[name].[hash:6][ext]",},},

四、認識plugin

  • Loader是用于特定的模塊類型進行轉換;

  • Plugin可以用于執行更加廣泛的任務,比如打包優化、資源管理、環境變量注入等;

1、CleanWebpackPlugin

每次修改了一些配置,重新打包時,都需要手動刪除dist文件夾,CleanWebpackPlugin可以幫助我們完成這個功能。

安裝:

npm install clean-webpack-plugin -D

配置:

const { CleanWebpackPlugin } = require("clean-webpack-plugin");module.exports = {plugins : [new CleanWebpackPlugin()]};

2、HtmlWebpackPlugin

HtmlWebpackPlugin用來對HTML進行打包處理

安裝:

npm install html-webpack-plugin -D

配置:

const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = {plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin({titile: "webpack案例",}),], };

3、自定義HTML模板

如果我們想在自己的模塊中加入一些比較特別的內容:

  • 添加一個noscript標簽,在用戶的JavaScript被關閉時,給予響應的提示;

  • 比如在開發vue或者react項目時,我們需要一個可以掛載后續組件的根標簽<div id="app"></div>;

自定義模板數據填充

上面的代碼中,會有一些類似這樣的語法<%變量%>,這個是EJS模塊填充數據的方式。

在配置HtmlWebpackPlugin時,我們可以添加如下配置:

  • template:指定我們要使用的模塊所在的路徑;

  • title:在進行htmlWebpackPlugin.options.title讀取時,就會讀到該信息;

const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = {plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin({titile: "webpack案例",template: "./public/index.html"}),], };

4、DefinePlugin的介紹

當在我們的模塊中還使用到一個BASE_URL的常量,我們需要設置這個常量,這個時候我們可以使用DefinePlugin插件;

使用:

DefinePlugin允許在編譯時創建配置的全局常量,是一個webpack內置的插件(不需要單獨安裝):

const { DefinePlugin } = require("webpack"); module.exports = {plugins: [new DefinePlugin({BASE_URL:'"./"' ?// 注意需要多一層包裹})], };

5、CopyWebpackPlugin

vue的打包過程中,如果我們將一些文件放到public的目錄下,那么這個目錄會被復制到dist文件夾中。這個復制的功能,我們可以使用CopyWebpackPlugin來完成;

安裝:

npm install copy-webpack-plugin -D

配置:

  • from:設置從哪一個源中開始復制;

  • to:復制到的位置,可以省略,會默認復制到打包的目錄下;

  • globOptions:設置一些額外的選項,其中可以編寫需要忽略的文件:

    • .DS_Store:mac目錄下回自動生成的一個文件;

    • index.html:也不需要復制,因為我們已經通過HtmlWebpackPlugin完成了index.html的生成;

? ?new CopyWebpackPlugin({patterns: [{from:"public",globOptions: {ignore: ['**/.DS_Store','**/index.html']}}]})

五、source-map

source-map是從已轉換的代碼,映射到原始的源文件。使瀏覽器可以重構原始源并在調試器中顯示重建的原始源

使用:

第一步:根據源文件,生成source-map文件,webpack在打包時,可以通過配置生成source-map;

第二步:在轉換后的代碼,最后添加一個注釋,它指向sourcemap;

//# sourceMappingURL=common.bundle.js.map

瀏覽器會根據我們的注釋,查找響應的source-map,并且根據source-map還原我們的代碼,方便進行調試。

分析source-map

  • version:當前使用的版本,也就是最新的第三版;

  • sources:從哪些文件轉換過來的source-map和打包的代碼(最初始的文件);

  • names:轉換前的變量和屬性名稱(因為我目前使用的是development模式,所以不需要保留轉換前的名稱);

  • mappings:source-map用來和源文件映射的信息(比如位置信息等),一串base64VLQ(veriablelengthquantity可變長度值)編碼;

  • file:打包后的文件(瀏覽器加載的文件);

  • sourceContent:轉換前的具體代碼信息(和sources是對應的關系);

  • sourceRoot:所有的sources相對的根目錄;

生成source-map

webpack為我們提供了非常多的選項,目前為止是26個,來處理source-map,選擇不同的值,打包形成的代碼會有性能的差異,可以根據不同情況進行選擇

  • 不會生成source-map的配置項

    • false:不使用source-map,也就是沒有任何和source-map相關的內容。

    • nnone:production模式下的默認值,不生成source-map。

    • eval:development模式下的默認值,不生成source-map

      • 但是它會在eval執行的代碼中,添加//#sourceURL=;

      • 它會被瀏覽器在執行時解析,并且在調試面板中生成對應的一些文件目錄,方便我們調試代碼;

source-map值

生成一個獨立的source-map文件,并且在bundle文件中有一個注釋,指向source-map文件;

bundle文件中有如下的注釋:

//# sourceMappingURL=bundle.js.map

eval-source-map值

eval-source-map:會生成sourcemap,但是source-map是以DataUrl添加到eval函數的后面

inline-source-map值

inline-source-map:會生成sourcemap,但是source-map是以DataUrl添加到bundle文件的后面

cheap-source-map

cheap-source-map:

  • 會生成sourcemap,但是會更加高效一些(cheap低開銷),因為它沒有生成列映射(Column Mapping)

cheap-module-source-map值

會生成sourcemap,類似于cheap-source-map,但是對源自loader的sourcemap處理會更好。

hidden-source-map值

  • 會生成sourcemap,但是不會對source-map文件進行引用;

  • 相當于刪除了打包文件中對sourcemap的引用注釋;

// 被刪除掉的 //# sourceMappingURL=bundle.js.map

nosources-source-map值

會生成sourcemap,但是生成的sourcemap只有錯誤信息的提示,不會生成源代碼文件;

多個值的組合(重要)

事實上,webpack提供給我們的26個值,是可以進行多組合的。

組合的規則如下:

  • inline-|hidden-|eval:三個值時三選一;

  • nosources:可選值;

  • cheap可選值,并且可以跟隨module的值;

    [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map

在開發中,最佳的實踐是什么呢?

  • 開發階段:推薦使用source-map或者cheap-module-source-map

  • 測試階段:推薦使用source-map或者cheap-module-source-map

  • 發布階段:false、缺省值(不寫)

六、Babel深入理解

1、babel是什么東西,用來做什么的

  • Babel是一個工具鏈,主要用于舊瀏覽器或者緩解中將ECMAScript 2015+代碼轉換為向后兼容版本的JavaScript;

  • 語法轉換、源代碼轉換、Polyfill實現目標緩解缺少的功能等;

Babel命令行使用

  • @babel/core:babel的核心代碼,必須安裝;

  • @babel/cli:可以讓我們在命令行使用babel;

npm install @babel/cli @babel/core

使用babel來處理我們的源代碼:

  • src:是源文件的目錄;

  • --out-dir:指定要輸出的文件夾dist;

npx babel src--out-dirdist

插件的使用

比如我們需要轉換箭頭函數,那么我們就可以使用箭頭函數轉換相關的插件:

npm install @babel/plugin-transform-arrow-functions -D npx babel src--out-dirdist--plugins=@babel/plugin-transform-arrow-functions

查看轉換后的結果,我們會發現const 并沒有轉成var,這是因為plugin-transform-arrow-functions,并沒有提供這樣的功能,我們需要使用plugin-transform-block-scoping 來完成這樣的功能。

npm install @babel/plugin-transform-block-scoping -D npx babel src--out-dirdist--plugins=@babel/plugin-transform-block-scoping @babel/plugin-transform-arrow-functions

Babel的預設preset

如果要轉換的內容過多,一個個設置是比較麻煩的,我們可以使用預設(preset)

安裝 :

npm install @babel/preset-env -D

執行:

npx babel src--out-dirdist--presets=@babel/preset-env

2、Babel的底層原理

工作流程:

  • 解析階段(Parsing)

  • 轉換階段(Transformation)

  • 生成階段(CodeGeneration)

流程圖:

3、babel-loader

安裝:

npm install babel-loader @babel/core

使用:

module.exports = {module: {rules: [{test:/\.js$/,use: {loader: "babel-loader"}}]} }

指定使用的插件

我們必須指定使用的插件才會生效

module: {rules: [{test:/\.js$/,use: {loader: "babel-loader",options: {plugins: ["@babel/plugin-transform-block-scoping","@babel/plugin-transform-arrow-functions"]}}}]}

babel-preset

如果我們一個個去安裝使用插件,那么需要手動來管理大量的babel插件,我們可以直接給webpack提供一個preset,webpack會根據我們的預設來加載對應的插件列表,并且將其傳遞給babel。

常見的預設:

  • env

  • react

  • TypeScript

安裝preset-env:

npm install @babel/preset-env {test:/\.js$/,use: {loader: "babel-loader",options: {plugins: ["@babel/plugin-transform-block-scoping","@babel/plugin-transform-arrow-functions"]}} }

Babel的Stage-X設置

在babel7之前(比如babel6中),我們會經常看到這種設置方式:

  • 它表達的含義是使用對應的babel-preset-stage-x預設;

  • 從babel7開始,已經不建議使用了,建議使用preset-env來設置;

4、Babel的配置文件

我們可以將babel的配置信息放到一個獨立的文件中,babel給我們提供了兩種配置文件的編寫:

  • babel.config.json(或者.js,.cjs,.mjs)文件;

  • .babelrc.json(或者.babelrc,.js,.cjs,.mjs)文件;

區別:

  • .babelrc.json:早期使用較多的配置方式,但是對于配置Monorepos項目是比較麻煩的;

  • babel.config.json(babel7):可以直接作用于Monorepos項目的子包,更加推薦;

5、認識polyfill

更像是應該填充物(墊片),一個補丁,可以幫助我們更好的使用JavaScript;

使用場景:

比如我們使用了一些語法特性(例如:Promise,Generator,Symbol等以及實例方法例如Array.prototype.includes等),但是某些瀏覽器壓根不認識這些特性,必然會報錯,我們可以使用polyfill來填充或者說打一個補丁,那么就會包含該特性了;

可以通過單獨引入core-js和regenerator-runtime來完成polyfill的使用:

npm install core-js regenerator-runtime --save {test:/\.m?js$/,exclude:/node_modules/,use:"babel-loader" }

配置babel.config.js

我們需要在babel.config.js文件中進行配置,給preset-env配置一些屬性:

  • useBuiltIns:設置以什么樣的方式來使用polyfill;

  • corejs:設置corejs的版本

    • 另外corejs可以設置是否對提議階段的特性進行支持;

    • 設置proposals屬性為true即可;

useBuiltIns屬性設置

  • useBuiltIns屬性有三個常見的值

    第一個值:false

    • 打包后的文件不使用polyfill來進行適配;

    • 并且這個時候是不需要設置corejs屬性的;

    第二個值:usage

    • 會根據源代碼中出現的語言特性,自動檢測所需要的polyfill;

    • 這樣可以確保最終包里的polyfill數量的最小化,打包的包相對會小一些;

    • 可以設置corejs屬性來確定使用的corejs的版本;

    第三個值:entry

    • 如果我們依賴的某一個庫本身使用了某些polyfill的特性,但是因為我們使用的是usage,所以之后用戶瀏覽器可能會報錯,果你擔心出現這種情況,可以使用entry;

    • 需要在入口文件中添加`import 'core-js/stable'; import 'regenerator-runtime/runtime';

    • 這樣做會根據browserslist目標導入所有的polyfill,但是對應的包也會變大;

6、認識Plugin-transform-runtime(了解)

在前面我們使用的polyfill,默認情況是添加的所有特性都是全局的,如果我們正在編寫一個工具庫,這個工具庫需要使用polyfill,別人在使用我們工具時,工具庫通過polyfill添加的特性,可能會污染它們的代碼,所以,當編寫工具時,babel更推薦我們使用一個插件:@babel/plugin-transform-runtime來完成polyfill的功能;

7、React的jsx支持

安裝:

npm install @babel/preset-react -D

使用:

presets: [["@babel/preset-env", {useBuiltIns:"usage",corejs: 3.8}],["@babel/preset-react"] ]

8、TypeScript的編譯

TypeScript通過compiler來轉換成JavaScript

安裝:

npm install typescript -D

TypeScript的編譯配置信息我們通常會編寫一個tsconfig.json文件:

tsc --init

之后我們可以運行npxtsc來編譯自己的ts代碼:

npx tsc

1、使用ts-loader編譯TS

安裝:

npm install ts-loader -D

配置:

{test:'/\.ts$/',exclude: /node_modules/,use: ["ts-loader"] }

2、使用babel-loader編譯TS

Babel是有對TypeScript進行支持

  • 我們可以使用插件:@babel/tranform-typescript;

  • 但是更推薦直接使用preset:@babel/preset-typescript;

安裝:

npm install @babel/preset-typescript -D

配置:

{test:'/\.ts$/',exclude: /node_modules/,use: ["babel-loader"] }

七、大數據中關于代碼格式校驗(Eslint和prettierrc )

大數據中關于eslint的配置

/** @Description: eslint 配置* @ 規則依賴于 @umijs/fabric,在此基礎上,可自行添加自己的規則進行配置* @Author: 賈永昌* @Date: 2022-05-01 13:55:14* @LastEditTime: 2022-05-02 17:35:45*/ module.exports = {extends: [require.resolve('@umijs/fabric/dist/eslint')], ?// in antd-design-proglobals: {ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: true,page: true,}, ?rules: {// 強制語句有分號結尾semi: [2, 'always'],// ? 操作符前后必須有空格 bad: 1||2 good: 1 || 2'space-infix-ops': 2,// ? 對象字面量中冒號前面禁止有空格,后面必須有空格 bad: {a :'a'} good:{a: 'a'}'key-spacing': 2,// ? 花括號首尾必須有空格'object-curly-spacing': [2, 'always'],// ? 語句塊(if、function、class、try...catch等的大括號) 的前面必須要有空格'space-before-blocks': 2,// ? 箭頭函數的箭頭與后面的{}之間需要空格'arrow-spacing': 2,// ? 禁止多余的空格'no-multi-spaces': 2,// ? 禁止代碼行結束后面有多余空格'no-trailing-spaces': 2,// ? 禁止多余空行'no-multiple-empty-lines': ['error', { max: 1, maxBOF: 1, maxEOF: 1 }],// ? 允許標識符中使用懸空下劃線(標識符的開頭或末尾的下劃線)'no-underscore-dangle': 0,// ? 允許邏輯短路、三元運算符等表達式求值'no-unused-expressions': 0,// ? 禁止使用嵌套的三元表達式'no-nested-ternary': 2,// ? 禁止對函數參數再賦值(保證react函數式編程純函數的概念)'no-param-reassign': 2,// ? 禁止使用 var 定義變量'no-var': 2,// ? 禁止修改const聲明的變量'no-const-assign': 2,// ? 函數調用時 函數名與()之間不能有空格'no-spaced-func': 2, ?// ? jsx 屬性中強制使用雙引號'jsx-quotes': [2, 'prefer-double'],// ? 禁止 jsx 屬性對象的引用括號里 兩邊加空格'react/jsx-curly-spacing': [2, 'never'],// ? JSX 中前標簽傳有屬性換行展示的話,其后面的 > 也需換行對齊展示'react/jsx-closing-bracket-location': 2,// ? 校驗 jsx 中所有換行屬性值縮進'react/jsx-indent-props': [2, 2],// ? jsx 中傳入屬性值是Boolean值且為true時,省略傳入'react/jsx-boolean-value': 2,// ? 在 JSX 屬性中禁止等號前后存在空格'react/jsx-equals-spacing': 2, ?// ? 關閉此規則,允許 useEffect 的依賴為空數組'react-hooks/exhaustive-deps': 0, ?// ? 未使用的變量警告提醒'@typescript-eslint/no-unused-vars': ['warn'],// ? 禁用使用在前,保證 useEffct 使用在最前面,這時候里面如果使用了外部的函數就會報這錯'@typescript-eslint/no-use-before-define': 0,// ? 允許空的 ts 接口定義 eg: interface IProps {}'@typescript-eslint/no-empty-interface': 0,}, }; 大數據中 .prettierrc 配置 {"printWidth": 80,"tabWidth": 2,"singleQuote": true,"useTabs": false,"semi": true,"jsxSingleQuote": false,"trailingComma": "all","bracketSpacing": true,"jsxBracketSameLine": false,"arrowParens": "always","requirePragma": false,"insertPragma": false,"proseWrap": "preserve", "htmlWhitespaceSensitivity": "css","overrides": [{"files": ".prettierrc","options": { "parser": "json" }}] }

八、DevServer

為什么需要搭建本地服務器?

我們希望可以做到,當文件發生變化時,可以自動完成編譯和展示

  • webpack watch mode

  • webpack-dev-server

  • webpack-dev-middleware

1、Webpack watch(基本不用)

webpack給我們提供了watch模式:

  • 在該模式下,webpack依賴圖中的所有文件,只要有一個發生了更新,那么代碼將被重新編譯(損耗性能)

開啟watch的兩種方式

  • 方式一:在導出的配置中,添加watch: true;

  • 方式二:在啟動webpack的命令中,添加--watch的標識;

"scripts" : {"watch":"webpack --watch" }

2、webpack-dev-server(必會,常用)

除了可以監聽到文件的變化,還可以具備實時重新加載的功能

安裝:

npm install --save-dev webpack-dev-server

配置:

"scripts" : {"watch":"webpack --watch""serve":"webpack serve --config wk.config.js" }

webpack-dev-server 在編譯之后不會寫入到任何輸出文件。而是將bundle 文件保留在內存中:

  • 事實上webpack-dev-server使用了一個庫叫memfs(memory-fswebpack自己寫的)

3、webpack-dev-middleware(基本不用)

如果我們想要有更好的自由度,可以使用webpack-dev-middleware;

定義:

webpack-dev-middleware 是一個封裝器(wrapper),它可以把webpack處理過的文件發送到一個server,webpack-dev-server 在內部使用了它,然而它也可以作為一個單獨的package 來使用,以便根據需求進行更多自定義設置;

4、output的publicPath(outPut中的配置)

output中還有一個publicPath屬性,該屬性是指定index.html文件打包引用的一個基本路徑

  • 它的默認值是一個空字符串,所以我們打包后引入js文件時,路徑是bundle.js;

  • 在開發中,我們也將其設置為/,路徑是/bundle.js,那么瀏覽器會根據所在的域名+路徑去請求對應的資源;

  • 如果我們希望在本地直接打開html文件來運行,會將其設置為./,路徑時./bundle.js,可以根據相對路徑去查找資源;

    module.exports = {entry: " 指定入口路徑",output: {filename:"bundle.js", // 出口名字path: '出口路徑'publicPath:'./'} }

5、devServer的publicPath

devServer中也有一個publicPath的屬性,該屬性是指定本地服務所在的文件夾

  • 它的默認值是/,也就是我們直接訪問端口即可訪問其中的資源http://localhost:8080

  • 如果我們將其設置為了/abc,那么我們需要通過http://localhost:8080/abc才能訪問到對應的打包后的資源

  • 并且這個時候,我們其中的bundle.js通過http://localhost:8080/bundle.js也是無法訪問的:

    • 所以必須將output.publicPath也設置為/abc;

    • 官方其實有提到,建議devServer.publicPath與output.publicPath相同

6、devServer的contentBase(不常用)

主要作用是如果我們打包后的資源,又依賴于其他的一些資源,那么就需要指定從哪里來查找這個內容

  • 比如在index.html中,我們需要依賴一個abc.js文件,這個文件我們存放在public文件中

  • 在index.html中,我們應該如何去引入這個文件

    • 比如代碼是這樣的:<script src="./public/abc.js"></script>

    • 但是這樣打包后瀏覽器是無法通過相對路徑去找到這個文件夾的;

    • 所以代碼是這樣的:<script src="/abc.js"></script>;

    • 但是我們如何讓它去查找到這個文件的存在呢?設置contentBase即可

devserver: {contentBase: path.resolve(__dirname,"why"),watchContentBase:true //監聽contentBase發生變化后重新編譯 }

7、hotOnly、hos、port、open、compress配置

  • hotOnly是當代碼編譯失敗時,是否刷新整個頁面

  • port設置監聽的端口,默認情況下是8080

  • host設置主機地址

  • open是否打開瀏覽器

  • compress是否為靜態文件開啟gzip compression

devserver: {contentBase: path.resolve(__dirname,"why"),watchContentBase:true, //監聽contentBase發生變化后重新編譯hotOnly:true,host: 0.0.0.0,port: 3000,open: true,compress:true }

8、Proxy代理(解決跨域問題)注意:在開發環境中使用

我們可以將請求先發送到一個代理服務器,代理服務器和API服務器沒有跨域的問題,就可以解決我們的跨域問題了

配置:

  • target:表示的是代理到的目標地址,比如/api-hy/moment會被代理到http://localhost:8888/api-hy/moment;

  • pathRewrite:默認情況下,我們的/api-hy也會被寫入到URL中,如果希望刪除,可以使用pathRewrite;

  • secure:默認情況下不接收轉發到https的服務器上,如果希望支持,可以設置為false;

  • changeOrigin:它表示是否更新代理后請求的headers中host地址;

devserver: {'/api': {// 標識需要進行轉換的請求的urltarget: 'http://172.16.188.188:8000', // 服務端域名changeOrigin: true, // 允許域名進行轉換pathRewrite: {// 將請求url里的ci去掉'^/api': '',},logLevel: 'debug',secure: false, // 將該屬性設置為false,將允許在https上運行或者運行在證書無效的后端服務器},},

9、historyApiFallback

  • historyApiFallback是開發中一個非常常見的屬性,它主要的作用是解決SPA頁面在路由跳轉之后,進行頁面刷新時,返回404的錯誤。

  • boolean值:默認是false

    • 如果設置為true,那么在刷新時,返回404錯誤時,會自動返回index.html的內容;

  • object類型的值,可以配置rewrites屬性:

    • 可以配置from來匹配路徑,決定要跳轉到哪一個頁面;

?devserver: {'/api': {// 標識需要進行轉換的請求的urltarget: 'http://172.16.188.188:8000', // 服務端域名changeOrigin: true, // 允許域名進行轉換pathRewrite: {// 將請求url里的ci去掉'^/api': '',},logLevel: 'debug',secure: false, // 將該屬性設置為false,將允許在https上運行或者運行在證書無效的后端服務器},historyApiFallback: {rewrites:[{from: /abc/, to:"/index.html"}]}},

九、模塊熱替換(HMR)

什么是HMR

  • HMR的全稱是Hot Module Replacement,翻譯為模塊熱替換;

  • 模塊熱替換是指在應用程序運行過程中,替換、添加、刪除模塊,而無需重新刷新整個頁面;

如何使用HMR

  • 默認情況下,webpack-dev-server已經支持HMR,我們只需要開啟即可;

  • 在不開啟HMR的情況下,當我們修改了源代碼之后,整個頁面會自動刷新,使用的是live reloading;

1、開啟HMR

// 在webpack.config.js 中添加以下配置 devserver: {hot:true }

同時還需要指定發生更新的模塊

if(module.hot) {module.hot.accept("./*文件路徑",() => {console.log()}) }

2、框架中的HMR

項目中已經有非常成熟的方案,別操心了

  • vue開發中,我們使用vue-loader,此loader支持vue組件的HMR,提供開箱即用的體驗

  • react開發中,有React HotLoader,實時調整react組件(目前React官方已經棄用了,改成使用reactrefresh);

3、HMR的原理

HMR的原理是什么

  • webpack-dev-server會創建兩個服務:提供靜態資源的服務(express)和Socket服務(net.Socket)

  • express server負責直接提供靜態資源的服務(打包后的資源直接被瀏覽器請求和解析);

HMR Socket Server,是一個socket的長連接:(想想webSocket,需要及時通信)

  • 長連接有一個最好的好處是建立連接后雙方可以通信(服務器可以直接發送文件到客戶端)

  • 當服務器監聽到對應的模塊發生變化時,會生成兩個文件.json(manifest文件)和.js文件(update chunk);

  • 通過長連接,可以直接將這兩個文件主動發送給客戶端(瀏覽器)

  • 瀏覽器拿到兩個新的文件后,通過HMR runtime機制,加載這兩個文件,并且針對修改的模塊進行更新;

十、resolve模塊解析

resolve用于設置模塊如何被解析:

  • resolve可以幫助webpack從每個require/import 語句中,找到需要引入到合適的模塊代碼;

  • webpack 使用enhanced-resolve來解析文件路徑;

webpack能解析三種文件路徑:

  • 絕對路徑

  • 相對路徑

  • 模塊路徑:在resolve.modules中指定的所有目錄檢索模塊,默認值是['node_modules'],所以默認會從node_modules中查找文件;

1、extensions和alias配置

extensions是解析到文件時自動添加擴展名:

  • 默認值是['.wasm','.mjs','.js','.json'];

    配置:

    module.exports = {entry: " 指定入口路徑",output: {filename:"bundle.js", // 出口名字path: '出口路徑'},resolve:{extensions:['.wasm','.mjs','.js','.json','.jsx','.ts'],} }

我們可以使用alias給某些常見的路徑起一個別名;

resolve:{extensions:['.wasm','.mjs','.js','.json','.jsx','.ts'],alias: {"@":resolveApp('./src'),pages:resolveApp('./src/pages')}}

十一、環境分離和代碼分離

1、入口文件解析

context的作用是用于解析入口(entry point)和加載器(loader)

默認是webpack的啟動目錄

module.exports = {context:path.resolve(__dirname,'./')entry:"../src/index.js" }

2、配置文件的分離

  • 將原來的webpack.config.js劃分為webpack.comm.conf.js(通用配置)、webpack.dev.conf.js(開發環境)、webpack.prod.conf.js(生產環境)三部分

  • 利用mode配置項,區分開發環境和生產環境。用利用merge將用到的環境配置和通用配置合并

3、認識代碼分離

代碼分離(CodeSplitting)主要的目的是將代碼分離到不同的bundle中,之后我們可以按需加載,或者并行加載這些文件;

Webpack中常用的代碼分離有三種

  • 入口起點:使用entry配置手動分離代碼;

  • 防止重復:使用EntryDependencies或者SplitChunksPlugin去重和分離代碼;

  • 動態導入:通過模塊的內聯函數調用來分離代碼;

1、多入口起點

entry: {index:"./src/index.js",main:"./src/main.js" } output: {filename:"[name].bundle.js",path:resolveApp("./build") }

2、EntryDependencies(入口依賴)

假如我們的index.js和main.js都依賴兩個庫:lodash、dayjs

  • 如果我們單純的進行入口分離,那么打包后的兩個bunlde都有會有一份lodash和dayjs;

    entry: {index: {import:"./src/index.js",dependOn:"shared"},main:{import:"./src/main.js",dependOn:"shared"},shared:['lodash','axios'] } output: {filename:"[name].bundle.js",path:resolveApp("./build"),publicPath: "" }

3、SplitChunks

另外一種分包的模式是splitChunk,它是使用SplitChunksPlugin來實現的:

Webpack提供了SplitChunksPlugin默認的配置,我們也可以手動來修改它的配置:

  • 比如默認配置中,chunks僅僅針對于異步(async)請求,我們可以設置為initial或者all;

optimization: {splitChunks: {chunks:'all'} }

4、SplitChunks自定義配置

SplitChunks: {chunks:'all',// 拆分包的大小,至少為minsize// 如果一個包拆分出來不到minsize,那么將不會被拆分minsize:100,// 將大于maxMize的包,拆分成不小于minSize 的包maxsize:1000,// 至少包被引入的次數minChunks:2,// 最大異步請求數量maxAsyncRequests:30,// 最大的初始化請求數量cacheGroups: {venders: {test:/[\\/]node_modules[\\/]/,priority: -10,filename: "[id]_[hash:6]_vendor.js"},foo: {test:/foo/,priority: -20,filename: "foo_[id]_[name]_.js"}} }

配置解析:

  • Chunks

    • 默認值是async

    • 另一個值是initial,表示對通過的代碼進行處理

    • all表示對同步和異步代碼都進行處理

  • minSize

    • 拆分包的大小, 至少為minSize;

    • 如果一個包拆分出來達不到minSize,那么這個包就不會拆分;

  • maxSize

    • 將大于maxSize的包,拆分為不小于minSize的包;

  • minChunks

    • 至少被引入的次數,默認是1;

    • 如果我們寫一個2,但是引入了一次,那么不會被單獨拆分;

  • name:設置拆包的名稱

    • 可以設置一個名稱,也可以設置為false;

    • 設置為false后,需要在cacheGroups中設置名稱;

  • cacheGroups

    • 用于對拆分的包就行分組,比如一個lodash在拆分之后,并不會立即打包,而是會等到有沒有其他符合規則的包一起來打包;

    • test屬性:匹配符合規則的包;

    • name屬性:拆分包的name屬性;

    • filename屬性:拆分包的名稱,可以自己使用placeholder屬性;

5、動態導入(dynamic import)

使用ECMAScript中的import()語法來完成,也是目前推薦的方式;

注意:

  • 在webpack中,通過動態導入獲取到一個對象;

  • 真正導出的內容,在改對象的default屬性中,所以我們需要做一個簡單的解構;

動態導入的文件命名

它的命名我們通常會在output中,通過chunkFilename屬性來命名

output: {filename: "[name].bundle.js",path:resolveApp("./build"),chunkFilename: "chunk_[id]_[name].js" }

默認情況下我們獲取到的[name]是和id的名稱保持一致的

  • 我們希望修改name的值,可以通過magic comments(魔法注釋)的方式

import(/* webpackChunkName:"bar"*/ "./bar").then(({default:bar}) => {bar() })

6、optimization.chunkIds配置

optimization.chunkIds配置用于告知webpack模塊的id采用什么算法生成。

  • natural:按照數字的順序使用id;

  • named:development下的默認值,一個可讀的名稱的id;

  • deterministic:確定性的,在不同的編譯中不變的短數字id

最佳實踐:

  • 開發過程中,我們推薦使用named;

  • 打包過程中,我們推薦使用deterministic;

7、optimization. runtimeChunk配置

配置runtime相關的代碼是否抽取到一個單獨的chunk中:

  • 抽離出來后,有利于瀏覽器緩存的策略:

  • 設置的值

    • true/multiple:針對每個入口打包一個runtime文件;

    • single:打包一個runtime文件;

    • 對象:name屬性決定runtimeChunk的名稱;

    optimization:{chunkIds:"deterministic",runtimeChunk: {name:"runtime"} }

8、Prefetch和Preload

  • webpack v4.6.0+增加了對預獲取和預加載的支持。

    • prefetch(預獲取):將來某些導航下可能需要的資源

    • preload(預加載):當前導航下可能需要資源

    import(/* webpackChunkName:"bar"*/ /* webpackpeload:true */"./bar").then(({default:bar}) => {bar() })
  • 區別

    • preload chunk 會在父chunk 加載時,以并行方式開始加載。prefetch chunk 會在父chunk 加載結束后開始加載。

    • preload chunk 具有中等優先級,并立即下載。prefetch chunk 在瀏覽器閑置時下載。

    • preload chunk 會在父chunk 中立即請求,用于當下時刻。prefetch chunk 會用于未來的某個時刻。

9、CDN

CDN稱之為內容分發網絡(ContentDeliveryNetwork或ContentDistributionNetwork,縮寫:CDN)

開發中的應用方式:

  • 方式一:打包的所有靜態資源,放到CDN服務器,用戶所有資源都是通過CDN服務器加載的;

  • 方式二:一些第三方資源放到CDN服務器上;

方式一花錢,直接說方式二

一些比較出名的開源框架都會將打包后的源碼放到一些比較出名的、免費的CDN服務器上

使用方法:

  • 第一步,我們可以通過webpack配置,來排除一些庫的打包:

    externals: {lodash: "_",dayjs: "dayjs" }
  • 第二步,在html模塊中,加入CDN服務器地址:

    <script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.core.js"></script>

10、認識shimming

  • shimming是一個概念,是某一類功能的統稱:

    • 比如我們現在依賴一個第三方的庫,這個第三方的庫本身依賴lodash,但是默認沒有對lodash進行導入(認為全局存在lodash),那么我們就可以通過ProvidePlugin來實現shimming的效果;

  • 注意:webpack并不推薦隨意的使用shimming

    • Webpack背后的整個理念是使前端開發更加模塊化;

    • 也就是說,需要編寫具有封閉性的、不存在隱含依賴(比如全局變量)的彼此隔離的模塊;

11、MiniCssExtractPlugin

MiniCssExtractPlugin可以幫助我們將css提取到一個獨立的css文件中,該插件需要在webpack4+才可以使用。

安裝:

npm install mini-css-extract-plugin -D

配置:

plugins: [new MiniCssExtractPlugin({filename:"css/[name].[contenthash:8].css",chunkfilename: "css/[name].[contenthash:8].css"}) ], module:{rules: [{test:/\.css$/i,use:[MiniCssExtractPlugin.loader,'css-loader']}] }

12、Hash、ContentHash、ChunkHash

  • hash值的生成和整個項目有關系:

    • 比如我們現在有兩個入口index.js和main.js;

    • 它們分別會輸出到不同的bundle文件中,并且在文件名稱中我們有使用hash;

    • 這個時候,如果修改了index.js文件中的內容,那么hash會發生變化;

    • 那就意味著兩個文件的名稱都會發生變化;

  • chunkhash可以有效的解決上面的問題,它會根據不同的入口進行借來解析來生成hash值:

比如我們修改了index.js,那么main.js的chunkhash是不會發生改變的;

  • contenthash表示生成的文件hash名稱,只和內容有關系:

    • 比如我們的index.js,引入了一個style.css,style.css有被抽取到一個獨立的css文件中;

    • 這個css文件在命名時,如果我們使用的是chunkhash;

    • 那么當index.js文件的內容發生變化時,css文件的命名也會發生變化;

    • 這個時候我們可以使用contenthash;

十二、DLL_Tree Shaking

認識DLL庫(了解一下)

  • DLL全程是動態鏈接庫(Dynamic Link Library),是為軟件在Windows中實現共享函數庫的一種實現方式;

  • webpack中也有內置DLL的功能,它指的是我們可以將可以共享,并且不經常改變的代碼,抽取成一個共享的庫;

Terser介紹和安裝(一般使用默認配置)

  • Terser是一個JavaScript的解釋(Parser)、Mangler(絞肉機)/Compressor(壓縮機)的工具集;

    • 早期我們會使用uglify-js來壓縮、丑化我們的JavaScript代碼,但是目前已經不再維護,并且不支持ES6+的語法;

  • Terser可以幫助我們壓縮、丑化我們的代碼,讓我們的bundle變得更小。

安裝:

npm install terser -g // 可以進行局部安裝,也可以全局安裝

命令行使用

terser [input files] [options]

常見的配置項:

Compress option

  • arrows:class或者object中的函數,轉換成箭頭函數;

  • arguments:將函數中使用arguments[index]轉成對應的形參名稱;

  • dead_code:移除不可達的代碼(tree shaking);

  • 等等其他屬性,詳情看官方文檔

Mangle option

  • toplevel:默認值是false,頂層作用域中的變量名稱,進行丑化(轉換)

  • keep_classnames:默認值是false,是否保持依賴的類名稱;

  • keep_fnames:默認值是false,是否保持原來的函數名稱;

Terser在webpack中配置使用

  • (注意)真實開發中,我們不需要手動的通過terser來處理我們的代碼,我們可以直接通過webpack來處理:

    • 在webpack中有一個minimizer屬性,在production模式下,默認就是使用TerserPlugin來處理我們的代碼的;

    • 如果我們對默認的配置不滿意,也可以自己來創建TerserPlugin的實例,并且覆蓋相關的配置;(基本不會手動配置)

module.exports = {optimization: {minimize:true,minimizer: [new TerserPlugin({parallel:true, // 使用多進程并發運行提高構建的速度,默認值是true,extractComments:false, // 默認值為true,表示會將注釋抽取到一個單獨的文件中terserOptions: { // 設置我們的terser相關的配置compress: { // 設置壓縮相關的選項;arguments:true,dead_code:true},mangle:true, // 設置丑化相關的選項,可以直接設置為true;toplevel:true, // 底層變量是否進行轉換keep_classnames:false,// 保留類的名稱keep_fnames:false// 保留函數的名稱;}})]} }

CSS的壓縮

安裝:

npm install css-minimizer-webpack-plugin -D

在optimization.minimizer中配置:

minimizer: [new CssMinimizerplugin({parallel: true}) ]

提升作用域 Scope Hoisting

  • Scope Hoisting從webpack3開始增加的一個新功能,功能是對作用域進行提升,并且讓webpack打包后的代碼更小、運行更快;

  • 默認情況下webpack打包會有很多的函數作用域,Scope Hoisting可以將函數合并到一個模塊中來運行

  • 使用:

    • 在production模式下,默認這個模塊就會啟用;

    • 在development模式下,我們需要自己來打開該模塊;

    new webpack.optimize.ModuleConcatenationPlugin()

Tree Shaking

定義:最早的想法起源于LISP,用于消除未調用的代碼(純函數無副作用,可以放心的消除,這也是為什么要求我們在進行函數式編程時,盡量使用純函數的原因之一)

webpack實現TreeShaking

兩種方法:

  • 在optimization中配置usedExports為true,來幫助Terser進行優化;

  • 在package.json中配置sideEffects,直接對模塊進行優化;

usedExports

在usedExports設置為true時,會有一段注釋:unused harmony export mul,這段注釋告知Terser在優化時,可以刪除掉這段代碼

注意:

  • 配置該屬性時,需要將mode設置為development模式

  • usedExports實現tree Shaking是結合terse來完成的

sideEffects

sideEffects用于告知webpack compiler哪些模塊時有副作用的(副作用的意思是這里面的代碼有執行一些特殊的任務,不能僅僅通過export來判斷這段代碼的意義;)

  • 在package.json中設置sideEffects的值:

    • false:告知webpack可以安全的刪除未用到的exports;

    • 如果有一些希望保留,可以設置數組

"sideEffects": ["./src/util/format.js","*.css" ]

CSS實現TreeShaking

我們可以使用一個庫來完成CSS的Tree Shaking:PurgeCSS,幫助我們刪除未使用的CSS的工具

安裝:

npm install purgecss-webpack-plugin -D

配置:

  • paths:表示要檢測哪些目錄下的內容需要被分析,這里我們可以使用glob;

  • 默認情況下,Purgecss會將我們的html標簽的樣式移除掉,如果我們希望保留,可以添加一個safelist的屬性;

  • purgecss也可以對less文件進行處理(所以它是對打包后的css進行tree shaking操作)

new ?PurgecssPlugin({paths:glob.sync(`${resolveApp(./src)}/**/*`,{nodir:true}),safelist: function() {return {standard:['html']}} })

HTTP壓縮

定義:HTTP壓縮是一種內置在服務器和客戶端之間的,以改進傳輸速度和帶寬利用率的方式

流程:

第一步:HTTP數據在服務器發送前就已經被壓縮了

第二步:兼容的瀏覽器在向服務器發送請求時,會告知服務器自己支持哪些壓縮格式

第三步:服務器在瀏覽器支持的壓縮格式下,直接返回對應的壓縮后的文件,并且在響應頭中告知瀏覽器;

目前的壓縮格式

  • compress–UNIX的“compress”程序的方法(歷史性原因,不推薦大多數應用使用,應該使用gzip或deflate);

  • deflate–基于deflate算法(定義于RFC1951)的壓縮,使用zlib數據格式封裝;

  • gzip–GNUzip格式(定義于RFC1952),是目前使用比較廣泛的壓縮算法;

  • br–一種新的開源壓縮算法,專為HTTP內容的編碼而設計;

Webpack對文件壓縮

webpack中相當于是實現了HTTP壓縮的第一步操作,我們可以使用CompressionPlugin。

安裝:

npm install compression-webpack-plugin -D

配置:

new CompressionPlugin({test:/\.(css|js)$/, ?// 匹配哪些文件需要壓縮threshold:500, // 設置文件多大開始壓縮minRatio: 0.7, // 至少采用的壓縮比例algorithm: "gzip" // 采用的壓縮算法 })

HTML文件中代碼的壓縮

我們之前使用了HtmlWebpackPlugin插件來生成HTML的模板,事實上它還有一些其他的配置:

  • inject:設置打包的資源插入的位置

    • true、false、body、head

  • cache:設置為true,只有當文件改變時,才會生成新的文件(默認值也是true)

  • minify:默認會使用一個插件html-minifier-terser

InlineChunkHtmlPlugin

可以輔助將一些chunk出來的模塊,內聯到html中

安裝

npm install react-dev-utils -D

在production的plugins中進行配置:

module.exports = {plugin:[new InlineChunkHtmlPlugin(HtmlWebpackPlugin,[/runtime.+\.js/])] }

十三、webpack打包分析

分析一:打包的時間分析

speed-measure-webpack-plugin 可以幫助我們看到每一個loader、每一個plugin的打包時間

安裝:

npm install speed-measure-webpack-plugin -D

配置:

const smp = new SpeedMeasurePlugin(); cpnst webpackConfig = smp.wrap({plugins: [new MyPlugin(),new MyOtherPlugin()] })

分析二:打包后文件分析

使用webpack-bundle-analyzer工具

安裝:

npm install webpack-bundle-analyzer -D

配置

module.exports = {plugins: [new BundleAnalyzerPlugin()] }

Compiler和Compilation的區別(面試題)

  • Compiler中webpack構建的之初就會創建的一個對象, 并且在webpack的整個生命周期都會存在(before -run -beforeCompiler-compile -make -finishMake-afterCompiler-done)

    • 只要是做webpack的編譯, 都會先創建一個Compiler

  • Compilation是到準備編譯模塊(比如main.js), 才會創建Compilation對象

    • watch -> 源代碼發生改變就需要重新編譯模塊

    • 主要是存在于compile -make 階段主要使用的對象

  • Compiler可以繼續使用(如果我修改webpack的配置, 那么需要重新執行run run build)

  • Compilation需要創建一個新的Compilation對象

總結

以上是生活随笔為你收集整理的webpack基础学习,各个loader和plugin的具体配置的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

国产精品毛片一区二区在线看 | 婷婷婷国产在线视频 | 国产精品亚洲视频 | 亚洲精品综合一区二区 | 久久久久日本精品一区二区三区 | av成人免费在线观看 | 亚洲一区二区三区毛片 | 97国产在线观看 | av免费看在线 | 一本一本久久a久久精品综合小说 | 国产精品视频免费 | 九九久久免费视频 | 黄色网www| 亚洲国内精品视频 | 免费试看一区 | 97国产情侣爱久久免费观看 | 久久五月天色综合 | 日韩高清观看 | 亚洲精品视频在线观看视频 | 色av男人的天堂免费在线 | 成人一级电影在线观看 | 涩涩色亚洲一区 | 国产91在线 | 美洲 | 黄色成人av在线 | 国产精品麻豆91 | 视频直播国产精品 | 日韩av在线小说 | 成人教育av | 国产中文字幕在线播放 | 久久avav | 97av在线视频免费播放 | 亚洲成人高清在线 | 亚洲电影自拍 | 欧美一区二区三区在线观看 | 亚洲免费国产 | 日韩精品在线观看av | 狠狠色噜噜狠狠狠狠 | 99热在线国产精品 | www.亚洲精品 | 97精品国产aⅴ | 国产精品一区二区果冻传媒 | 涩五月婷婷 | 日韩最新中文字幕 | 91精品国产乱码在线观看 | 国产在线91精品 | 亚洲欧美成aⅴ人在线观看 四虎在线观看 | 国产99久久久精品视频 | 欧美 激情在线 | 在线观看成人国产 | 日本韩国中文字幕 | 久久久久久久久久久精 | 友田真希av | 日韩中文字幕第一页 | 96精品高清视频在线观看软件特色 | 亚洲免费成人 | 色偷偷88欧美精品久久久 | 亚洲一级特黄 | 黄色特级片 | 日韩理论片在线 | 在线观看蜜桃视频 | 视频一区二区三区视频 | 欧美激情第八页 | 久久久久一区二区三区四区 | 91网站在线视频 | 日韩久久在线 | 毛片网站在线看 | 麻豆传媒视频在线播放 | 麻豆成人精品视频 | 国产精品99久久久久的智能播放 | 一级黄色电影网站 | 亚洲精品一区二区18漫画 | 最新在线你懂的 | 国产日韩欧美在线播放 | 免费亚洲成人 | 亚洲最新av在线网址 | 日本成人中文字幕在线观看 | 91精品国产乱码 | 日韩一区二区免费视频 | 免费av看片 | 色五月成人 | 亚洲一区日韩精品 | 欧美与欧洲交xxxx免费观看 | 国内精品视频一区二区三区八戒 | 热精品| 嫩小bbbb摸bbb摸bbb | 久久这里有 | 日韩影视大全 | 97av免费视频 | 91精品视频免费观看 | 精品女同一区二区三区在线观看 | 999国内精品永久免费视频 | 在线观看日韩免费视频 | 97视频免费播放 | 色在线中文字幕 | 中文字幕日韩精品有码视频 | 五月综合在线观看 | 亚洲婷婷网 | 99久久精品无码一区二区毛片 | 西西www4444大胆视频 | 在线岛国av| 成人久久18免费网站图片 | 在线观看成人 | 久久精品国产99 | 天天操天天射天天插 | 激情文学丁香 | 日韩在线观看视频一区二区三区 | 午夜久草 | 综合网伊人 | 国产精品美女999 | 国产精品精品久久久久久 | 国产精品永久免费视频 | 激情丁香 | 国产成人三级 | 成人资源在线播放 | 亚洲黄在线观看 | 综合网中文字幕 | 99精品国产兔费观看久久99 | 日韩字幕 | 国产系列在线观看 | 日本黄色片一区二区 | 精品久久久久久久久中文字幕 | 国产成人在线免费观看 | 天天操夜夜操夜夜操 | 精品亚洲免费视频 | 欧美精品一级视频 | 久久久亚洲精华液 | 欧美一级视频在线观看 | 国产日本高清 | 精品夜夜嗨av一区二区三区 | 久久久影院一区二区三区 | 国产视频精品久久 | 欧美日韩p片 | 久久免费视频这里只有精品 | www.天天操.com | 香蕉视频在线免费 | 精品日韩在线一区 | 青春草免费在线视频 | 久久精品成人热国产成 | 99久久精品免费看国产麻豆 | 91高清免费看 | 午夜av在线电影 | 五月天色丁香 | 亚洲理论影院 | 国际av在线 | 色姑娘综合网 | 久久激情久久 | 久久九九影视网 | 国产成人黄色网址 | 毛片视频网址 | 日韩视频欧美视频 | 在线免费av播放 | 国产又粗又猛又色又黄视频 | 日韩精品一区二区在线观看视频 | 九九精品久久 | 久久爱导航 | 国产精品久久久久久久久久免费看 | 天天曰夜夜爽 | 中文字幕在线视频一区二区 | 欧美一区二区三区不卡 | 人人爽人人 | 国产成人精品一区二区在线观看 | 国产精品九色 | 婷婷精品 | av中文在线观看 | 天天操天天干天天插 | 久久成人国产精品免费软件 | 日韩网站在线 | 欧美精品久久 | 欧美日韩在线视频免费 | 丁香六月伊人 | 久久在线一区 | 精品毛片一区二区免费看 | 国产一区麻豆 | 一级片黄色片网站 | 免费网站v| 色网免费观看 | 国产高清免费观看 | 91九色在线 | 27xxoo无遮挡动态视频 | 一区二区三区四区精品视频 | 日本亚洲国产 | 天天曰天天爽 | 亚洲 中文 欧美 日韩vr 在线 | 国产黄色精品在线观看 | 久久国产精品一区二区三区四区 | 欧美视频日韩 | 久久在线视频在线 | 91精彩视频 | 国产精品免费观看国产网曝瓜 | 欧美极度另类性三渗透 | 欧美日韩在线免费视频 | 亚洲午夜久久久综合37日本 | 欧美小视频在线 | 日本性xxxxx 亚洲精品午夜久久久 | 91日韩在线视频 | 国产色拍拍拍拍在线精品 | www色| 国产精品久久久久久五月尺 | 69av在线播放 | 欧美国产日韩在线观看 | 高清av网 | 久草在线观 | 深爱婷婷 | 99热99re6国产在线播放 | 欧美日韩国产mv | 日本精品久久久久影院 | 麻豆传媒视频观看 | 91超碰免费在线 | 色综合久久88色综合天天6 | 麻豆va一区二区三区久久浪 | 97干com | 成人免费观看视频网站 | 五月天国产 | 久草电影免费在线观看 | 中文字幕2021 | 国产精品手机在线观看 | 激情五月婷婷综合 | 夜夜操网 | 国产精品第7页 | 国产黄色精品在线 | 亚洲精品久久久久久中文传媒 | 亚洲一级二级 | 六月色婷婷| 久一网站| 久久噜噜少妇网站 | 婷婷六月中文字幕 | 婷婷在线色 | 欧美一区二区三区免费看 | 国产在线最新 | 麻豆91网站 | 国产99久久精品 | 久久精品99视频 | 久久精品国产99国产 | 久久av网 | 日韩二区三区在线 | 久草在线免费看视频 | 欧美一区二视频在线免费观看 | 国产精品18videosex性欧美 | 久久综合五月婷婷 | 久久久精品 | 国产精品视频永久免费播放 | 欧美激情在线网站 | 国产一级大片在线观看 | 国产xvideos免费视频播放 | 在线观看免费 | 国产精品热 | 午夜性生活片 | 国产麻豆果冻传媒在线观看 | 免费中文字幕在线观看 | 久久久麻豆视频 | 国产在线播放一区二区 | 日本大片免费观看在线 | 国产精品永久免费观看 | 婷婷狠狠操 | 狠狠干成人综合网 | 91av视频导航 | 高清中文字幕 | 日韩免费久久 | 欧美国产日韩一区二区 | 国产高清不卡在线 | 免费看特级毛片 | 亚洲乱码在线 | 四虎影视国产精品免费久久 | av高清网站在线观看 | 色综合天天做天天爱 | av最新资源 | 午夜视频欧美 | 92av视频| 99视频久久| 91精品视屏 | 中文字幕在线色 | 国产一级做a | 中文字幕第一页在线播放 | 天堂在线一区二区 | 国产网红在线观看 | 国产精品九九九九九 | 黄色国产成人 | 久久久国产精品麻豆 | 欧美日韩在线播放一区 | 日韩亚洲精品电影 | 亚洲精品在线国产 | 一级黄视频 | 婷婷去俺也去六月色 | 午夜在线观看影院 | 亚洲视频电影在线 | 国产91电影在线观看 | 最近中文字幕在线中文高清版 | 欧美激情视频久久 | 欧美精品小视频 | 亚洲黄色免费网站 | 免费aa大片| 久艹视频免费观看 | 国产精品日韩欧美一区二区 | 国产999免费视频 | 亚洲精品成人网 | 日本久久免费视频 | 国产玖玖在线 | 亚洲人成人99网站 | 亚洲精选在线观看 | 久久经典国产 | 波多野结衣一区二区三区中文字幕 | 久久久久免费视频 | 久综合网 | 综合激情网 | 中文字幕亚洲综合久久五月天色无吗'' | 免费日韩一区二区三区 | 欧美一级视频免费看 | 国产精品淫片 | 欧美先锋影音 | 国产精品igao视频网入口 | 欧美 日韩 国产 中文字幕 | 在线v片免费观看视频 | 久久久久久久福利 | 最新国产精品拍自在线播放 | 久久综合精品国产一区二区三区 | 亚洲精品xx| 中文在线a∨在线 | 在线观看不卡视频 | 国产在线自 | 久久精品国产亚洲精品 | 韩日电影在线 | 精品国产综合区久久久久久 | 国产人成一区二区三区影院 | 久久精品男人的天堂 | 亚洲精品国产精品国产 | 91毛片在线观看 | 91在线视频导航 | 免费aa大片 | 日韩视频一区二区 | 亚洲精品中文字幕在线观看 | 又黄又爽的视频在线观看网站 | 黄色美女免费网站 | 国产999视频 | 免费av观看| 国产一线天在线观看 | 一区二区三区www | 亚洲理论在线 | 91在线视频免费观看 | 96视频在线| 四虎在线观看精品视频 | 91大神视频网站 | 97超碰精品 | 日韩中文字幕免费在线观看 | 国产精品自在欧美一区 | 亚洲精品久久久久999中文字幕 | 91探花国产综合在线精品 | 三级av在线| 欧美精品久久久久性色 | 在线91精品| 国产成人一区二区在线观看 | 日韩精品中文字幕一区二区 | 日韩有码网站 | 国产精品久久久久久吹潮天美传媒 | 亚洲专区视频在线观看 | 丁香婷婷激情网 | 91插插插免费视频 | 国产v亚洲v | 高清视频一区二区三区 | 欧美一区二区日韩一区二区 | 91完整版| 激情欧美xxxx | 欧美性护士| 欧美精品乱码久久久久 | 视频二区在线视频 | 久久人人爽人人爽人人片 | 久久黄色片子 | 日韩av看片 | 99久久精品久久亚洲精品 | 久久精品8 | 三上悠亚一区二区在线观看 | 99精品一区二区三区 | 久久国产麻豆 | 免费在线播放黄色 | 久久精品日产第一区二区三区乱码 | 日韩欧美一区二区三区黑寡妇 | 91中文在线 | 国产午夜精品一区二区三区在线观看 | 免费日韩 精品中文字幕视频在线 | 韩日电影在线观看 | 成人欧美一区二区三区黑人麻豆 | 亚洲精品中文字幕在线观看 | 国产精品久久久久久久久久免费 | 91久久偷偷做嫩草影院 | 西西人体4444www高清视频 | 久草网在线 | 99久热在线精品视频成人一区 | 国产精品久久久一区二区 | 亚洲一级黄色大片 | 国产成人av综合色 | 一区二区三区国产欧美 | 日韩特级毛片 | 91精品国产福利在线观看 | 精品国产伦一区二区三区观看体验 | 色综合 久久精品 | 波多野结衣日韩 | 在线观看av麻豆 | 国产天天爽 | 一区二区三区在线视频111 | 国产99久久久国产精品 | 人人爱天天操 | 亚洲黄色av网址 | 日日夜精品 | av不卡免费看 | va视频在线 | 久久天堂网站 | 成人国产网站 | 伊人亚洲精品 | 国产又粗又猛又爽又黄的视频先 | 国产精品6999成人免费视频 | 国产九九热视频 | 亚洲久草在线视频 | 免费a视频在线观看 | 国产精品s色 | 色资源在线观看 | 欧亚日韩精品一区二区在线 | 精品国产一区二区三区久久 | 日日摸日日爽 | 伊人天天干 | 亚洲天天在线日亚洲洲精 | 久久久久久久久黄色 | 在线国产一区 | 天天天天天天天操 | 亚洲天堂自拍视频 | 500部大龄熟乱视频 欧美日本三级 | 超薄丝袜一二三区 | 综合国产视频 | 99在线视频精品 | 国产在线国偷精品产拍 | 全黄网站 | 激情久久久久 | 在线观看中文字幕亚洲 | 黄色小说网站在线 | 亚欧日韩成人h片 | 国产视频丨精品|在线观看 国产精品久久久久久久久久久久午夜 | 少妇激情久久 | 在线免费观看国产黄色 | 成人在线观看免费 | 91完整版 | 国产一级二级三级视频 | 国产中文字幕三区 | www日韩在线| 国产成人在线免费观看 | 国产99久久久久 | 欧美午夜理伦三级在线观看 | 黄视频色网站 | 日韩在线观看第一页 | 天天干天天操天天拍 | 国产婷婷精品av在线 | 国产精品久久久久久久免费 | 伊人电影在线观看 | 黄色官网在线观看 | 欧美精品在线免费 | 日日干夜夜草 | 国产精品国产三级国产aⅴ入口 | 亚洲日韩精品欧美一区二区 | 亚洲成人av在线电影 | 久热av在线 | 久人人| 久久99欧美| 久草在线观看视频免费 | av免费在线观看1 | 亚洲成人免费观看 | 91精品在线视频观看 | 欧美一区二区三区在线视频观看 | 五月综合色婷婷 | 亚洲精品中文在线 | 精品999久久久 | av在线之家电影网站 | 天天操夜夜曰 | 极品美女被弄高潮视频网站 | 91麻豆精品国产91久久久无限制版 | 精壮的侍卫呻吟h | 日韩一区精品 | 国产高潮久久 | 99热这里只有精品8 久久综合毛片 | 天堂va欧美va亚洲va老司机 | 激情小说网站亚洲综合网 | 亚洲免费成人av电影 | 欧美色图一区 | 天天干天天操天天射 | 国产精品午夜av | 国产另类xxxxhd高清 | 色综合天天色 | 美女视频网站久久 | 国产无吗一区二区三区在线欢 | 国产一区二区三区免费在线 | 欧美极品少妇xxxxⅹ欧美极品少妇xxxx亚洲精品 | 精品国产欧美一区二区三区不卡 | 最近免费中文字幕大全高清10 | 欧美日韩午夜爽爽 | 97精品视频在线 | 狠狠做深爱婷婷综合一区 | 久久国产女人 | 玖玖爱国产在线 | 精品国产一区二区三区男人吃奶 | 婷婷激情五月综合 | 日韩精品 在线视频 | 国产 视频 久久 | 美女露久久 | 国产亚洲视频在线免费观看 | 十八岁以下禁止观看的1000个网站 | 51久久夜色精品国产麻豆 | 中文字幕日韩电影 | 91视频麻豆 | 日日夜夜91| 婷婷亚洲激情 | 五月婷婷综 | 久久精品99国产精品亚洲最刺激 | 国产午夜麻豆影院在线观看 | 亚洲激情 在线 | 欧美久草视频 | 国产精品9999久久久久仙踪林 | 五月av在线 | 五月婷婷六月丁香在线观看 | 不卡的av在线 | 久久99热这里只有精品 | 久久夜靖品 | 国产免费xvideos视频入口 | 婷婷激情欧美 | 亚洲激情六月 | 欧美最猛性xxxxx(亚洲精品) | 亚洲五月婷 | 天堂av在线中文在线 | 国产精品综合久久久久 | 亚洲国产视频在线 | 国产精品理论片在线观看 | 国产91影院 | 黄色成人av在线 | 午夜精品久久久99热福利 | 国产免费久久精品 | 欧美黄色软件 | 五月开心色 | 欧美日韩亚洲在线观看 | 伊人伊成久久人综合网站 | 在线免费中文字幕 | aaa日本高清在线播放免费观看 | 国产免费不卡 | 91在线网址 | 欧美激情精品久久久久久免费印度 | 亚洲国产字幕 | 伊人中文字幕在线 | 黄色在线观看网站 | 日本久久成人 | 欧美精品久久久久性色 | 依人成人综合网 | 特黄特色特刺激视频免费播放 | 激情深爱 | av色影院| 狠狠干狠狠久久 | 久久99精品久久久久蜜臀 | 在线精品视频在线观看高清 | 91免费网站在线观看 | 黄网站a | 中文国产在线观看 | 欧美va天堂在线电影 | 日本在线观看黄色 | 国产又黄又猛又粗 | 亚洲视屏 | 成人综合婷婷国产精品久久免费 | 狠狠精品 | 国产精品久久久久9999吃药 | 国产精品69av | 久久狠狠一本精品综合网 | 中文字幕第一 | 亚洲精品视频在线观看免费视频 | 操一草| 91一区二区在线 | 国产剧情久久 | 人人爱在线视频 | 天天操天天操天天操天天 | 91在线免费公开视频 | 国产不卡片 | 超碰97国产在线 | 国产精品久久久久久久久久ktv | 91视频在线免费下载 | av无限看 | 91在线观看视频网站 | 一级免费黄视频 | 999成人网 | 韩日av一区二区 | 久草视频在线资源 | 久保带人| 91在线免费公开视频 | 狠狠色丁香婷婷综合久久片 | 久久婷婷一区二区三区 | 夜夜看av | 在线观看视频你懂 | 四虎免费在线观看视频 | 99999精品| 九九九热精品免费视频观看网站 | 在线播放亚洲激情 | 国产亚洲精品成人 | 久久看片网站 | 欧美亚洲精品一区 | 日韩一级理论片 | 激情综合五月天 | 国产精品一区二区三区四 | 2022久久国产露脸精品国产 | 一区电影 | 日韩成人在线一区二区 | 国产高清第一页 | 97色se| 99久久99久久免费精品蜜臀 | 伊人狠狠操 | 亚洲精品高清在线 | 在线免费视频a | 激情导航 | 久久中国精品 | 99爱在线| 天天射综合网站 | 天天操天天操天天操天天操天天操天天操 | a级国产片 | www激情网| 亚洲在线色 | 91视频在线自拍 | 亚洲精品免费视频 | 91麻豆精品国产91久久久无需广告 | 国产亚洲精品无 | 国产在线观看网站 | 91精品国自产拍天天拍 | 又污又黄网站 | 欧美日韩免费观看一区二区三区 | 午夜精品久久久久久久爽 | 久久99精品国产99久久6尤 | 亚洲理论片在线观看 | 91网站在线视频 | 久久久久久激情 | 99视频在线免费 | 六月丁香综合网 | 久久精品视频网址 | 成人亚洲精品国产www | 97精品国产91久久久久久久 | 中文字幕亚洲综合久久五月天色无吗'' | 国产原创av片 | 欧美 日韩 国产 中文字幕 | 久久精品欧美日韩精品 | 韩国av电影在线观看 | 久久久久亚洲精品成人网小说 | 久精品视频 | 丁香婷婷综合激情 | 亚洲乱码精品 | 欧美色图亚洲图片 | 免费在线一区二区三区 | 蜜臀av夜夜澡人人爽人人 | 91在线精品播放 | 亚洲成色777777在线观看影院 | 日韩免费福利 | 国产免费一区二区三区最新 | 日韩乱码在线 | 狠狠干夜夜操 | 亚洲精品久久久久久久蜜桃 | 国产精品入口a级 | 男女视频久久久 | 青青河边草免费观看完整版高清 | 五月天精品视频 | 99视频在线精品 | 国产精品久久久久久久久久妇女 | 亚洲日本中文字幕在线观看 | 国产一级片在线播放 | 国产亚洲精品久久久久久大师 | 黄色网址在线播放 | 亚洲欧美精品在线 | 国产1区2区 | 天天操比| 国产精品va最新国产精品视频 | 看毛片网站 | 欧美国产日韩在线观看 | 九九热只有这里有精品 | 国产精品美女久久久久久久网站 | 不卡av在线播放 | 91精品免费在线视频 | 麻豆一二三精选视频 | 一级成人网| 美女黄久久 | 亚洲黄在线观看 | 一区二区视频在线免费观看 | 日韩r级在线 | 国产中文a | 日韩免费电影在线观看 | 麻豆视传媒官网免费观看 | 国产成人精品久久亚洲高清不卡 | 国产高潮久久 | 日日日日 | 国产精品99久久久久久有的能看 | 欧美a免费 | 婷婷激情网站 | 四虎影视成人永久免费观看视频 | 日一日操一操 | 91精品国产乱码 | 天天爱天天 | 99热这里精品 | 久草视频一区 | 精品国产伦一区二区三区观看体验 | 国产视频精选 | 日韩久久激情 | 在线免费av网 | 成人av免费看 | 色多多视频在线 | 丁香5月婷婷久久 | 国产精品剧情在线亚洲 | 欧美激情视频一区二区三区 | 91精品国产99久久久久 | 国产91在线播放 | 久二影院| 黄色1级毛片 | 日本视频高清 | 中文字幕最新精品 | 黄色毛片一级片 | 91污污 | 久久综合国产伦精品免费 | 人人爽人人 | 成人午夜电影免费在线观看 | 97色在线观看免费视频 | 丁香六月在线观看 | 精品影院 | 国产精品久久久久久久久毛片 | 麻豆系列在线观看 | 亚洲成人在线免费 | 蜜臀av性久久久久av蜜臀三区 | 狠狠干婷婷 | 国产中文视频 | 久久伊人热 | 欧美精品免费在线 | 欧美激情第八页 | 午夜精品久久久久久久久久 | 日韩在线精品 | 在线观看视频你懂得 | 日韩啪啪小视频 | 特级xxxxx欧美 | 精品国产理论 | 免费精品人在线二线三线 | 天堂中文在线播放 | 精品美女在线观看 | 亚洲黄色免费观看 | 欧美色图亚洲图片 | 国产高清网站 | av视屏在线播放 | 五月婷网站 | 久热免费 | 狠狠躁18三区二区一区ai明星 | 日韩欧美在线高清 | 久久激情视频 | 亚洲婷婷在线视频 | 亚洲2019精品 | 最近的中文字幕大全免费版 | 亚州精品天堂中文字幕 | 欧美国产不卡 | 成人欧美一区二区三区黑人麻豆 | 天天天天爱天天躁 | av大片免费在线观看 | 国产91丝袜在线播放动漫 | 久久久久免费网 | 精品久久久久久国产偷窥 | 成人三级网站在线观看 | 国产玖玖精品视频 | 在线观看免费高清视频大全追剧 | 国产日本在线 | 日韩成人黄色av | 人人爱人人做人人爽 | 亚洲乱码精品久久久久 | 国产精品久久久久久久午夜 | 欧美日韩国产二区三区 | 国产啊v在线观看 | 91久久久久久久一区二区 | 国产成人在线观看免费 | 免费国产在线视频 | 成人免费视频播放 | 欧美日韩精品在线免费观看 | 欧美特一级 | 麻豆免费在线播放 | 中文字幕欧美日韩va免费视频 | 亚洲va欧美va人人爽春色影视 | 久久久夜色| 亚洲无线视频 | 草久久av | av在线影片 | 国内久久久久久 | 日本mv大片欧洲mv大片 | 免费av的网站 | 日韩精品一区二区免费 | 亚洲天堂精品视频 | 日韩一区在线免费观看 | 国产一区二区三区免费在线 | 男女拍拍免费视频 | 国产在线久草 | 丁香综合网 | 色综合色综合色综合 | 亚洲成人av电影 | 日韩免费播放 | 亚洲精品欧美专区 | 久草免费资源 | 久久涩涩网站 | 91精品国产乱码 | 99久精品视频 | 国产精品视频永久免费播放 | 婷婷综合成人 | 国产精品对白一区二区三区 | 丁香五婷 | 国产午夜精品一区二区三区在线观看 | 精品国产亚洲在线 | 一区二区三区四区五区在线 | 久久超碰97 | 韩国在线一区 | 久久久久久久18 | 麻豆视频在线 | 91亚洲精品乱码久久久久久蜜桃 | 人人澡澡人人 | 成人亚洲欧美 | 国产美女视频一区 | 欧美性性网 | 亚洲国产av精品毛片鲁大师 | 免费看一级特黄a大片 | 91麻豆精品国产91久久久久久 | 最近字幕在线观看第一季 | 久久久久久久久久久久影院 | 在线中文字幕视频 | wwwwww黄| 91精品伦理| 一区二区三区福利 | 97超碰人人爱 | 婷婷丁香狠狠爱 | 国产xxxxx在线观看 | 国产亚洲精品综合一区91 | 99久久日韩精品视频免费在线观看 | 97超碰人人网 | 亚洲激情在线视频 | 国产视频1 | 探花视频免费观看 | 五月天堂网 | 黄色特一级片 | 国产免费观看久久 | 免费中文字幕视频 | 国产精品专区h在线观看 | 亚洲 综合 激情 | 亚洲一区二区麻豆 | 韩国一区二区三区在线观看 | 中文字幕在线字幕中文 | 在线亚洲午夜片av大片 | 天堂黄色片 | 亚洲精品美女久久 | 精品视频在线免费 | 天天做天天爱天天爽综合网 | 国产精品午夜在线观看 | 中文av资源站 | 久久人网 | 99国产精品久久久久久久久久 | 欧美在线91 | 天天爽网站 | 国产一级一片免费播放放a 一区二区三区国产欧美 | 欧美成人性网 | 国产精品成久久久久三级 | 中国精品一区二区 | 日韩一级理论片 | 最新国产精品拍自在线播放 | 五月天婷亚洲天综合网精品偷 | 成人午夜黄色影院 | 国产精品自拍av | 国产精品99久久久久 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 超碰在97| 91在线观看欧美日韩 | 丁香激情综合 | 日本黄色a级大片 | 一区三区视频在线观看 | 免费在线一区二区 | 日精品 | 伊人色**天天综合婷婷 | 欧美国产高清 | 亚洲精品在线免费播放 | 国产精品成人免费精品自在线观看 | 免费黄色av | 国产日韩精品一区二区在线观看播放 | 欧美精品久久久久久久久老牛影院 | 精品国产91亚洲一区二区三区www | 福利视频网站 | а中文在线天堂 | 欧美一级片在线播放 | www.久久视频 | 五月天综合激情网 | 久久人人97超碰国产公开结果 | 三级视频日韩 | 最近2019年日本中文免费字幕 | 国产精品小视频网站 | 精选久久| caobi视频| 国产精品黄色 | 97在线公开视频 | 精品日韩在线 | 久久伦理电影 | 91精品国产自产在线观看永久 | 国产一二三区av | 国产97免费 | www.国产高清 | 国产成人久久精品77777 | 国产精品久久一 | 日韩在线欧美在线 | 日韩高清一区在线 | 久久伊人免费视频 | 免费国产在线观看 | 欧美a视频在线观看 | 国产一区成人在线 | 久草综合在线观看 | 日韩乱码中文字幕 | 香蕉视频在线免费 | 午夜男人影院 | 中文字幕精品一区久久久久 | 久久99国产精品久久99 | 国产亚洲视频中文字幕视频 | 玖玖视频 | 中文字幕国产一区二区 | 爱色婷婷 | 毛片一级免费一级 | 国产精品美女久久久久久2018 | 4hu视频| 中文字幕在线专区 | 91精品国产欧美一区二区成人 | 亚洲毛片久久 | 国产手机视频精品 | 日韩免费在线观看视频 | 中文字幕一区二区三区四区 | 免费观看www7722午夜电影 | 97爱| 99精品久久久| 激情五月网站 | 天天插夜夜操 | 久久人人97超碰国产公开结果 | 成人黄色小说在线观看 | 亚洲精品在线一区二区 | 国产免费视频在线 | 在线免费观看羞羞视频 | 亚洲免费永久精品国产 | 99中文字幕视频 | 国产系列精品av | 欧美一级片免费观看 | 久久国产一二区 | 在线影视 一区 二区 三区 | 午夜成人免费影院 | 91桃色在线观看视频 | 中文字幕有码在线播放 | 亚洲手机天堂 | 天天草综合 | 在线va视频 | 国产高清免费观看 | 久久久久高清毛片一级 | 香蕉视频日本 | 亚洲欧美视频一区二区三区 | av免费网页 | 久久国内免费视频 | 玖玖在线观看视频 | 国产精彩在线视频 | 国产精品一区久久久久 | 欧美激情综合色 | 二区视频在线观看 | 亚洲成年人av | 国产精品手机在线观看 | 五月综合网| 色资源网在线观看 | 手机在线观看国产精品 | 六月丁香激情综合 | 国产黄色片一级三级 | 91在线最新 | av综合av| 丁香六月在线观看 | 成人免费看视频 | 国产九色在线播放九色 | 久久这里只有精品久久 | 最新中文在线视频 | 免费黄色在线网址 | 日韩在观看线 | 免费大片黄在线 | 米奇影视7777| 国产成人av在线 | 91看片在线 | 狠狠操狠狠插 | 久久久人| 中文字幕在线视频第一页 | 天天插视频 | 97精品在线视频 | 国产精品美女免费视频 | 天天曰天天爽 | 97精品国产97久久久久久久久久久久 | 六月丁香色婷婷 | 中文字幕影片免费在线观看 | 久久污视频 | 在线观看精品一区 | 中文字幕av免费在线观看 | 精品国产精品久久一区免费式 | 91大神一区二区三区 | 欧美地下肉体性派对 | 亚洲h在线播放在线观看h | 黄色小说视频在线 | 欧美另类sm图片 | 天天干天天射天天插 | 四虎成人精品永久免费av九九 | 91人人爽久久涩噜噜噜 | www视频在线观看 | 久久影视网 | 国产网站av |