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
Webpack 4.X 从入门到精通 - 第三方库(六)
原文地址:http://blog.51cto.com/13258913/2165507