您好,登錄后才能下訂單哦!
在開發的時候會時常用到第三方的庫或者框架,比如耳熟能詳的jquery
。借助它們能提高開發效率,但是如何在webpack
中使用呢。這篇文章介紹兩個東西,如何使用第三方庫以及如何提取第三方庫。
安裝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
的代碼依然被打包了
- 自動加載模塊,而不必用import或require
- 如果加載的模塊沒有使用,則不會被打包
- 加載的模塊為全局模塊,在全局都可以使用
修改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
的內容并沒有被打包進來。這種方式比上一種方式就智能的很,會根據你是否使用庫而決定是否打包。
對于提取第三方庫有兩種形式,第一種是在一個頁面里引入了多個庫,最終所有的代碼都會打包到一個文件里,如果引入的庫非常之多,那文件會非常大,不利于加載。第二種就是在多個頁面里都引入了同一個庫,那會把這個庫打包多次,造成資源浪費。所以就需要把第三方庫單獨提取出來,優化資源。
接著上面的代碼,再添加一個庫,這個庫的名字叫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
里。可以分別注釋jquery
與underscore
的使用代碼,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.js
與vender.js
,其中vender.js
里放的就是jquery
與underscore
的代碼。
說明:
optimization
是webpack
的另一個配置參數,它的意義在于優化。里面的splitChunks
參數值用來放提取第三方庫的一些設置,比如:要提取同步還是異步的模塊,這個模塊的引用次數達到多少能被提取等。但是放在這里的參數會對所有要提取的模塊生效。如果不同的公共模塊要不同的對待的話就需要在splitChunks.cacheGroups
里去定義cacheGroups
翻譯過來就是緩存組,可以理解為針對不同的要提取的公共部分進行單獨設置,比如上面例子中要針對js進行提取,所以就起了個名字叫commonjs
,那它是個對象,里面放的就是單獨的配置參數
詳細說明請參考:https://webpack.js.org/plugins/split-chunks-plugin/
還有另一種形式,像jquery
,它在多個頁面里都被引入了,因為打包只能針對單頁面進行打包,那就會在每個頁面里都打包一次jquery
,造成資源浪費
新建a.js
與b.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.js
與b.js
的大小,這兩個文件里都包含了jquery
。再分別打開a.html
與b.html
頁面正常運行,控制臺里打印出了想要的內容。
這樣就是一種浪費了,我們完全可以把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' //以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.js
與b.js
的大小,相比前面是否小了很多?公共的jquery
已經被提取出來了并放到了vender.js
中。查看a.html
與b.html
頁面源碼發現vender.js
已經被引入了。
至此Webpack 4.X
的內容已經全部寫完~
×××:https://pan.baidu.com/s/1h9PSkbkrhQ1IX7rzOQqk9Q
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。