Webpack 4.X 從入門到精通 - 第三方庫(六)

來源:互聯網
上載者:User

標籤:split   mode   run   開啟   多少   red   group   meta   oca   

在開發的時候會時常用到第三方的庫或者架構,比如耳熟能詳的 jquery。藉助它們能提高開發效率,但是如何在 webpack中使用呢。這篇文章介紹兩個東西,如何使用第三方庫以及如何提取第三方庫。

使用第三方庫1、在入口檔案當中直接匯入

安裝jQuery

npm i jquery -S

目錄結構

package.json內容如下:

{  "name": "webpack-demo",  "version": "1.0.0",  "description": "",  "main": "webpack.config.js",  "scripts": {    "build": "webpack --mode production",    "dev": "webpack-dev-server --mode development"  },  "keywords": [],  "author": "",  "license": "ISC",  "devDependencies": {    "css-loader": "^1.0.0",    "file-loader": "^1.1.11",    "html-webpack-plugin": "^3.2.0",    "mini-css-extract-plugin": "^0.4.1",    "url-loader": "^1.0.1",    "webpack": "^4.16.3",    "webpack-cli": "^3.1.0",    "webpack-dev-server": "^3.1.5"  },  "dependencies": {    "jquery": "^3.3.1"  }}

webpack.config.js內容如下:

const path=require(‘path‘);const HtmlWebpackPlugin=require(‘html-webpack-plugin‘);const MiniCssExtractPlugin=require(‘mini-css-extract-plugin‘);module.exports={    entry:‘./src/js/index.js‘,    output:{        path:path.resolve(__dirname,‘dist‘),        filename:‘js/index.js‘    },    plugins:[        new HtmlWebpackPlugin({            title:‘陳學輝‘,            template:‘./src/template.html‘,            filename:‘index.html‘        }),        new MiniCssExtractPlugin({            filename:‘css/index.css‘        }),    ],    devServer:{        host:‘localhost‘,        port:1573,        open:true    },    module:{        rules:[            {                test:/\.css$/,                use:[                    {                        loader:MiniCssExtractPlugin.loader,                        options:{                            publicPath:‘../‘                        }                    },                    ‘css-loader‘,                ]            },            {                test:/\.(jpg|png|gif)$/,                use:[                    {                        loader:‘url-loader‘,                        options:{                            limit:5 * 1024,                            outputPath:‘images‘                        }                    }                ]            }        ]    }}

templage.html內容如下:

<!DOCTYPE html><html>    <head>        <meta charset="UTF-8">        <title><%= htmlWebpackPlugin.options.title %></title>    </head>    <body>        <div id="box">            <p>這是內建的div</p>            <ul>                <li><a href="#">red</a></li>                <li><a href="#">green</a></li>                <li><a href="#">blue</a></li>            </ul>        </div>    </body></html>

index.css內容如下:

#box{    width: 800px;    height: 500px;    border: 5px solid #999;    color: #00f;    background: url(../images/img_01.jpg);}

index.js內容如下:

import ‘../css/index.css‘;import $ from ‘jquery‘; //引入jquery$(‘ul li:last-child‘).css(‘background‘,‘green‘);

npm run build後開啟頁面會看到最後一個li標籤有了一個綠色的背景。如果你開啟index.js檔案後會發現jquery的代碼也被壓縮了進來。

這是引入第三方庫的一種方式,但這種方式會有一個問題,如果我僅僅只是引入而並沒有使用,在打包的時候依然會把第三方庫打包進來。如果你的代碼由第二位同學接手,他為了避免出錯並不會直接把import刪掉,而會把使用這個庫的代碼刪掉,假如這個庫的代碼只剩下了import,那打包後的檔案體積依然很大,便是一種浪費

修改index.js如下:

import ‘../css/index.css‘;import $ from ‘jquery‘; //引入jquery//$(‘ul li:last-child‘).css(‘background‘,‘green‘);

npm run build後開啟index.js,你會發現jquery的代碼依然被打包了

2、webpack.ProvidePlugin
  1. 自動載入模組,而不必用import或require
  2. 如果載入的模組沒有使用,則不會被打包
  3. 載入的模組為全域模組,在全域都可以使用

修改webpack.config.js如下:

const path=require(‘path‘);const HtmlWebpackPlugin=require(‘html-webpack-plugin‘);const MiniCssExtractPlugin=require(‘mini-css-extract-plugin‘);const webpack=require(‘webpack‘);   //引入webpack模組,ProvidePlugin是webpack身上的一個外掛程式module.exports={    entry:‘./src/js/index.js‘,    output:{        path:path.resolve(__dirname,‘dist‘),        filename:‘js/index.js‘    },    plugins:[        new HtmlWebpackPlugin({            title:‘陳學輝‘,            template:‘./src/template.html‘,            filename:‘index.html‘        }),        new MiniCssExtractPlugin({            filename:‘css/index.css‘        }),        new webpack.ProvidePlugin({ //它是一個外掛程式,所以需要按外掛程式的用法new一個            $:‘jquery‘, //接收名字:模組名        }),    ],    devServer:{        host:‘localhost‘,        port:1573,        open:true    }    ...

修改index.js內容如下:

import ‘../css/index.css‘;$(‘ul li:last-child‘).css(‘background‘,‘green‘);

npm run build後開啟index.html可以看到一樣的效果
再次修改index.js內容如下:

import ‘../css/index.css‘;//$(‘ul li:last-child‘).css(‘background‘,‘green‘);

npm run build後開啟index.js可以看到jquery的內容並沒有被打包進來。這種方式比上一種方式就智能的很,會根據你是否使用庫而決定是否打包。

提取第三方庫

對於提取第三方庫有兩種形式,第一種是在一個頁面裡引入了多個庫,最終所有的代碼都會打包到一個檔案裡,如果引入的庫非常之多,那檔案會非常大,不利於載入。第二種就是在多個頁面裡都引入了同一個庫,那會把這個庫打包多次,造成資源浪費。所以就需要把第三方庫單獨提取出來,最佳化資源。

1、一個頁面引入多個庫

接著上面的代碼,再添加一個庫,這個庫的名字叫underscore,它裡面封裝了很多關於數組與對象的方法,我拿其中一個方法進行示範

npm i underscore -S

修改webpack.config.js裡的外掛程式:

new webpack.ProvidePlugin({ //它是一個外掛程式,所以需要按外掛程式的用法new一個    $:‘jquery‘, //接收名字:模組名    _:‘underscore‘  //引入underscore庫}),

修改index.js如下

import ‘../css/index.css‘;$(‘ul li:last-child‘).css(‘background‘,‘green‘);console.log(_([1,2,3]).map(v=>v*3));    //使用underscore庫裡的map方法,此方法為迴圈數組裡每一位元據,並把每位元據都乘以3,返回新數組

npm run build後開啟index.html能看到控制台有輸出了[3, 6, 9],說明underscore庫已經被打包到index.js裡。可以分別注釋jqueryunderscore的使用代碼,npm run build後對比index.js的大小就能看出區別

提取第三方庫

optimization 最佳化

  • splitChunks 緩衝組
  • 能被提取的條件
    1、模組被重複引用或者來自node_modules中的模組
    2、模組壓縮前至少有30kb
    3、按需(非同步)請求的數量小於5個
    4、初始化載入時,並行請求數量小於等於3

修改webpack.config.js裡的moudle.exports

module.exports={    entry:{        index:‘./src/js/index.js‘,  //要把入口檔案與第三方庫分開,所以要單獨的給名字    },    output:{        path:path.resolve(__dirname,‘dist‘),        filename:‘js/[name].js‘ //以key做為輸出的名字    },    plugins:[        //...        new webpack.ProvidePlugin({            $:‘jquery‘,            _:‘underscore‘        }),    ],    devServer:{        //...    },    module:{        //...    },    optimization:{  //最佳化        splitChunks:{            cacheGroups:{//緩衝組,一個對象。它的作用在於,可以對不同的檔案做不同的處理                commonjs:{                    name:‘vender‘,      //輸出的名字(提出來的第三方庫)                    test: /\.js/,       //通過條件找到要提取的檔案                    chunks:‘initial‘    //只對入口檔案進行處理                }            }        }    }}

npm run build之後有兩個檔案,index.jsvender.js,其中vender.js裡放的就是jqueryunderscore的代碼。

說明:
optimizationwebpack的另一個配置參數,它的意義在於最佳化。裡面的splitChunks參數值用來放提取第三方庫的一些設定,比如:要提取同步還是非同步模組,這個模組的引用次數達到多少能被提取等。但是放在這裡的參數會對所有要提取的模組生效。如果不同的公用模組要不同的對待的話就需要在splitChunks.cacheGroups裡去定義
cacheGroups翻譯過來就是緩衝組,可以理解為針對不同的要提取的公用部分進行單獨設定,比如上面例子中要針對js進行提取,所以就起了個名字叫commonjs,那它是個對象,裡面放的就是單獨的配置參數

詳細說明請參考:https://webpack.js.org/plugins/split-chunks-plugin/

2、多個頁面同時引入一個庫

還有另一種形式,像jquery,它在多個頁面裡都被引入了,因為打包只能針對單頁面進行打包,那就會在每個頁面裡都打包一次jquery,造成資源浪費

建立a.jsb.js,內容如下:
a.js

import $ from ‘jquery‘;console.log(‘這是a.js‘);console.log($(‘ul‘));

b.js

import $ from ‘jquery‘;console.log(‘這是b.js‘);console.log($(‘ul li‘));

可以看到兩個js檔案都引入了jquery檔案

修改webpack.config.js檔案的module.exports

module.exports={    entry:{        a:‘./src/js/a.js‘,        b:‘./src/js/b.js‘    },    output:{        path:path.resolve(__dirname,‘dist‘),        filename:‘js/[name].js‘    },    plugins:[        //需要兩個頁面,所以寫兩個new HtmlWebpackPlugin        /*new HtmlWebpackPlugin({            title:‘陳學輝‘,            template:‘./src/template.html‘,            filename:‘index.html‘        }),*/        new HtmlWebpackPlugin({            title:‘a頁面‘,            template:‘./src/template.html‘,            filename:‘a.html‘,            chunks:[‘a‘],   //引入對應的js,需要用到chunks        }),        new HtmlWebpackPlugin({            title:‘b頁面‘,            template:‘./src/template.html‘,            filename:‘b.html‘,            chunks:[‘b‘],        }),        new MiniCssExtractPlugin({            filename:‘css/index.css‘        }),        //jquery已經單獨在a與b檔案裡引入了,這裡就不需要了        /*new webpack.ProvidePlugin({            $:‘jquery‘, //接收名字:模組名            _:‘underscore‘        }),*/    ],    devServer:{        //...    },    module:{        //...    },}

npm run build後結構如,在dist下的js目錄裡分別看一下a.jsb.js的大小,這兩個檔案裡都包含了jquery。再分別開啟a.htmlb.html頁面正常運行,控制台裡列印出了想要的內容。

這樣就是一種浪費了,我們完全可以把jquery單獨提取出來,在兩個頁面裡分別引入。如果是多個頁面都引入同一個庫,那提取公用庫就會是剛需。

修改webpack.config.jsmodule.exports

module.exports={    entry:{        a:‘./src/js/a.js‘,        b:‘./src/js/b.js‘    },    output:{        path:path.resolve(__dirname,‘dist‘),        filename:‘js/[name].js‘ //以key做為輸出的名字    },    plugins:[        new HtmlWebpackPlugin({            title:‘a頁面‘,            template:‘./src/template.html‘,            filename:‘a.html‘,            chunks:[‘a‘,‘vender‘],  //vender為提取出的公用部分,需要在頁面裡引入        }),        new HtmlWebpackPlugin({            title:‘b頁面‘,            template:‘./src/template.html‘,            filename:‘b.html‘,            chunks:[‘b‘,‘vender‘],        }),        new MiniCssExtractPlugin({            filename:‘css/index.css‘        }),    ],    devServer:{        //...    },    module:{        //...    },    optimization:{        splitChunks:{            cacheGroups:{                common:{                    name:‘vender‘,                    test: /\.js/,                    chunks:‘initial‘                }            }        }    }}

npm run build後結構目錄如,再次看一下a.jsb.js的大小,相比前面是否小了很多?公用的jquery已經被提取出來了並放到了vender.js中。查看a.htmlb.html頁面源碼發現vender.js已經被引入了。

至此Webpack 4.X的內容已經全部寫完~

源碼下載:https://pan.baidu.com/s/1h9PSkbkrhQ1IX7rzOQqk9Q

Webpack 4.X 從入門到精通 - 第三方庫(六)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.