成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

傻傻分不清的Manifest

printempw / 1053人閱讀

摘要:的英文含義是名單種技術(shù)的確都是把當(dāng)做清單使用緩存清單清單打包資源路徑清單打包清單只不過(guò)是在不同的場(chǎng)景中使用特定的清單來(lái)完成某些功能所以,學(xué)好英文是多么重要,這樣才不會(huì)傻傻分不清到底是干啥的

在前端,說(shuō)到manifest,其實(shí)是有歧義的,就我了解的情況來(lái)說(shuō),manifest可以指代下列含義:

html標(biāo)簽的manifest屬性: 離線緩存(目前已被廢棄)

PWA: 將Web應(yīng)用程序安裝到設(shè)備的主屏幕

webpack中webpack-manifest-plugin插件打包出來(lái)的manifest.json文件,用來(lái)生成一份資源清單,為后端渲染服務(wù)

webpack中DLL打包時(shí),輸出的manifest.json文件,用來(lái)分析已經(jīng)打包過(guò)的文件,優(yōu)化打包速度和大小

下面我們來(lái)一一介紹下

html屬性




  
  
  
  Document
  
  
  


 


瀏覽器解析這段html標(biāo)簽時(shí),就會(huì)去訪問(wèn)tc.mymanifest這個(gè)文件,這是一個(gè)緩存清單文件

tc.mymanifest

# v1 這是注釋
CACHE MANIFEST
/theme.css
/main.js

NETWORK:
*

FALLBACK:
/html5/ /404.html

CACHE MANIFEST指定需要緩存的文件,第一次下載完成以后,文件都不會(huì)再?gòu)木W(wǎng)絡(luò)請(qǐng)求了,即使用戶不是離線狀態(tài),除非tc.mymanifest更新了,緩存清單更新之后,才會(huì)再次下載。標(biāo)記了manifest的html本身也被緩存

NETWORK指定非緩存文件,所有類似資源的請(qǐng)求都會(huì)繞過(guò)緩存,即使用戶處于離線狀態(tài),也不會(huì)讀緩存

FALLBACK指定了一個(gè)后備頁(yè)面,當(dāng)資源無(wú)法訪問(wèn)時(shí),瀏覽器會(huì)使用該頁(yè)面。
比如離線訪問(wèn)/html5/目錄時(shí),就會(huì)用本地的/404.html頁(yè)面

緩存清單可以是任意后綴名,不過(guò)必須指定content-type屬性為text/cache-manifest

那如何更新緩存?一般有以下幾種方式:

用戶清空瀏覽器緩存

manifest 文件被修改(即使注釋被修改)

由程序來(lái)更新應(yīng)用緩存

需要特別注意:用戶第一次訪問(wèn)該網(wǎng)頁(yè),緩存文件之后,第二次進(jìn)入該頁(yè)面,發(fā)現(xiàn)tc.mymanifest緩存清單更新了,于是會(huì)重新下載緩存文件,但是,第二次進(jìn)入顯示的頁(yè)面仍然執(zhí)行的是舊文件,下載的新文件,只會(huì)在第三次進(jìn)入該頁(yè)面后執(zhí)行!??!

如果希望用戶立即看到新內(nèi)容,需要js監(jiān)聽(tīng)更新事件,重新加載頁(yè)面

window.addEventListener("load", function (e) {

  window.applicationCache.addEventListener("updateready", function (e) {

    if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
      // 更新緩存
      // 重新加載
      window.applicationCache.swapCache();
      window.location.reload();

    } else {

    }

  }, false);

}, false);

建議對(duì)tc.mymanifest緩存清單設(shè)置永不緩存

不過(guò),manifest也有很多缺點(diǎn),比如需要手動(dòng)一個(gè)個(gè)填寫(xiě)緩存的文件,更新文件之后需要二次刷新,如果更新的資源中有一個(gè)資源更新失敗了,將導(dǎo)致全部更新失敗,將用回上一版本的緩存

HTML5規(guī)范也廢棄了這個(gè)屬性,因此不建議使用

PWA

為了實(shí)現(xiàn)PWA應(yīng)用添加至桌面的功能,除了要求站點(diǎn)支持HTTPS之外,還需要準(zhǔn)備 manifest.json文件去配置應(yīng)用的圖標(biāo)、名稱等信息

{ 
"name" : "Minimal PWA" , 
"short_name" : "PWA Demo" , 
"display" : "standalone" , 
"start_url" : "/" , 
"theme_color" : "#313131" , 
"background_color" : "#313131" , 
"icons" : [ 
  {
    "src": "images/touch/homescreen48.png",
    "sizes": "48x48",
    "type": "image/png"
  }
 ] 
}

通過(guò)一系列配置,就可以把一個(gè)PWA像APP一樣,添加一個(gè)圖標(biāo)到手機(jī)屏幕上,點(diǎn)擊圖標(biāo)即可打開(kāi)站點(diǎn)

基于webpack的react開(kāi)發(fā)環(huán)境

本文默認(rèn)你已經(jīng)了解最基本的webpack配置,如果完全不會(huì),建議看下這篇文章

我們首先搭建一個(gè)最簡(jiǎn)單的基于webpack的react開(kāi)發(fā)環(huán)境

源代碼地址:https://github.com/deepred5/l...

mkdir learn-dll
cd learn-dll

安裝依賴

npm init -y
npm install @babel/polyfill react react-dom --save
npm install webpack webpack-cli webpack-dev-server @babel/core @babel/preset-env @babel/preset-react add-asset-html-webpack-plugin autoprefixer babel-loader clean-webpack-plugin css-loader html-webpack-plugin mini-css-extract-plugin node-sass postcss-loader sass-loader style-loader --save-dev

新建.bablerc

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage", // 根據(jù)browserslis填寫(xiě)的瀏覽器,自動(dòng)添加polyfill
        "corejs": 2,
      }
    ],
    "@babel/preset-react" // 編譯react
  ],
  "plugins": []
}

新建postcss.config.js

module.exports = {
  plugins: [
    require("autoprefixer") // 根據(jù)browserslis填寫(xiě)的瀏覽器,自動(dòng)添加css前綴
  ]
}

新建.browserslistrc

last 10 versions
ie >= 11
ios >= 9
android >= 6

新建webpack.dev.js(基本配置不再詳細(xì)介紹)

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  mode: "development",
  devtool: "cheap-module-eval-source-map",
  entry: {
    main: "./src/index.js"
  },
  output: {
    path: path.resolve(__dirname, "./dist"),
    filename: "[name].js",
    chunkFilename: "[name].chunk.js",
  },
  devServer: {
    historyApiFallback: true,
    overlay: true,
    port: 9001,
    open: true,
    hot: true,
  },
  module: {
    rules: [
      {
        test: /.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      },
      {
        test: /.css$/,
        use: ["style-loader",
          "css-loader",
          "postcss-loader"
        ],
      },
      {
        test: /.scss$/,
        use: ["style-loader",
          {
            loader: "css-loader",
            options: {
              modules: false,
              importLoaders: 2
            }
          },
          "sass-loader",
          "postcss-loader"
        ],
      },
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({ template: "./src/index.html" }), // index打包模板
  ]
}

新建src目錄,并新建src/index.html




  
  
  
  learn dll


  

新建src/Home.js

import React from "react";
import "./Home.scss";

export default () => 
home

新建src/Home.scss

.home {
  color: red;
}

新建src/index.js

import React, { Component } from "react";
import ReactDom from "react-dom";
import Home from "./Home";

class Demo extends Component {
  render() {
    return (
      
    )
  }
}

ReactDom.render(, document.getElementById("app"));

修改package.json

"scripts": {
  "dev": "webpack-dev-server --config webpack.dev.js"
},

最后,運(yùn)行npm run dev,應(yīng)該可以看見(jiàn)效果

新建webpack.prod.js

const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");


module.exports = {
  mode: "production",
  entry: {
    main: "./src/index.js"
  },
  output: {
    path: path.resolve(__dirname, "./dist"),
    filename: "[name].[contenthash:8].js",
    chunkFilename: "[name].[contenthash:8].chunk.js",
  },
  module: {
    rules: [
      {
        test: /.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      },
      {
        test: /.css$/,
        use: [MiniCssExtractPlugin.loader, // 多帶帶提取css文件
          "css-loader",
          "postcss-loader"
        ],
      },
      {
        test: /.scss$/,
        use: [MiniCssExtractPlugin.loader,
        {
          loader: "css-loader",
          options: {
            modules: false,
            importLoaders: 2
          }
        },
          "sass-loader",
          "postcss-loader"
        ],
      },
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({ template: "./src/index.html" }),
    new MiniCssExtractPlugin({
      filename: "[name].[contenthash:8].css",
      chunkFilename: "[id].[contenthash:8].css",
    }),
    new CleanWebpackPlugin(), // 打包前先刪除之前的dist目錄
  ]
};

修改package.json,添加一句"build": "webpack --config webpack.prod.js"

運(yùn)行npm run build,可以看見(jiàn)打包出來(lái)的dist目錄

html,js,css都多帶帶分離出來(lái)了

至此,一個(gè)基于webpack的react環(huán)境搭建完成

webpack-manifest-plugin

通常情況下,我們打包出來(lái)的js,css都是帶上版本號(hào)的,通過(guò)HtmlWebpackPlugin可以自動(dòng)幫我們?cè)?b>index.html里面加上帶版本號(hào)的js和css




  
  
  
  learn dll


  

但是在某些情況,index.html模板由后端渲染,那么我們就需要一份打包清單,知道打包后的文件對(duì)應(yīng)的真正路徑

安裝插件webpack-manifest-plugin

npm i webpack-manifest-plugin -D

修改webpack.prod.js

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

重新打包,可以看見(jiàn)dist目錄新生成了一個(gè)manifest.json

{
  "main.css": "main.198b3634.css",
  "main.js": "main.d312f172.js",
  "index.html": "index.html"
}

比如在SSR開(kāi)發(fā)時(shí),前端打包后,node后端就可以通過(guò)這個(gè)json數(shù)據(jù),返回正確資源路徑的html模板

const buildPath = require("./dist/manifest.json");

res.send(`
  


  
  
  
  ssr


  
`);
代碼分割

我們之前的打包方式,有一個(gè)缺點(diǎn),就是把業(yè)務(wù)代碼和庫(kù)代碼都統(tǒng)統(tǒng)打到了一個(gè)main.js里面。每次業(yè)務(wù)代碼改動(dòng)后,main.js的hash值就變了,導(dǎo)致客戶端又要重新下載一遍main.js,但是里面的庫(kù)代碼其實(shí)是沒(méi)改變的!

通常情況下,react react-dom之類的庫(kù),都是不經(jīng)常改動(dòng)的。我們希望多帶帶把這些庫(kù)代碼提取出來(lái),生成一個(gè)vendor.js,這樣每次改動(dòng)代碼,只是下載main.jsvendor.js可以充分緩存(也就是所謂的代碼分割code splitting)

webpack4自帶代碼分割功能,只要配置:

optimization: {
  splitChunks: {
    chunks: "all"
  }
}

webpack.prod.js

const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const ManifestPlugin = require("webpack-manifest-plugin");

module.exports = {
  mode: "production",
  entry: {
    main: "./src/index.js"
  },
  output: {
    path: path.resolve(__dirname, "./dist"),
    filename: "[name].[contenthash:8].js",
    chunkFilename: "[name].[contenthash:8].chunk.js",
  },
  module: {
    rules: [
      {
        test: /.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      },
      {
        test: /.css$/,
        use: [MiniCssExtractPlugin.loader,
          "css-loader",
          "postcss-loader"
        ],
      },
      {
        test: /.scss$/,
        use: [MiniCssExtractPlugin.loader,
        {
          loader: "css-loader",
          options: {
            modules: false,
            importLoaders: 2
          }
        },
          "sass-loader",
          "postcss-loader"
        ],
      },
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({ template: "./src/index.html" }),
    new MiniCssExtractPlugin({
      filename: "[name].[contenthash:8].css",
      chunkFilename: "[id].[contenthash:8].css",
    }),
    new CleanWebpackPlugin(),
    new ManifestPlugin()
  ],
  optimization: {
    splitChunks: {
      chunks: "all"
    }
  }
};

重新打包,發(fā)現(xiàn)新生成了一個(gè)vendor.js文件,公用的一些代碼就被打包進(jìn)去了

重新修改src/Home.js,然后打包,你會(huì)發(fā)現(xiàn)vendor.js的hash沒(méi)有改變,這也是我們希望的

DLL打包

上面的打包方式,隨著項(xiàng)目的復(fù)雜度上升后,打包速度會(huì)開(kāi)始變慢。原因是,每次打包,webpack都要分析哪些是公用庫(kù),然后把他打包到vendor.js

我們可不可以在第一次構(gòu)建vendor.js以后,下次打包,就直接跳過(guò)那些被打包到vendor.js里的代碼呢?這樣打包速度可以明顯提升

這就需要DllPlugin結(jié)合DllRefrencePlugin插件的運(yùn)用

dll打包原理就是:

把指定的庫(kù)代碼打包到一個(gè)dll.js,同時(shí)生成一份對(duì)應(yīng)的manifest.json文件

webpack打包時(shí),讀取manifest.json,知道哪些代碼可以直接忽略,從而提高構(gòu)建速度

我們新建一個(gè)webpack.dll.js

const path = require("path");
const webpack = require("webpack");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
  mode: "production",
  entry: {
    vendors: ["react", "react-dom"] // 手動(dòng)指定打包哪些庫(kù)
  },
  output: {
    filename: "[name].[hash:8].dll.js",
    path: path.resolve(__dirname, "./dll"),
    library: "[name]"
  },
  plugins: [
    new CleanWebpackPlugin(),
    new webpack.DllPlugin({
      path: path.join(__dirname, "./dll/[name].manifest.json"), // 生成對(duì)應(yīng)的manifest.json,給webpack打包用
      name: "[name]",
    }),
  ],
}

添加一條命令:

"build:dll": "webpack --config webpack.dll.js"

運(yùn)行dll打包

npm run build:dll

發(fā)現(xiàn)生成一個(gè)dll目錄

修改webpack.prod.js

const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const ManifestPlugin = require("webpack-manifest-plugin");
const webpack = require("webpack");

module.exports = {
  mode: "production",
  entry: {
    main: "./src/index.js"
  },
  output: {
    path: path.resolve(__dirname, "./dist"),
    filename: "[name].[contenthash:8].js",
    chunkFilename: "[name].[contenthash:8].chunk.js",
  },
  module: {
    rules: [
      {
        test: /.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      },
      {
        test: /.css$/,
        use: [MiniCssExtractPlugin.loader,
          "css-loader",
          "postcss-loader"
        ],
      },
      {
        test: /.scss$/,
        use: [MiniCssExtractPlugin.loader,
        {
          loader: "css-loader",
          options: {
            modules: false,
            importLoaders: 2
          }
        },
          "sass-loader",
          "postcss-loader"
        ],
      },
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({ template: "./src/index.html" }),
    new MiniCssExtractPlugin({
      filename: "[name].[contenthash:8].css",
      chunkFilename: "[id].[contenthash:8].css",
    }),
    new webpack.DllReferencePlugin({
      manifest: path.resolve(__dirname, "./dll/vendors.manifest.json") // 讀取dll打包后的manifest.json,分析哪些代碼跳過(guò)
    }),
    new CleanWebpackPlugin(),
    new ManifestPlugin()
  ],
  optimization: {
    splitChunks: {
      chunks: "all"
    }
  }
};

重新npm run build,發(fā)現(xiàn)dist目錄里,vendor.js沒(méi)有了

這是因?yàn)?b>react,react-dom已經(jīng)打包到dll.js里了,webpack讀取manifest.json之后,知道可以忽略這些代碼,于是就沒(méi)有再打包了

但這里還有個(gè)問(wèn)題,打包后的index.html還需要添加dll.js文件,這就需要add-asset-html-webpack-plugin插件

npm i add-asset-html-webpack-plugin -D

修改webpack.prod.js

const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const ManifestPlugin = require("webpack-manifest-plugin");
const webpack = require("webpack");
const AddAssetHtmlPlugin = require("add-asset-html-webpack-plugin");

module.exports = {
  mode: "production",
  entry: {
    main: "./src/index.js"
  },
  output: {
    path: path.resolve(__dirname, "./dist"),
    filename: "[name].[contenthash:8].js",
    chunkFilename: "[name].[contenthash:8].chunk.js",
  },
  module: {
    rules: [
      {
        test: /.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      },
      {
        test: /.css$/,
        use: [MiniCssExtractPlugin.loader,
          "css-loader",
          "postcss-loader"
        ],
      },
      {
        test: /.scss$/,
        use: [MiniCssExtractPlugin.loader,
        {
          loader: "css-loader",
          options: {
            modules: false,
            importLoaders: 2
          }
        },
          "sass-loader",
          "postcss-loader"
        ],
      },
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({ template: "./src/index.html" }),
    new AddAssetHtmlPlugin({ filepath: path.resolve(__dirname, "./dll/*.dll.js") }), // 把dll.js加進(jìn)index.html里,并且拷貝文件到dist目錄
    new MiniCssExtractPlugin({
      filename: "[name].[contenthash:8].css",
      chunkFilename: "[id].[contenthash:8].css",
    }),
    new webpack.DllReferencePlugin({
      manifest: path.resolve(__dirname, "./dll/vendors.manifest.json") // 讀取dll打包后的manifest.json,分析哪些代碼跳過(guò)
    }),
    new CleanWebpackPlugin(),
    new ManifestPlugin()
  ],
  optimization: {
    splitChunks: {
      chunks: "all"
    }
  }
};

重新npm run build,可以看見(jiàn)dll.js也被打包進(jìn)dist目錄了,同時(shí)index.html也正確引用




  
  
  
  learn dll


  

小結(jié)

我們介紹了4種manifest相關(guān)的前端技術(shù)。manifest的英文含義是名單, 4種技術(shù)的確都是把manifest當(dāng)做清單使用:

緩存清單

PWA清單

打包資源路徑清單

dll打包清單

只不過(guò)是在不同的場(chǎng)景中使用特定的清單來(lái)完成某些功能

所以,學(xué)好英文是多么重要,這樣才不會(huì)傻傻分不清manifest到底是干啥的!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/104443.html

相關(guān)文章

  • 傻傻分不清的__proto__與prototype

    摘要:今天同事小英童鞋問(wèn)了我一個(gè)問(wèn)題小英童鞋認(rèn)為的原型對(duì)象是,所以會(huì)繼承的屬性,調(diào)用相當(dāng)于調(diào)用,但結(jié)果不是一個(gè)方法。構(gòu)造函數(shù)創(chuàng)建對(duì)象實(shí)例函數(shù)有兩個(gè)不同的內(nèi)部方法和。如果不通過(guò)關(guān)鍵字調(diào)用函數(shù),則執(zhí)行函數(shù),從而直接執(zhí)行代碼中的函數(shù)體。 今天同事小英童鞋問(wèn)了我一個(gè)問(wèn)題: function Foo(firstName, lastName){ this.firstName = firstNam...

    YancyYe 評(píng)論0 收藏0
  • CSS中+ , > , ~ 傻傻不清

    摘要:選擇器相鄰兄弟選擇器作用于緊跟其后的兄弟節(jié)點(diǎn)。注意事項(xiàng)有共同的父級(jí)必須緊跟其后,中間隔個(gè)啥都不行。注意事項(xiàng)要有共同的父級(jí)點(diǎn)擊查看大氣的,作用的范圍廣,限制少選擇器后代選擇器注意事項(xiàng)只作用于第一層后代點(diǎn)擊查看只作用于第一層后代 +選擇器(相鄰兄弟選擇器) 作用于緊跟其后的兄弟節(jié)點(diǎn)。 注意事項(xiàng): 1.有共同的父級(jí) 2.必須緊跟其后,中間隔個(gè)啥都不行。 3.只作用于緊跟其后的元素...

    piglei 評(píng)論0 收藏0
  • CSS中+ , > , ~ 傻傻不清

    摘要:選擇器相鄰兄弟選擇器作用于緊跟其后的兄弟節(jié)點(diǎn)。注意事項(xiàng)有共同的父級(jí)必須緊跟其后,中間隔個(gè)啥都不行。注意事項(xiàng)要有共同的父級(jí)點(diǎn)擊查看大氣的,作用的范圍廣,限制少選擇器后代選擇器注意事項(xiàng)只作用于第一層后代點(diǎn)擊查看只作用于第一層后代 +選擇器(相鄰兄弟選擇器) 作用于緊跟其后的兄弟節(jié)點(diǎn)。 注意事項(xiàng): 1.有共同的父級(jí) 2.必須緊跟其后,中間隔個(gè)啥都不行。 3.只作用于緊跟其后的元素...

    joyqi 評(píng)論0 收藏0
  • 神經(jīng)網(wǎng)絡(luò)訓(xùn)練中,Epoch、Batch Size和迭代傻傻不清?

    摘要:損失代價(jià)的減小是一件好事只有在數(shù)據(jù)很龐大的時(shí)候在機(jī)器學(xué)習(xí)中,幾乎任何時(shí)候都是,我們才需要使用,,迭代這些術(shù)語(yǔ),在這種情況下,一次性將數(shù)據(jù)輸入計(jì)算機(jī)是不可能的。 你肯定經(jīng)歷過(guò)這樣的時(shí)刻,看著電腦屏幕抓著頭,困惑著:「為什么我會(huì)在代碼中使用這三個(gè)術(shù)語(yǔ),它們有什么區(qū)別嗎?」因?yàn)樗鼈兛雌饋?lái)實(shí)在太相似了。為了理解這些術(shù)語(yǔ)有什么不同,你需要了解一些關(guān)于機(jī)器學(xué)習(xí)的術(shù)語(yǔ),比如梯度下降,以幫助你理解。這里簡(jiǎn)單...

    aisuhua 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<