在开发阶段,我们希望把最终的代码和页面部署到服务器上来调试是否有bug,如果我们的代码不能实现热加载的话,那会对开发效率产生极大的影响,我们所有的时间,可能都浪费在打包、运行、调试过程了。
webpack-dev-server
就是一个热加载的模拟服务器。
我们要使用webpack-dev-server
,先要安装
npm install --D webpack-dev-server
我们通过执行webpack-dev-server
命令,来运行服务器。webpack-dev-server
命令几乎支持所有的webpack命令参数,如--config
、-env
等等,你可以把它当作webpack命令使用
webpack-dev-server --open
# --open 运行时打开浏览器
其实webpack-dev-server
的运行原理非常简单:
webpack-dev-server
的配置。
具体配置查看官方文档:https://www.webpackjs.com/configuration/dev-server/
module.exports = {
mode:"development",
devServer:{
port:3000,
open:true,
proxy: {
'/api': {
target: 'http://localhost:8081',
changeOrigin: true //修改请求头中的host,origin
},
}
}
}
解释:
api
路径,就会跳转到代理中的目标地址,常用于跨域访问,配合后台使用。我整理了几个webpack进行项目开发时常用的插件和常用的loader。
具体的使用请查看官网:https://www.npmjs.com/
clean-webpack-plugin:清除输出目录
npm install --save-dev clean-webpack-plugin
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
plugins: [
new CleanWebpackPlugin(),
]
}
html-webpack-plugin:生成html文件的插件
npm i --save-dev html-webpack-plugin
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template:"./public/index.html" //可以指定模板html,也可以使用默认的
}),
]
}
copy-webpack-plugin:复制文件的插件,复制静态资源
npm install --save-dev copy-webpack-plugin
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
plugins: [
new CopyPlugin([
{ from: 'source', to: 'dest' },
{ from: 'other', to: 'public' },
]),
],
};
综合使用一下
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
output:{
filename:"[name].[hash:5].js"
},
plugins:[
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
//指定模板html文件
template:"./public/index.html"
}),
new CopyPlugin([
{from:"./assets",to:"./assets"}
]
)
]
}
bundle analyzer:对bundle进行分析,直观的显示各个bundle文件的大小,以达到优化性能的目的
npm i -D webpack-bundle-analyzer
const WebpackBundleAnalyzer = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
module.exports = {
mode: "production",
plugins: [
new WebpackBundleAnalyzer()
]
};
compression-webpack-plugin:使用gzip方式对文件进行预压缩
npm i -D compression-webpack-plugin
const compressionWebpackPlugin = require("compression-webpack-plugin")
module.exports = {
mode: "production",
plugins: [
new compressionWebpackPlugin({
test: /\.(js)|(css)$/,
threshold: 10240, //超过多少字节进行压缩
minRatio: 0.8 //至少压缩到原来体积的0.8,才会进行压缩
})
]
};
file-loader: 生成依赖的文件到输出目录,生成的文件会导出一个路径。采用export default "文件名"
方式导出。
如果我们在某个js通过require导入图片,require无法对图片进行语法解析,打包时会报错,但是我们又要使用这个图片,那么我们就需要通过file-loader对图片进行处理。
/*----------假如我们在某个js中使用图片----------*/
const png = require("../assets/test.png").default //通过require导入图片,导出时用默认导出
let img = document.getElementsByTagName("img")[0]
img.src = png
/*----------webpack.config.js----------*/
module:{
rules:[
{
test:/\.(png)|(jpg)$/,
use:[{
loader:"file-loader",
options:{
name: '[name].[ext]',
}
}]
}
]
}
url-loader:将依赖的文件转换为:导出一个base64格式的字符。export default "base64编码"
module:{
rules:[
{
test:/\.(png)|(jpg)$/,
use:[{
loader:"url-loader",
options:{
limit:100*1024, //如果设置了大小,超出改范围就会自动转交给file-loader进行处理
name: 'imgs/[name].[ext]',//设置file-loader的输出目录文件
}
}]
}
]
},
url-loader中引入了file-loader,当限制大小的时候,超出限制会自动使用file-loader进行处理。
css-loader:将css代码转换为js代码。它的处理原理极其简单:将css文件的内容作为字符串导出。然后将css中的其他依赖作为require导入,以便webpack分析依赖
例如:我们的css代码是这样的
@import "./reset.css";
.red{
color:"#f40";
background:url("./bg.png")
}
经过css-loader处理以后,它会把代码转换为这样。具体转换过程可以去看源码(只是类似转换后的,有出入)
var import1 = require("./reset.css");
var import2 = require("./bg.png");
module.exports = `.red{
color:"#f40";
background:url("${import1}")
}`;
使用css-loader:
module:{
rules:[
{test:/\.css$/,use:"css-loader"}
]
}
style-loader:因为css-loader仅提供了将css转换为字符串导出的能力,style-loader可以将css-loader转换后的代码进一步处理,将css-loader导出的字符串加入到页面的style元素中
例如:
.red{
color:"#f40";
}
经过css-loader转换后变成js代码:
module.exports = `.red{
color:"#f40";
}`
经过style-loader转换后变成:(非真实转换代码,只是模拟一下)
module.exports = `.red{
color:"#f40";
}`
var style = module.exports;
var styleElem = document.createElement("style");
styleElem.innerHTML = style;
document.head.appendChild(styleElem);
module.exports = {}
style-loader的使用:
module:{
rules:[
{
test:/\.css$/,
use:["style-loader","css-loader"]
}]
}
mini-css-extract-plugin:因为css-loader转换css代码后,交给style-loader进习性处理,sytle-loader是用一段js代码,将样式加到style文件中。而我们通常更需要的是生成一个css文件。于是就有了库mini-css-extract-plugin
,这个库提供了一个plugin和一个loader:
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
module.exports = {
module: {
rules: [
{
test: /\.css$/, use: [MiniCssExtractPlugin.loader, "css-loader?modules"]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename:"[name].[hash:5].css"
}) //负责生成css文件,name是chunk的name
]
}
cache-loader:可以将loader的解析结果保存下来,让后续的解析直接使用缓存的结果,当然这种方式会增加第一次构建时间,要将cache-loader
放在最前面,虽然放在最前面,但是他可以决定让后续loader是否运行。
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: ['cache-loader', ...loaders]
},
],
},
};
所有的webpack内置插件都作为webpack的静态属性存在的,使用下面的方式即可创建一个插件对象
const webpack = require("webpack")
new webpack.插件名(options)
DefinePlugin:全局常量定义插件,使用该插件通常定义一些常量值。在源码中,我们可以直接使用插件中提供的常量,当webpack编译完成后,会自动替换为常量的值
const webpack = require("webpack")
module.export = {
plugins:[
new webpack.DefinePlugin({
PI: `Math.PI`, // PI = Math.PI
VERSION: `"1.0.0"`, // VERSION = "1.0.0"
})
]
}
BannerPlugin:它可以为每个chunk生成的文件头部添加一行注释,一般用于添加作者、公司、版权等信息
const webpack = require("webpack")
module.export = {
plugins:[
new webpack.BannerPlugin({
banner: `hash:[hash]
chunkhash:[chunkhash]
name:[name]
author:llk
corporation:xxx`
})
]
}
ProvidePlugin:自动加载模块,而不必到处 import 或 require 。我们可以在任意源码中直接使用$
和_
const webpack = require("webpack")
module.export = {
plugins:[
new webpack.ProvidePlugin({
$: 'jquery',
_: 'lodash'
})
]
}