概念
webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个 依赖图(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用于展示你的内容。
优点
代码拆分 — 形成项目依赖树,每个依赖都可拆分成一个模块,进行按需加载
Loader – webpack核心模块之一,主要处理各类型文件编译转换webpack处理模块,babel语法转换
智能解析 – 对CommonJS,AMD,CMD等支持性很好
Plugin(插件系统) – 强大的插件系统,可实现对代码压缩,分包chunk,模块热替换等,自定义模块,图片base64等,文档非常全面,自动化工作都有直接的解决方案
快速高效 – 开发配置可以选择不同环境的配置模式,可选择的打包文件,使用异步 I/O 和多级缓存提高运行效率
功能全面 — 最主流的前端模块打包工具,社区全面
缺点
配置复杂
不分包bundele.js体积庞大
只能用于采用模块化开发的项目
打包慢
ES模块除Module外全用babel转换,但是一部分ES2015 语法的 firefox 与 chrome 浏览器中能直接跑的代码,无法用 webpack 编译
使用
创建项目
需要node.js环境
配置webpack
webpack.config.js
// 导入html-webpack-plugin插件处理html目标
// 提前安装 npm i html-webpack-plugin -D
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 自定拷贝到dist目录,插入打包好的js文件
// 使用loader
// npm i css-loader style-loader -D
// 作用 css-loader处理css文件 style-loader 把加载好的css放入style标签
// npm i clean-webpack-plugin -D
// 作用:清零dist目录(执行npm run build 需要清理上一次的生成的内容)
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
// 导入path
const path = require("path");
// 导入css 抽出插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// 导入css优化插件
// 需要安装:css-minimizer-webpack-plugin
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
// js压缩
// 需要安装 npm i terser-webpack-plugin -D
const TerserPlugin = require("terser-webpack-plugin");
// 导入vue-loader
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
optimization: { //优化选项
// minimize: true, //默认是压缩
minimizer: [new CssMinimizerPlugin(),new TerserPlugin()],//压缩器
splitChunks: { // 代码分割 当js比较小会多个合成1个,当js超过3m一个分割为多个
chunks: "all",
}
},
resolve: {
// 别名:@代表是 src目录
alias: {
'@': path.resolve(__dirname, './src'), //设置@为src目录的别名
}
},
entry:{
"main":"./src/main.js",
"index":"./src/index.js"
}, //入口
output:{ //出口
filename:"[name]-[chunkhash].js",//文件名
// path:path.resolve(__dirname,'/dist')
path:__dirname+'/dist' //文件夹 __dirname 当前目录
},
mode:process.env.NODE_ENV,//模式:开发模式 production产品模式
plugins:[
new VueLoaderPlugin(),
// 实例化插件,指定template模板的位置
new HtmlWebpackPlugin({
template:'./public/index.html',//模板
chunks:["index"],//入口
filename:"index.html" //文件名
}),
new HtmlWebpackPlugin({
template:'./public/main.html',//模板
chunks:["main"],//入口
filename:"main.html" //文件名
}),
// 实例化好清理
new CleanWebpackPlugin(),
// 初始化css抽出插件
new MiniCssExtractPlugin({
filename:"style-[contenthash].css"
})
],
module:{
rules:[
{ test: /\.vue$/, use: ['vue-loader'] },
// 当文件名test通过,使用如下插件
{test:/\.css$/,use:[/*"style-loader",*/ MiniCssExtractPlugin.loader,"css-loader"]},
// 需要安装 npm i scss-loader -D
{test:/\.scss$/,use:[/*"style-loader",*/ MiniCssExtractPlugin.loader,"css-loader","sass-loader"]},
// 需要提前安装 url-loader file-loader
{test:/\.(png|jpg|jpeg|webp|ico|gif|bmp)$/,
use:[{
loader:"url-loader", //使用url加载器
options:{limit:5000,name:'images/[hash].[ext]'},
// 选项,当图片小于5000字节时候,转换base64(小图片减少一次http请求)
// 文件命名 images文件夹,hash值(计算出图片的名称) ext 后缀名
}]
},
]
},
// 需要提前安装 npm i webpack-dev-server -D
devServer:{
port:8080,
hot:true, //更新
host:"localhost",//域名
open:true,//默认自动打开浏览器
proxy:{} //vue.config.js 代理一致
},
devtool:process.env.NODE_ENV==="production"?false:'eval-cheap-source-map',
}
// js经过了压缩,如果出错了,找错误困难,
// js出的错误和源代码有个一一对应关系
// dev-tool
// module 模块 exports 导出 entry output输出 filename文件名,path路径 dirname当前目录 dist目标
// mode模式 development开发模式 production产品 rule规程 test测试 use使用 plugins插件 template模板
// dev开发 Server服务器 prot端口号 hot热更新 host域名 open打开 proxy代理
package.json
"scripts": {
"build": "webpack",
"serve": "webpack serve",
"test": "echo \"Error: no test specified\" && exit 1"
},
src>assets>index.js
// 导入css(webpack默认不能处理css需要使用loader处理)
import './assets/index.css'
// 导入header
import header from './header.js'
header.className = "active"; //添加类名
// header.classlist.add("active");
// 插入到body标签
document.body.appendChild(header);
// 插入一张图片
var img = document.createElement("img");
// 导入一张图片
import pic from './assets/images/pic.jpeg';
// 设置图片的src
img.src = pic;
// 设置样式宽
img.style.width="200px";
// 插入图片到body
document.body.appendChild(img);
// 创建div
var icon = document.createElement("div");
// 设置内容
icon.innerHTML = '<span class="iconfont icon-check-circle"></span> <span class="iconfont icon-close-circle"></span>';
// 插入div icon
document.body.append(icon);
// 导入scss
import '@/assets/my.scss';
// 创建div
var big = document.createElement("div");
// 设置html内容
big.innerHTML = `<span class="item">我是小2淘气</span>前端月薪过万`;
// 设置类名
big.className="big";
// 插入body
// alert(b);//没有b这个变量 会报错
document.body.appendChild(big);
// import $ from 'jquery';
// console.log($);
// 希望big被单击才导入jq //提前安装 jq npm i jquery -S
// big.onclick = function(){
// // webpack魔法注释,给这个文件命名
// // prefetch 提前预加载jquery(等网络有空闲的时候)
// import(/* webpackChunkName:"jquery" , webpackPrefetch: true */ "jquery").then(({default:$})=>{
// console.log($);
// })
// }
var baseURL = "";
if(process.env.NODE_ENV=="production"){
baseURL = "http://dida100.com";
}else{
baseURL = "http://localhost"
}
console.log("当前环境:",process.env.NODE_ENV,baseURL);
src>assets>index.css
@import './font/iconfont.css';
/* css-loader 会自动处理字体文件,不需要对字体单独的打包处理 */
.active{
color:#f70;
font-weight: 900;
margin: 10px;
}
.active{
border-left:23px solid red;
border-top:1px solid red;
border-right:1px solid red;
border-bottom:1px solid red;
}
.active{
margin-left:50px;
margin-right:50px;
margin-bottom:50px;
margin-top:50px;
}
src>assets>header.js
// 创建一个div标签
var div = document.createElement("div");
// 插入内容
div.innerHTML = "你好 123";
// 导出
export default div;
更多方法见官网:https://www.webpackjs.com/concepts/