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

  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

原文地址:http://blog.51cto.com/13258913/2165507

时间: 2024-10-08 22:20:50

Webpack 4.X 从入门到精通 - 第三方库(六)的相关文章

Webpack 4.X 从入门到精通 - plugin(二)

通过上一篇文章,我们明白了webpack的两个配置参数入口与出口,webpack会找到入口文件的地址,进去后一顿蹂躏,再通过你给的输出地址就把编译后的文件给你了.这篇文章接着去丰富webpack.config.js的内容,说一个参数叫plugins plugins plugins里面放的是插件,在webpack里有各式各样的插件能够帮你完成任何构建的事情.只有你想不到的,没有它做不到的.并且全世界的小伙伴们都在给webpack贡献开源的插件,所以插件的种类是非常丰富的. 插件能做什么 插件的作用

Webpack 4.X 从入门到精通 - devServer与mode(三)

上一篇文章里详细介绍了一下插件的用法,这一篇文章接着丰富module.exports里的属性.如今的前端发展已经非常迅速了,伴随而来的是开发模式的转变.现在已经不再是写个静态页面并放在浏览器里打开预览一下了.在实际的开发中会经常需要使用http服务器,比如之前的ajax,想要看到效果就必需搭建一个服务器.搭建服务器的方式有非常的多,而webpack则原生的提供服务器的支持,大家无需再去下载软件.同时它还提供了自动刷新.热更新等功能,使开发变得非常方便. devServer 安装使用 npm i

Scala入门到精通——第二十六节 Scala并发编程基础

作者:摇摆少年梦 视频地址:http://www.xuetuwuyou.com/course/12 本节主要内容 Scala并发编程简介 Scala Actor并发编程模型 react模型 Actor的几种状态 Actor深入使用解析 本节主要介绍的scala并发编程的基本思想,由于scala在2.10版本之后宣布使用akka作为其并发编程库,因此本节只进行基础性的内容介绍,后面将把重点放在akka框架的讲解上. 1. Scala并发编程简介 2003 年,Herb Sutter 在他的文章 "

Scala入门到精通——第十六节 泛型与注解

本节主要内容 泛型(Generic Type)简介 注解(Annotation)简介 注解常用场景 1. 泛型(Generic Type)简介 泛型用于指定方法或类可以接受任意类型参数,参数在实际使用时才被确定,泛型可以有效地增强程序的适用性,使用泛型可以使得类或方法具有更强的通用性.泛型的典型应用场景是集合及集中中的方法参数,可以说同java一样,scala中泛型无处不在,具体可以查看scala的api //单个泛型参数的使用情况 class Person[T](var name:T) cla

WF从入门到精通学习目录

WF从入门到精通(第一章):WF简介 WF从入门到精通(第二章):workflow运行时 WF从入门到精通(第三章):workflow实例 WF从入门到精通(第四章):活动及workflow类型介绍 WF从入门到精通(第五章):workflow跟踪 WF从入门到精通(第六章):加载和卸载实例 WF从入门到精通(第七章):基本活动的操作 WF从入门到精通(第八章):调用外部方法及工作流(一) WF从入门到精通(第八章):调用外部方法及工作流(二) WF从入门到精通(第九章):逻辑流活动 WF从入门

Charles 从入门到精通

Charles 从入门到精通 更新说明 这是一篇发过的文章,最近我进行了更新,增加了 Charles 4 的介绍,反向代理功能和设置外部代理,并且介绍了如何解决与FQ软件的冲突. 与此同时,正值 Charles 推出 4.0 版本,数码荔枝在做 Charles 优惠 30 元的特价活动(限时:2016 年 8 月 8 日 - 15 日),最终的正版价格仅为 169 元.感兴趣的可以复制如下信息查看: 淘口令:Charles 新版发布,使用¥Charles¥限时特惠购买正版(长按复制整段文案,打开

Charles从入门到精通

Charles 从入门到精通 发表于 2015-11-14 12:00 文章目录 1. 目录 2. 简介 3. 安装 Charles 4. 将 Charles 设置成系统代理 5. Charles 主界面介绍 6. 过滤网络请求 7. 截取 iPhone 上的网络封包 7.1. Charles 上的设置 7.2. iPhone 上的设置 8. 截取 Https 通讯信息 8.1. 安装证书 8.2. 截取移动设备中的 Https 通讯信息 9. 模拟慢速网络 10. 修改网络请求内容 11. 给

“H5跨平台APP开发”APICloud从入门到精通

"H5跨平台APP开发"APICloud从入门到精通 课程学习地址:http://www.xuetuwuyou.com/course/164 课程出自学途无忧网:http://www.xuetuwuyou.com 课程介绍:               一.课程使用到的软件 APICloud Studuio(或Sublime.WebStorm加上APICloud插件) Google Chrome浏览器 海马玩手机模拟器(或真机) 二.课程目的:     随着IOS.Android等原生

NHibernate从入门到精通系列

http://www.cnblogs.com/GoodHelper/archive/2011/02/17/1948744.html NHibernate从入门到精通系列(4)——持久对象的生命周期(上) 内容摘要 持久对象的状态的概念 持久对象的状态Demo 一.持久对象的状态的概念 在NHibernate中有三种状态,对它的深入理解,才能更好的理解NHibernate的运行机理,刚开始不太注意这些概念,后来发现它是重要的.对于NHibernate和SQL的关系有更好的理解:对于理解需要持久化的