摘要:配置如上圖測試用例所示,由于這個插件默認使用了來作優化,所以它不僅壓縮了代碼刪掉了代碼中無用的注釋還去除了冗余的優化了的書寫順序,優化了你的代碼。
webpack基本使用
// webpack4中除了正常安裝webpack之外,需要再多帶帶安一個webpack-cli npm i webpack webpack-cli -D基本命令行
webpack
直接輸入webpack,默認執行: webpack.config.js or webpackfile.js文件;
如果想自定義文件名,運行:webpack --config webpack.conf.dev.js
// ESmodule export default function(a,b){ return a+b } import sum from "./sum" // common.js規范 module.exports = function(a,b){ return a-b } var minus = require("./minus") // AMD規范,多了兩個bundle,異步加載 //amd規范 define(function(require, factory) { "use strict"; return function(a,b){ return a*b } }); require(["./muti"],function(muti){ console.log("muti,23,24="+muti(23,24)) }) console.log("sum,23,24="+sum(23,24)) console.log("minus,23,24="+minus(23,24))編譯 ES 6/7
安裝babel-loader, babel-core, babel-preset-env
npm install --save-dev babel-loader babel-core babel-preset-env
babel-loader:在import或加載模塊時,對es6代碼進行預處理,es6語法轉化為es5語法。
babel-core:允許我們去調用babel的api,可以將js代碼分析成ast(抽象語法樹),方便各個插件分析語法進行相應的處理.
babel-preset-env:為了告訴babel只編譯批準的內容,相當于babel-preset-es2015, es2016, es2017及最新版本。通過它可以使用最新的js語法。
配置webpack.config.js
module.exports = { entry:{ app:"./app.js" }, output:{ filename:"[name].[hash:5].js" }, module:{ rules:[ { test:/.js$/, use:{ loader:"babel-loader", options:{ presets:[ // 最新的版本 ["@babel/preset-env",{ targets:{// 支持目標,數據來源于‘can i use’網站 browsers:["> 1%","last 2 versions"] //chrome:"52" } }] ] } }, //排除相關文件 exclude:"/node_modules/" } ] } }
其中,exclude是定義不希望babel處理的文件。targets是presets的一些預設選項,這里表示將js用于瀏覽器,只確保占比大于1%的瀏覽器的特性,主流瀏覽器的最新兩個主版本。
更多與配置有關的信息,可以參考:
babel env preset設置,
browserlist預設置
由于babel-preset配置選項較多,我們一般可以在根目錄下建立.babelrc文件,專門用來放置babel preset配置,這是一個json文件。可以將上述配置修改如下:
//.bablerc文件 { "presets": [ ["env",{ "targets": { "browsers": ["> 1%", "last 2 versions"] } }] ] } //原webpack.config.js文件 module: { rules: [ { test: /.js$/, use: { loader: "babel-loader" }, exclude: "/node_modules/" } ] }babel-polifill
在上面的babel配置中,babel只是將一些es6,es7-8的語法轉換成符合目標的js代碼,但是如果我們使用一些特性或方法,比如Generator, Set, 或者一些方法。babel并不能轉換為低版本瀏覽器識別的代碼。這時就需要babel-polifill。
簡單的說,polifill就是一個墊片,提供了一些低版本es標準對高級特性的實現。使用polifill的方法如下:
npm install --save babel-polifill
然后在應用入口引入polifill,要確保它在任何其他代碼/依賴聲明前被調用。
//CommonJS module require("babel-polyfill"); //es module import "babel-polifill";
在webpack.config.js中,將babel-polifill加入entry數組中:
entry: ["babel-polifill", "./app.js"]
相比于runtime-transform,polifill用于應用開發中。會添加相應變量到全局,所以會污染全局變量。
更多配置參考:babel-polifill
完整代碼如下:
const path = require("path"); module.exports = { //entry為入口,webpack從這里開始編譯 entry: [ "babel-polyfill", path.join(__dirname, "./src/index.js") ], //output為輸出 path代表路徑 filename代表文件名稱 output: { path: path.join(__dirname, "./bundle"), filename: "bundle.js" }, //module是配置所有模塊要經過什么處理 //test:處理什么類型的文件,use:用什么,include:處理這里的,exclude:不處理這里的 module: { rules: [ { test: /.js$/, use: ["babel-loader"], include: path.join(__dirname , "src"), exclude: /node_modules/ } ] }, };runtime-transform插件
runtime transform也是一個插件,它與polifill有些類似,但它不污染全局變量,所以經常用于框架開發。
安裝:
*npm install --save-dev babel-plugin-transform-runtime
npm install --save babel-runtime*
用法:
將下面內容添加到.bablerc文件中
{ "plugins": ["transform-runtime"] }
更多配置參考:bable-runtime-transform插件
使用 loader 處理 CSS1 . 安裝處理 css 相關 loader
// css-loader讓你能import css , style-loader能將css以style的形式插入 $ npm install --save-dev css-loader style-loader
module.exports = { plugins: [require("autoprefixer")] // 引用該插件即可了 }
然后在webpack里配置postcss-loader
module.exports = { module: { rules: [ { test: /.css$/, use: ["style-loader", "css-loader", "postcss-loader"] } ] } }
2 . 安裝 less 相關
npm install --save-dev less less-loader
3 . 添加CSS3前綴
通過postcss中的autoprefixer可以實現將CSS3中的一些需要兼容寫法的屬性添加響應的前綴,這樣省去我們不少的時間
npm i postcss-loader autoprefixer -D
創建 postcss.config.js 加入以下代碼
module.exports = { plugins: { "postcss-cssnext": {} } }
4 . 實現
src/app.css
body { background: pink; }
src/app.js
import css from "./app.css"; console.log("hello world");
// 處理順序從右到左 less -> postcss -> css -> style { test: /.css$/, use: [ "style-loader", "css-loader" ] }
5.用 mini-css-extract-plugin 把 CSS 分離成文件
npm install --save-dev mini-css-extract-plugin
rules: [ { test: /.css$/, use: [MiniCssExtractPlugin.loader, "css-loader"] } ] new MiniCssExtractPlugin({ filename: "[name].css",// 指定打包后的css chunkFilename: "[id].css" }),
6.壓縮與優化
打包 css 之后查看源碼,我們發現它并沒有幫我們做代碼壓縮,這時候需要使用 optimize-css-assets-webpack-plugin 這個插件,它不僅能幫你壓縮 css 還能優化你的代碼。
npm install --save-dev optimize-css-assets-webpack-plugin
const optimizeCss = require("optimize-css-assets-webpack-plugin"); //配置 optimization: { minimizer: [new OptimizeCSSAssetsPlugin()]; }
如上圖測試用例所示,由于optimize-css-assets-webpack-plugin這個插件默認使用了 cssnano 來作 css 優化,
所以它不僅壓縮了代碼、刪掉了代碼中無用的注釋、還去除了冗余的 css、優化了 css 的書寫順序,優化了你的代碼 margin: 10px 20px 10px 20px; =>margin:10px 20px;。同時大大減小了你 css 的文件大小。更多優化的細節見文檔。
安裝插件npm install --save-dev html-webpack-plugin 配置 webpack.config.js
npm install --save-dev html-webpack-plugin
const htmlWebpackPlugin = require("html-webpack-plugin"); ... plugins: [ new htmlWebpackPlugin({ filename: "index.html", //打包后的文件名 template: path.join(__dirname , "./src/index.html"), // 用哪個html作為模板,在src目錄下創建一個index.html頁面當做模板來用 hash: true, // 會在打包好的bundle.js后面加上hash串 }) ],
如果需要多頁面開發,可以這樣寫:
let path = require("path"); let HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = { // 多頁面開發,怎么配置多頁面 entry: { index: "./src/index.js", login: "./src/login.js" }, // 出口文件 output: { filename: "[name].js", path: path.resolve("dist") }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", filename: "index.html", chunks: ["index"] // 對應關系,index.js對應的是index.html }), new HtmlWebpackPlugin({ template: "./src/login.html", filename: "login.html", chunks: ["login"] // 對應關系,login.js對應的是login.html }) ] }
html-webpack-plugin用法全解
清理打包文件插件$ npm i clean-webpack-plugin --save-dev
const CleanWebpackPlugin = require("clean-webpack-plugin"); ... plugins: [ ... new CleanWebpackPlugin(["bundle"]) //傳入清楚路徑 ]提取公共代碼 原因和優勢
原因
1.相同的資源被重復的加載,浪費用戶的流量和服務器的成本;
2.每個頁面需要加載的資源太大,導致網頁首屏加載緩慢,影響用戶體驗。
優點
1.減少網絡傳輸流量,降低服務器成本;
2.雖然用戶第一次打開網站的速度得不到優化,但之后訪問其它頁面的速度將大大提升。
在webpack4之前,提取公共代碼都是通過一個叫CommonsChunkPlugin的插件來辦到的。到了4以后,內置了一個一模一樣的功能,而且起了一個好聽的名字叫“優化”
下面我們就來看看如何提取公共代碼
// 假設a.js和b.js都同時引入了jquery.js和一個寫好的utils.js // a.js和b.js import $ from "jquery"; import {sum} from "utils";
那么他們兩個js中其中公共部分的代碼就是jquery和utils里的代碼了
可以針對第三方插件和寫好的公共文件
module.exports = { entry: { a: "./src/a.js", b: "./src/b.js" }, output: { filename: "[name].js", path: path.resolve("dust") }, // 提取公共代碼 + optimization: { splitChunks: { cacheGroups: { vendor: { // 抽離第三方插件 test: /node_modules/, // 指定是node_modules下的第三方包 chunks: "initial", name: "vendor", // 打包后的文件名,任意命名 // 設置優先級,防止和自定義的公共代碼提取時被覆蓋,不進行打包 priority: 10 }, utils: { // 抽離自己寫的公共代碼,utils這個名字可以隨意起 chunks: "initial", name: "utils", // 任意命名 minSize: 0 // 只要超出0字節就生成一個新包 } } } + }, plugins: [ new HtmlWebpackPlugin({ filename: "a.html", template: "./src/index.html", // 以index.html為模板 + chunks: ["vendor", "a"] }), new HtmlWebpackPlugin({ filename: "b.html", template: "./src/index.html", // 以index.html為模板 + chunks: ["vendor", "b"] }) ] }
通過以上配置,可以把引入到a.js和b.js中的這部分公共代碼提取出來,如下圖所示
webpack-dev-server配置安裝 webpack-dev-server
npm install --save-dev webpack-dev-server
webpack.config.js 添加配置
... devServer: { contentBase: path.join(__dirname, "bundle"), //啟動路徑 host:"localhost", //域名,默認是localhost port: 8018, //端口號 open: true, //自動打開瀏覽器 hot: true //開啟熱更新 }
當然在npm run dev命令下,打包的文件存在于內存中,并不會產生在dist目錄下
熱更新和自動刷新的區別
配置devServer的時候,如果hot為true,就代表開啟了熱更新
But這并沒那么簡單,因為熱更新還需要配置一個webpack自帶的插件并且還要在主要js文件里檢查是否有module.hot
下面就讓我們直接看下代碼是如何實現的
// webpack.config.js let webpack = require("webpack"); module.exports = { plugins: [ // 熱更新,熱更新不是刷新 new webpack.HotModuleReplacementPlugin() ], devServer: { contentBase: "./dist", hot: true, port: 3000 } } // 此時還沒完雖然配置了插件和開啟了熱更新,但實際上并不會生效 // index.js let a = "hello world"; document.body.innerHTML = a; console.log("這是webpack打包的入口文件"); // 還需要在主要的js文件里寫入下面這段代碼 if (module.hot) { // 實現熱更新 module.hot.accept(); }編譯圖片
file-loader
對一些對象作為文件來處理,然后可以返回它的URL。
$ npm install --save-dev file-loader
test: /.(gif|png|jpe?g|svg)$/i, use: [ { loader: "file-loader", options: { name: "[name].[ext]", // 文件名和擴展名 outputPath: "images/" } },
url-loader
npm i file-loader url-loader -D
module.exports = { module: { rules: [ { test: /.css$/, use: ExtractTextWebpackPlugin.extract({ use: "css-loader", publicPath: "../" }) }, { test: /.(jpe?g|png|gif)$/, use: [ { loader: "url-loader", options: { limit: 8192, // 小于8k的圖片自動轉成base64格式,并且不會存在實體圖片 outputPath: "images/" // 圖片打包后存放的目錄 } } ] } ] } }
解析 html 代碼里面 img 的標簽
html-loader: html 變成導出成字符串的過程中,還能進行壓縮處理(minimized)
$ npm install --save-dev html-loader
... { test: /.(gif|png|jpe?g|svg)$/i, use: [ { loader: "file-loader", options: { name: "[name].[ext]", outputPath: "images/" } }, ] }, // 下面幾行才是 html-loader 的配置內容 { test: /.html$/, use: [ { loader: "html-loader", options: { minimize: true } }], } ...
壓縮圖片
image-webpack-loader:壓縮圖片文件
$ npm install image-webpack-loader --save-dev
{ test: /.(gif|png|jpe?g|svg)$/i, use: [ { loader: "file-loader", options: { name: "[name].[ext]", outputPath: "images/" } }, { loader: "image-webpack-loader", options: { bypassOnDebug: true, } } ] }, { test: /.html$/, use: [ { loader: "html-loader", options: { minimize: true } }], }resolve解析
在webpack的配置中,resolve我們常用來配置別名和省略后綴名
module.exports = { resolve: { // 別名 alias: { $: "./src/jquery.js" }, // 省略后綴 extensions: [".js", ".json", ".css"] }, }打包速度
webpack 4 在項目中實際測了下,普遍能提高 20%~30%的打包速度。
首先你需要知道你目前打包慢,是慢在哪里。
我們可以用 speed-measure-webpack-plugin 這個插件,它能監控 webpack 每一步操作的耗時。如下圖:
可以看出其實大部分打包花費的時間是在Uglifyjs壓縮代碼。和前面的提升熱更新的切入點差不多,查看source map的正確與否,exclude/include的正確使用等等。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97110.html
摘要:引言最近在學習,發現好多知識點,之前一點都沒有接觸過,如等等。使用本地安裝,會存于文件夾內與屬性內,更方便項目文件遷移以及協同開發等情況。 引言 最近在學習webpack,發現好多知識點,之前一點都沒有接觸過,如babel、core-js、browserslist等等。以前習慣了使用cli構建項目,很多東西不用考慮,拿來就用,這樣的碼農是不會有能力提升的,必須了解更多的知識點,才能成為...
摘要:運行該語句會執行如下步驟使用進行文件壓縮。設置環境變量,觸發某些包,以不同的方式進行編譯。在原始的源碼中執行查找和替換操作。等同于表示任何出現的地方都會被替換為。提供函數用來合并配置對象當文件小于限制,會返回。 選項 1.devtool:通過在瀏覽器調試工具(browser devtools)中添加元信息(meta info)增強調試。 2.resolve.alias:創建 impor...
摘要:新搭建的個人博客,本文地址學習筆記環境搭建本文的書寫環境為,之后會補充下的差異創建學習目錄初始化項目根據相關提示完善信息,入口文件安裝相關包,并且使用也就是支持,需要包,因為我之前做個一些相關項目,所以部分包已經全局安裝,比如等等,大家 新搭建的個人博客,本文地址:React學習筆記1:環境搭建 本文的書寫環境為mac,之后會補充windows下的差異 1、創建學習目錄 mkdir l...
摘要:前言在上一篇文章中我介紹了學習前的準備工作,下面開始的學習。目標一般我們接觸到的關于的文章,都是以解讀官方文檔為主,而且是針對單頁面項目的應用。我先在假設要做一個多頁面應用,該如何去通過打包。 前言 在上一篇文章中我介紹了學習webpack前的準備工作,下面開始webpack的學習。 *創建webpack-demo文件夾 $ mkdir webpack-demo $ cd webpac...
摘要:前言在上一篇文章中我介紹了學習前的準備工作,下面開始的學習。目標一般我們接觸到的關于的文章,都是以解讀官方文檔為主,而且是針對單頁面項目的應用。我先在假設要做一個多頁面應用,該如何去通過打包。 前言 在上一篇文章中我介紹了學習webpack前的準備工作,下面開始webpack的學習。 *創建webpack-demo文件夾 $ mkdir webpack-demo $ cd webpac...
閱讀 1537·2023-04-25 18:56
閱讀 1484·2021-09-29 09:34
閱讀 1710·2021-09-22 15:51
閱讀 3483·2021-09-14 18:03
閱讀 1160·2021-07-23 17:54
閱讀 2018·2019-08-29 18:38
閱讀 2900·2019-08-29 12:38
閱讀 610·2019-08-26 13:41