前言:筆者把學習的webpack知識從基礎到原理寫個系列,以便回顧。希望能幫助到更多正在學習webpack的小伙伴。 本篇文章講述下熱更新,文件指紋,壓縮知識。 webpack中的文件監(jiān)聽文件監(jiān)聽是在發(fā)現(xiàn)源碼發(fā)生變化時,自動重新構建新的輸出文件webpack開啟監(jiān)聽模式,有兩種1.啟動webpack命令,帶上--watch參數(shù)。 缺點:需要每次手動刷新瀏覽器"scripts": { "build": "webpack", "watch": "webpack --watch"},
2.在配置webpack.config.js中配置watch:true。 原理:輪訓判斷文件最后編輯時間是否變化// webpack.config.jsmodule.exports = { // 默認false,就是不開啟 watch: true, // 只有開啟監(jiān)聽模式,watchOptions才有意義 watchOptions:{ // 默認為空,不監(jiān)聽的文件或者文件夾,支持正則匹配 ignored: /node_modules/, // 監(jiān)聽到變化發(fā)生后會等300ms再去執(zhí)行,默認300ms aggregateTimeout:300, // 判斷文件是否發(fā)生變化是通過不停詢問系統(tǒng)指定文件有么有變化實現(xiàn),默認1000ms poll:1000 }}
webpack-dev-server熱更新1.安裝webpack-dev-server npm i webpack-dev-server -D
2.在package.json中配置npm scripts "scripts": { "dev": "webpack-dev-server --open" // --open是自動打開瀏覽器 },
3.在webpack.config.js中配置webpack-dev-server的plugin const webpack = require('webpack'); module.exports = { // 以上省略 plugins:[ new webpack.HotModuleReplacementPlugin() ], devServer:{ contentBase:'./dist', hot: true } }
4.運行:npm run dev。自動打開瀏覽器。 5.修改代碼,保存,瀏覽器自動刷新。 熱更新原理分析從右圖看,分兩步,一步是啟動階段,第二步是熱更新階段1.啟動階段 1 -> 2 -> A -> B 文件經webpack compile將js編譯打包bundle.js 利用Bundle server 可以直接提供在線訪問,就是localhost:8080/index.html2.熱更新階段 當修改文件后,也經過webpack complie將js編譯打包成bundle.js 利用HMR Server 將熱更新的文件輸出給HMR Runtime HMR Runtime 將bundle.js注入到瀏覽器,更新文件的變化。熱更新有最核心的是 HMR Server 和 HMR runtime。 HMR Server 是服務端,用來將變化的 js 模塊通過 websocket 的消息通知給瀏覽器端。 HMR Runtime是瀏覽器端,用于接受 HMR Server 傳遞的模塊數(shù)據,瀏覽器端可以看到 .hot-update.json 的文件過來。HotModuleReplacementPlugin webpack 構建出來的 bundle.js 本身是不具備熱更新的能力的 HotModuleReplacementPlugin 的作用就是將 HMR runtime 注入到 bundle.js,使得bundle.js可以和HMR server建立websocket的通信連接webpack-dev-server和hot-module-replacement-plugin之間的關系。 webpack-dev-server(WDS)的功能提供 bundle server的能力,就是生成的 bundle.js 文件可以通過 localhost://xxx 的方式去訪問,另外 WDS 也提供 livereload(瀏覽器的自動刷新)。 hot-module-replacement-plugin 的作用是提供 HMR 的 runtime,并且將 runtime 注入到 bundle.js 代碼里面去。一旦磁盤里面的文件修改,那么 HMR server 會將有修改的 js module 信息發(fā)送給 HMR runtime,然后 HMR runtime 去局部更新頁面的代碼。因此這種方式可以不用刷新瀏覽器。 簡單來說就是:hot-module-replacement-plugin 包給 webpack-dev-server 提供了熱更新的能力。另一種熱更新:webpack-dev-middleware 將webpack輸出的文件傳輸給服務器.文件指紋Hash:和整個項目的構建相關,只要項目文件有修改,整個項目構建的hash值就會更改Chunkhash:和webpack打包的chunk有關,不同的entry會生成不同的chunkhash值Contenthash:根據文件內容來定義hash,文件內容不變,則contenthash不變js的文件指紋設置設置output的filename.使用[chunkhash]// webpack.config.js module.exports = { entry:{ app:'./src/app.js', search:'./src/search.js', }, output:{ path:__dirname+"/dist", filename:'[name][chunkhash:8].js' } }
css的文件指紋設置 設置MiniCssExtractPlugin的filename,使用[contenthash]MiniCssExtractPlugin將css從js中抽離出來單獨的css文件安裝MiniCssExtractPluginMiniCssExtractPlugin.loader 和style-loader是互斥的,不能共用npm i mini-css-extract-plugin -D
// webpack.config.js module.exports = { entry:{ app:'./src/app.js', search:'./src/search.js', }, output:{ path:__dirname+"/dist", filename:'[name][chunkhash:8].js' }, module:{ rules:[{ test:/\.css/, use:[ MiniCssExtractPlugin.loader, 'css-loader' ] }] }, plugins:[ new MiniCssExtractPlugin({ filename:'[name][contenthash:8].css' }) ] }
設置圖片的文件指紋設置設置file-loader的name,使用[hash]// webpack.config.js module.exports = { entry:{ app:'./src/app.js', search:'./src/search.js', }, output:{ path:__dirname+"/dist", filename:'[name][chunkhash:8].js' }, module:{ rules:[{ test:/\.(png|jpg|jpeg|gif)$/, use:[{ loader:'file-loader', options:{ name:'img/[name][hash:8].[ext]' } }] }] } }
bundle,chunk和modulebundle:打包最終生成的文件chunk:每個chunk是由多個module組成,可以通過代碼分割成多個chunk。module:webpack中的模塊(js、css、圖片等等)代碼壓縮js壓縮webpack內置了uglifyjs-webpack-plugincss文件壓縮使用optimize-css-assets-webpack-plugin,同時使用cssnano(預處理器)安裝npm i optimize-css-assets-webpack-plugin cssnano -D
使用 // webpack.config.js module.exports = { entry:{ app:'./src/app.js', search:'./src/search.js', }, output:{ path:__dirname+"/dist", filename:'[name][chunkhash:8].js' }, plugins:[ new OptimizeCSSAssetsPlugin({ assetNameRegExp:/\.css$/g, cssProcessor:require('cssnano') }) ] }
html文件壓縮設置html-webpack-plugin,設置壓縮參數(shù)安裝npm i html-webpack-plugin -D
使用 // webpack.config.js module.exports = { entry:{ app:'./src/app.js', search:'./src/search.js', }, output:{ path:__dirname+"/dist", filename:'[name][chunkhash:8].js' }, plugins:[ new HtmlWebpackPlugin({ template:path.join(__dirname,'src/search.html'), filename:'search.html', chunks:['search'], inject:true, minify:{ html5:true, collapseWhitespace:true, preserveLineBreaks:false, minifyCss:true, minifyJs:true, removeComments:false } }) ] }
|