玖叶教程网

前端编程开发入门

Webpack 4.X 从入门到精通-第三方库(六)

在开发的时候会时常用到第三方的库或者框架,比如耳熟能详的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

  • 自动加载模块,而不必用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的内容并没有被打包进来。这种方式比上一种方式就智能的很,会根据你是否使用库而决定是否打包。

提取第三方库

对于提取第三方库有两种形式,第一种是在一个页面里引入了多个库,最终所有的代码都会打包到一个文件里,如果引入的库非常之多,那文件会非常大,不利于加载。第二种就是在多个页面里都引入了同一个库,那会把这个库打包多次,造成资源浪费。所以就需要把第三方库单独提取出来,优化资源。

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里。可以分别注释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/

2、多个页面同时引入一个库

还有另一种形式,像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

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言