本章节我们学习一下webpack中的eslint , 字体引入 ,如何调试打包后的代码,打包第三方类库,watch,拷贝静态文件,服务器代理,添加商标.
1、eslint的使用
在我们平时的开发过程中,eslint是一个必不可少的代码质量检测工具,他的用处主要体现在以下几点:
- 1.审查代码是否符合编码规范和统一的代码风格;
- 2.审查代码是否存在语法错误;
- 3.方便项目后期的一个维护和迭代开发
下面,我们来看看如何在webpack中进行配置吧。
第一步安装包:
npm i eslint eslint-loader babel-eslint -D
第二步:
在项目根目录下面创建eslint的配置文件 ==> .eslintrc.js
并在其中写入eslint的相关配置:
module.exports = {
root: true,
//指定解析器选项
parserOptions: {
sourceType: "module",
ecmaVersion: "2015",
},
//执行脚本的运行环境
env: {
browser: true, //浏览器端
},
//启用的规则及其各自的错误级别
rules: {
indent: ["error", 2], //缩进风格,第一个参数的eslint提示的类型 error => 错误
quotes: ["error", "double"], //引号类型
semi: ["error", "always"], //关闭语句强制分号结尾
"no-console": "error", //禁止使用console
"arrow-parens": 0, //箭头函数用小括号括起来
},
};
第三步:
vscode安装eslint插件,并开启
这样子我们在写代码的时候,eslint就会检测到我们代码中不规范以及错误的地方,例如禁止console,如图:
我们也可以配置打包的时候eslint的校验
配置webpack的module
{
test: /\.js$/,
loader: "eslint-loader",
enforce: "pre", //强制提前执行
include: path.resolve(__dirname, "src"), //校验src目录下面的文件
exclude: /node_modules/, //不校验node_modules下面的文件
},
这样子在我们打包时,如果有不规范的代码时就会报错,如下:
注:eslint的规则配置也可以直接继承eslint-config-airbnb,具体配置查看https://www.npmjs.com/package/eslint-config-airbnb
2、字体引入
首先我们需要配置loader:
{
test: /\.(ttf|svg|eot|woff|woff2|otf)/,
use: ["url-loader"],
},
然后就可以在代码中引入字体了:
@font-face {
font-family: "FONT_TEST";
src: url("./../static/font/D-DIN-Bold.ttf") format("truetype");
}
.font-change {
font-family: "FONT_TEST" !important;
}
3、调试打包后的代码(source-map)
sourcemap是为了解决开发代码与实际运行代码不一致时帮助我们debug到原始开发代码的技术,webpack通过配置可以自动给我们source map 文件,map文件是一种对应编译文件和源文件的方法。
sourceMap有以下几种类型:
配置source-map:
devtool: "source-map",
source-map打包之后会生成sourceMap文件,但是这样子就会导致打包之后的文件体积特别大,因为会生成很多.map文件
eval:
devtool: "eval",
使用eval规则打包之后的代码会被传eval当做字符串包裹住:
并且调试的时候也看不到真正的源代码:
并且他们会在尾部给浏览器暴露出代码的位置:
cleap-module-source-map
相较于cleap-source-map,他可以调试真正的源码
4、打包第三方模块
第一种:使用webpack.ProviderPlugin插件
- webpack配置了ProviderPlugin插件之后,可以不再需要import和require进行引入,直接使用即可
- _ 函数会自动添加到当前模块的上下文,无需显示声明
new Webpack.ProvidePlugin({
_: "lodash",
}),
let arr = ["a", "b", "c"];
console.log(_.join(arr, "@")); // => a@b@c
第二种:expose-loader
expose 寓意为:暴露,就是为了解决一些插件不支持commonJs引入的问题(如:bootstrap.js,它只允许jQuery暴露为全局变量才可用)
// 注意,需要将这个loader的使用放在所有的loader之前
{
test: require.resolve("jquery"),
loader: "expose-loader",
options: {
exposes: ["$"],
},
},
在入口文件引入我们暴露出去的函数:
import $ from "jquery";
这样子我们就可以在其他模块代码中全局使用jquery了
他还会在window全局下挂载这个变量
第三种:externals
如果我们想引用一个库,但是又不想webpack打包,并且又不影响我们在程序中以CMD、AMD或者window/global等方式进行使用,那就可以通过配置externals
配置webpack
externals: {
jquery: "jQuery",//key是jquery,是一个包的名字,值是jQuery,是一个全局(window)上面的属性
}
在index.html中去引入js文件的CDN:
我们可以在全局的任何地方去使用它:
import $ from "jquery";
console.log($)
优点:此时,我们打包的时候就不会再把jquery打包进来,使用jquery时会直接去拿全局上面的jquery
缺点:每次使用都需要引入包的cdn,并且还要去配置externals
第四种:html-webpack-externals-plugin
这个插件的优势相较于externals的是,他会自己去外链CDN资源,不需要我们在html中去添加script标签引入第三方js
配置webpack:
new htmlWebpackExternalsPlugin({
externals: [
{
module: "jquery", //模块名
entry: "https://cdn.bootcss.com/jquery/3.4.1/jquery.js", //CDN的脚本路径
global: "jQuery", //从全局对象的哪个属性上获取导出的值
},
],
}),
我们可以在全局的任何地方去使用它:
import $ from "jquery";
console.log($)
而且他会帮我们在html中自动引入script标签:
5、watch:代码发生变化后会自动重新打包,编译
当代码发生修改后,可以自动重新编译,热更新
原理:
- 1、webpack定时获取文件的更新时间,并跟上次保存的时间进行比对,不一致就表示发生了变化,poll就用来配置每秒问多少次。
- 2、当检测文件不再发生变化,会先缓存起来,等待一段时间后之后再通知监听者,这个等待时间通过aggregateTimeout 配置
- 3、webpack只会监听entry依赖的文件。
- 4、我们需要尽可能减少需要监听的文件数量和检查频率,当然频率的降低会导致灵敏度下降
配置:
watch: true,//默认为false,不开启
//只有开启了watch为true,watchOptions采用意义
watchOptions:{
ignore: /node_modules/, //默认为空,表示不需要监听的文件夹,支持正则匹配
aggregateTimeout:300,//监听到变化发生后会等300ms再去执行,默认300ms
poll:1000,// 判断文件是否发生变化是通过不停的询问文件系统,默认每一秒询问1000次
},
6、添加商标webpack.BannerPlugin
在打包后的代码前面加上一个商标(标志)
配置:
new Webpack.BannerPlugin("我的商标"),
7、拷贝静态文件copy-webpack-plugin
有时项目中没有引用的文件也需要打包到指定的目录
配置:
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, "src/static"),
to: path.resolve(__dirname, "dist/static"),
globOptions: {
ignore: [".*"],
},
},
],
}),
8、打包前清空目录
new CleanWebpackPlugin(), //打包自动清空之前打包的文件目录
9、服务器代理
如果你有单独的后端开发服务器API,并且希望在同域名下发送API请求,那么代理某些URL会很有用
配置:
devServer: {
//开发服务器配置
//请求 /api/user 现在会被代理到请求http://localhost:3000/api/user
proxy: {
"/api": "http://localhost:3000",
},
},
当然,也可以重写路径:
proxy: {
"/api": "http://localhost:3000",
pathRewrite: {
"^/api": "", //这样子被重写之后,请求/api/user就会被代理成 http://localhost:3000/user
},
},
可以使用开发服务器中的before来模拟一个服务器: