本章节我们学习一下webpack中的babel-polyfill,libraryTarget和library,purgecss-webpack-plugin,CDN。
babel-polyfill
有些浏览器对一些es6的新特性不支持,例如promise在ie浏览器中,使用babel-polyfill就可以解决这个问题。
安装:
cnpm i babel-polyfill -S
使用方式,在入口文件引入:
//第一种
import "babel-polyfill";
//第二种
require('babel-polyfill');
这样子全局引入babel-polyfill虽然可以解决一些浏览器不兼容es6新特性的问题,但是这样子全局引入就会存在一个问题,首先引入就会导致打包之后的代码体积变大,其次是就是Chrome浏览器等都支持es6的新特性,这样子引入会有一点资源浪费。
解决方式:
可以使用polyfill-service。
他是一个Javascript的自动化服务,他可以通过分析请求头的userAgent实现自动加载浏览器所需的polyfills。
使用:在html中引入js脚本
<script src="https://polyfill.io/v3/polyfill.min.js"></script>
babel-polyfill和babel-runtime的区别:
https://www.jianshu.com/p/73ba084795ce
libraryTarget和library
当我们需要用webpack去构建一个可以被其它模块导入使用的库时需要用到他们。
- output.library : 配置到出库的名称
- output.libraryExport:配置要导出的模块中哪些子模块需要被导出。他只有在output.libraryTarget被设置成commonjs或者commonjs2时使用才有意义
- output.libraryTarget:配置以何种方式导出库,是字符串的枚举类型
我们先写一个库来测试这个打包功能
第一种:var(默认)
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist"),
library: "wxhf_add", //导出库的名称
libraryTarget: "var", // 以何种方式导出
libraryExport: "default", // 导出哪个属性,只有在libraryTarget设置为commonjs或者commonjs2的时候才有效
},
这样子导出去的库会被打包赋值给library定义的这个字段
使用方式:
第二种:comminjs
编写的库将通过CommonJs的规范导出
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist"),
library: "wxhf_add", //导出库的名称
libraryTarget: "commonjs", // 以何种方式导出 => 导出default属性
libraryExport: "default", // 导出哪个属性,只有在libraryTarget设置为commonjs或者commonjs2的时候才有效
},
使用方式:
import AddZpPackage from "add-zp-package";
// const AddZpPackage = require("add-zp-package");
console.log("AddZpPackage:", AddZpPackage);
let result = AddZpPackage.wxhf_add(100, 200);
result.then((res) => {
console.log("累加的结果:", res); // => 300
});
源码中导出的方式:
exports['module'] = (function(module){})({})
第三种:comminjs2
编写的库将通过CommonJs的规范导出
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist"),
library: "wxhf_add", //导出库的名称
libraryTarget: "commonjs2", // 以何种方式导出 => 导出default属性
libraryExport: "default", // 导出哪个属性,只有在libraryTarget设置为commonjs或者commonjs2的时候才有效
},
使用方式:
// import AddZpPackage from "add-zp-package";
const AddZpPackage = require("add-zp-package");
console.log("AddZpPackage:", AddZpPackage);
let result = AddZpPackage.wxhf_add(100, 200);
result.then((res) => {
console.log("累加的结果:", res); // => 300
});
源码中导出的方式:
module.exports = (function(modules){})({})
第四种:window
编写的库将通过window被赋值给通过library指定的名称,即把库挂载到window上面
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist"),
library: "wxhf_add", //导出库的名称
libraryTarget: "window", // 以何种方式导出 => 导出default属性
libraryExport: "default", // 导出哪个属性,只有在libraryTarget设置为commonjs或者commonjs2的时候才有效
},
使用方式:
window.wxhf_add(10,20) // => 30
导出方式:
window.xxx = modules
第五种:umd导出
umd最强大:支持所有的使用方式。
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist"),
library:'wxhf_add',//导出库的名称
libraryTarget: "umd",// 以何种方式导出
libraryExport: "default",// 导出哪个属性,只有在libraryTarget设置为commonjs或者commonjs2的时候才有效
},
导出方式:
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["wxhf_add"] = factory();
else
root["wxhf_add"] = factory();
})(xxx,xxx)
使用方式:
import的方式,require的方式,或者amd的define方式。
例如:
import AddZpPackage from "add-zp-package";
// const AddZpPackage = require("add-zp-package");
let result = AddZpPackage(100, 200);
result.then((res) => {
console.log("累加的结果:", res); // => 300
});
注:除了上面说的导出方式,libraryTarget还有amd,this,global等导出方式
purgecss-webpack-plugin
用来清理一下用不到的css文件,必须在生产模式下面使用
配置:
const glob = require("glob");
const PurgecssPlugin = require("purgecss-webpack-plugin");
module.exports = {
plugins: [
new PurgecssPlugin({
paths: glob.sync(`${path.join(__dirname, "src")}/**/*`, {
nodir: true,
}), //不匹配目录,只匹配文件
}),
],
};
我们创建一些没有用到的css类名:
打包之后的css,多余的类名就没有被打包进来,被过滤掉了
CDN
CDN又叫内容分发网络,通过把资源部署到世界各地,用户在访问的时候按照就近原则从离用户最近的服务器获取资源,从而加速资源获取速度。
- HTML文件不缓存,放在自己的服务器上,关闭自己服务器的缓存,静态资源的URL变成指向CDN服务器的地址。
- 静态的JavaScriptCSS图片等文件开启CDN和缓存,并文件名带上HASH值。
- 为了并行加载不阻塞,把不同的静态资源分配到不同的CDN服务器上。
使用缓存
- 由于CDN服务一般都会给资源开启很长时间的缓存,例如用户从CDN上获取到了index.html这个文件后 即使之后的发布操作把index.html文件给重新覆盖了,但是用户在很长一段时间内还是运行的之前的版本,这会新的导致发布不能立即生效 解决办法。
- 针对 HTML文件:不开启缓存,把HTML放到自己的服务器上,而不是CDN服务上,同时关闭自己服务器上的缓存。自己的服务器只提供HTML 文件和数据接口。
- 针对静态的JavaScriptCSS图片等文件:开启CDN和缓存,上传到CDN服务上去,同时给每个文件名带上由文件内容算出的 Hash 值
- 带上Hash值的原因是文件名会随着文件内容而变化,只要文件发生变化其对应的URL 就会变化,它就会祈重新下载,无论缓存时间有多长。
- 启用CDN之后相对路径,都变成了绝对的指向CDN 服务的URL地址
域名限制
- 同一时刻针对同一个域名的资源并行请求是有限制。
- 可以把这些静态资源分散到不同的CDN 服务上去。
- 多个域名后会增加域名解析时间。
- 可以通过在HTML HEAD标签中加入<link re="dns-prefetch"href=“http://www.baidu.com”>去预解析域名以降低域名解析带来的延迟
接入CDN
要给网站接入CDN,需要把网页的静态资源上传到CDN服务上去,在访问这些静态资源的时候需要通过CDN 服务提供的URL 地址去访问
module.exports = {
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist"),
publicPath:'https://img.baidu.cn/' //配置cdn之后,需要设置静态资源的访问路径
},
}