溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

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

發(fā)布時(shí)間:2020-07-14 14:49:27 來源:網(wǎng)絡(luò) 閱讀:2924 作者:陳學(xué)輝 欄目:web開發(fā)

在開發(fā)的時(shí)候會(huì)時(shí)常用到第三方的庫或者框架,比如耳熟能詳?shù)?code>jquery。借助它們能提高開發(fā)效率,但是如何在webpack中使用呢。這篇文章介紹兩個(gè)東西,如何使用第三方庫以及如何提取第三方庫。

使用第三方庫

1、在入口文件當(dāng)中直接導(dǎo)入

安裝jQuery

npm i jquery -S

目錄結(jié)構(gòu)如圖:
Webpack 4.X 從入門到精通 - 第三方庫(六)

package.json內(nèi)容如下:

{
  "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內(nèi)容如下:

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:'陳學(xué)輝',
            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內(nèi)容如下:

<!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內(nèi)容如下:

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

index.js內(nèi)容如下:

import '../css/index.css';
import $ from 'jquery'; //引入jquery

$('ul li:last-child').css('background','green');

npm run build后打開頁面會(huì)看到最后一個(gè)li標(biāo)簽有了一個(gè)綠色的背景。如果你打開index.js文件后會(huì)發(fā)現(xiàn)jquery的代碼也被壓縮了進(jìn)來。

這是引入第三方庫的一種方式,但這種方式會(huì)有一個(gè)問題,如果我僅僅只是引入而并沒有使用,在打包的時(shí)候依然會(huì)把第三方庫打包進(jìn)來。如果你的代碼由第二位同學(xué)接手,他為了避免出錯(cuò)并不會(huì)直接把import刪掉,而會(huì)把使用這個(gè)庫的代碼刪掉,假如這個(gè)庫的代碼只剩下了import,那打包后的文件體積依然很大,便是一種浪費(fèi)

修改index.js如下:

import '../css/index.css';
import $ from 'jquery'; //引入jquery

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

npm run build后打開index.js,你會(huì)發(fā)現(xiàn)jquery的代碼依然被打包了

2、webpack.ProvidePlugin

  1. 自動(dòng)加載模塊,而不必用import或require
  2. 如果加載的模塊沒有使用,則不會(huì)被打包
  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身上的一個(gè)插件

module.exports={
    entry:'./src/js/index.js',
    output:{
        path:path.resolve(__dirname,'dist'),
        filename:'js/index.js'
    },
    plugins:[
        new HtmlWebpackPlugin({
            title:'陳學(xué)輝',
            template:'./src/template.html',
            filename:'index.html'
        }),
        new MiniCssExtractPlugin({
            filename:'css/index.css'
        }),
        new webpack.ProvidePlugin({ //它是一個(gè)插件,所以需要按插件的用法new一個(gè)
            $:'jquery', //接收名字:模塊名
        }),
    ],
    devServer:{
        host:'localhost',
        port:1573,
        open:true
    }

    ...

修改index.js內(nèi)容如下:

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

npm run build后打開index.html可以看到一樣的效果
再次修改index.js內(nèi)容如下:

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

npm run build后打開index.js可以看到jquery的內(nèi)容并沒有被打包進(jìn)來。這種方式比上一種方式就智能的很,會(huì)根據(jù)你是否使用庫而決定是否打包。

提取第三方庫

對(duì)于提取第三方庫有兩種形式,第一種是在一個(gè)頁面里引入了多個(gè)庫,最終所有的代碼都會(huì)打包到一個(gè)文件里,如果引入的庫非常之多,那文件會(huì)非常大,不利于加載。第二種就是在多個(gè)頁面里都引入了同一個(gè)庫,那會(huì)把這個(gè)庫打包多次,造成資源浪費(fèi)。所以就需要把第三方庫單獨(dú)提取出來,優(yōu)化資源。

1、一個(gè)頁面引入多個(gè)庫

接著上面的代碼,再添加一個(gè)庫,這個(gè)庫的名字叫underscore,它里面封裝了很多關(guān)于數(shù)組與對(duì)象的方法,我拿其中一個(gè)方法進(jìn)行演示

npm i underscore -S

修改webpack.config.js里的插件:

new webpack.ProvidePlugin({ //它是一個(gè)插件,所以需要按插件的用法new一個(gè)
    $:'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方法,此方法為循環(huán)數(shù)組里每一位數(shù)據(jù),并把每位數(shù)據(jù)都乘以3,返回新數(shù)組

npm run build后打開index.html能看到控制臺(tái)有輸出了[3, 6, 9],說明underscore庫已經(jīng)被打包到index.js里??梢苑謩e注釋jqueryunderscore的使用代碼,npm run build后對(duì)比index.js的大小就能看出區(qū)別

提取第三方庫

optimization 優(yōu)化

  • splitChunks 緩存組
  • 能被提取的條件
    1、模塊被重復(fù)引用或者來自node_modules中的模塊
    2、模塊壓縮前至少有30kb
    3、按需(異步)請(qǐng)求的數(shù)量小于5個(gè)
    4、初始化加載時(shí),并行請(qǐng)求數(shù)量小于等于3

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

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

npm run build之后有兩個(gè)文件,index.jsvender.js,其中vender.js里放的就是jqueryunderscore的代碼。

說明:
optimizationwebpack的另一個(gè)配置參數(shù),它的意義在于優(yōu)化。里面的splitChunks參數(shù)值用來放提取第三方庫的一些設(shè)置,比如:要提取同步還是異步的模塊,這個(gè)模塊的引用次數(shù)達(dá)到多少能被提取等。但是放在這里的參數(shù)會(huì)對(duì)所有要提取的模塊生效。如果不同的公共模塊要不同的對(duì)待的話就需要在splitChunks.cacheGroups里去定義
cacheGroups翻譯過來就是緩存組,可以理解為針對(duì)不同的要提取的公共部分進(jìn)行單獨(dú)設(shè)置,比如上面例子中要針對(duì)js進(jìn)行提取,所以就起了個(gè)名字叫commonjs,那它是個(gè)對(duì)象,里面放的就是單獨(dú)的配置參數(shù)

詳細(xì)說明請(qǐng)參考:https://webpack.js.org/plugins/split-chunks-plugin/

2、多個(gè)頁面同時(shí)引入一個(gè)庫

還有另一種形式,像jquery,它在多個(gè)頁面里都被引入了,因?yàn)榇虬荒茚槍?duì)單頁面進(jìn)行打包,那就會(huì)在每個(gè)頁面里都打包一次jquery,造成資源浪費(fèi)

新建a.jsb.js,內(nèi)容如下:
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'));

可以看到兩個(gè)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:[
        //需要兩個(gè)頁面,所以寫兩個(gè)new HtmlWebpackPlugin
        /*new HtmlWebpackPlugin({
            title:'陳學(xué)輝',
            template:'./src/template.html',
            filename:'index.html'
        }),*/
        new HtmlWebpackPlugin({
            title:'a頁面',
            template:'./src/template.html',
            filename:'a.html',
            chunks:['a'],   //引入對(duì)應(yīng)的js,需要用到chunks
        }),
        new HtmlWebpackPlugin({
            title:'b頁面',
            template:'./src/template.html',
            filename:'b.html',
            chunks:['b'],
        }),
        new MiniCssExtractPlugin({
            filename:'css/index.css'
        }),

        //jquery已經(jīng)單獨(dú)在a與b文件里引入了,這里就不需要了
        /*new webpack.ProvidePlugin({
            $:'jquery', //接收名字:模塊名
            _:'underscore'
        }),*/
    ],
    devServer:{
        //...
    },
    module:{
        //...
    },
}

npm run build后結(jié)構(gòu)如下圖,在dist下的js目錄里分別看一下a.jsb.js的大小,這兩個(gè)文件里都包含了jquery。再分別打開a.htmlb.html頁面正常運(yùn)行,控制臺(tái)里打印出了想要的內(nèi)容。
Webpack 4.X 從入門到精通 - 第三方庫(六)
這樣就是一種浪費(fèi)了,我們完全可以把jquery單獨(dú)提取出來,在兩個(gè)頁面里分別引入。如果是多個(gè)頁面都引入同一個(gè)庫,那提取公共庫就會(huì)是剛需。

修改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后結(jié)構(gòu)目錄如下圖,再次看一下a.jsb.js的大小,相比前面是否小了很多?公共的jquery已經(jīng)被提取出來了并放到了vender.js中。查看a.htmlb.html頁面源碼發(fā)現(xiàn)vender.js已經(jīng)被引入了。
Webpack 4.X 從入門到精通 - 第三方庫(六)

至此Webpack 4.X的內(nèi)容已經(jīng)全部寫完~

×××:https://pan.baidu.com/s/1h9PSkbkrhQ1IX7rzOQqk9Q

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI