wepack是什么
面向过程编写的代码非常庞大,难以维护
面向对象编程能提高代码的可维护性,但是会诞生另一个问题,模块太多引起的上线文件过大
而webpack模块打包工具就能解决这一问题,将模块化进行一个大包,极大地优化了项目的大小,对项目上线运行速度有极大地提升
merge
- 公共配置
- production配置
- development配置
merge的作用就是将生产配置和开发配置合并到公共配置中去
核心概念
JavaScript 的 模块打包工具 (module bundler)。通过分析模块之间的依赖,最终将所有模块打包成一份或者多份代码包 (bundler),供 HTML 直接引用。实质上,Webpack 仅仅提供了 打包功能 和一套 文件处理机制,然后通过生态中的各种 Loader 和 Plugin 对代码进行预编译和打包。因此 Webpack 具有高度的可拓展性,能更好的发挥社区生态的力量。
- mode:
- development:不压缩代码
- production:压缩代码
- Entry: 入口文件,Webpack 会从该文件开始进行分析与编译;
- Output: 出口路径,打包后创建 bundler 的文件路径以及文件名;
- Module: 模块,在 Webpack 中任何文件都可以作为一个模块,会根据配置的不同的 Loader 进行加载和打包;
- Chunk: 代码块,可以根据配置,将所有模块代码合并成一个或多个代码块,以便按需加载,提高性能;
- Loader: 模块加载器,进行各种文件类型的加载与转换;
Plugin: 拓展插件,可以通过 Webpack 相应的事件钩子,介入到打包过程中的任意环节,从而对代码按需修改;
工作流程 (加载 - 编译 - 输出)
1、读取配置文件webpack.config.js,按命令 初始化 配置参数,创建 Compiler 对象;
- 2、调用插件的 apply 方法 挂载插件 监听,然后从入口文件开始执行编译;
- 3、按文件类型,调用相应的 Loader 对模块进行 编译,并在合适的时机点触发对应的事件,调用 Plugin 执行,最后再根据模块 依赖查找 到所依赖的模块,递归执行第三步;
- 4、将编译后的所有代码包装成一个个代码块 (Chuck), 并按依赖和配置确定 输出内容。这个步骤,仍然可以通过 Plugin 进行文件的修改;
- 5、最后,根据 Output 把文件内容一一写入到指定的文件夹中,完成整个过程;
基础配置
mode 模式
"production" | "development" | "none"
不同的模式会对 webpack 打包的时候进行一些对应的优化配置。
module.exports = {mode: 'production'}
entry 指定打包⼊口⽂文件
有三种不同的形式:string | object | array
一对一:一个入口、一个打包文件
module.exports = {entry: './src/index.js'}
多对一:多个入口、一个打包文件
module.exports = {entry: ['./src/index1.js','./src/index2.js',]}
多对多:多个入口、多打包文件
module.exports = {entry: {'index1': "./src/index1.js",'index2': "./src/index2.js"}}
output 打包后的文件位置
- 可以指定一个固定的文件名称,如果是多入口多出口(
entry为对象),则不能使用单文件出口,需要使用下面的方式 - 通过
webpack内置的变量占位符:[name]
module.exports = {...,output: {path: path.resolve(__dirname, "dist"),filename: "bundle.js",filename: "[name].js"}}
如果想要把静态资源放入cdn
output: {publicPath: "http://cdn.com.cn",filename: "[name].js",path: path.resolve(__dirname, "dist"),},
多入口文件时,plugin的配置
针对每一个入口文件生成一个plugin的实例,配置chunks
plugins: [// new HtmlWebpackPlugin({// template: path.join(srcPath, 'index.html'),// filename: 'index.html'// })// 多入口 - 生成 index.htmlnew HtmlWebpackPlugin({template: path.join(srcPath, 'index.html'),filename: 'index.html',// chunks 表示该页面要引用哪些 chunk (即上面的 index 和 other),默认全部引用chunks: ['index'] // 只引用 index.js}),// 多入口 - 生成 other.htmlnew HtmlWebpackPlugin({template: path.join(srcPath, 'other.html'),filename: 'other.html',chunks: ['other'] // 只引用 other.js})]
loaders
Loaders文档
注意loader是从右往左边加载的
const path = require("path");module.exports = {mode: "development",entry: "./src/index.js",output: {filename: "index.js",path: path.resolve(__dirname, "dist"),},module: {rules: [{test: /\.jpg$/,use: {loader: "file-loader",},},{test: /\.vue$/,use: {loader: "vue-loader",},},],},};
当 webpack 碰到不识别的模块的时候,webpack 会在配置的 module 中进行该文件解析规则的查找
- rules 就是我们为不同类型的文件定义的解析规则对应的 loader,它是一个数组
- 每一种类型规则通过 test 选项来定义,通过正则进行匹配,通常我们会通过正则的方式来匹配文件后缀类型
- use 针对匹配到文件类型,调用对应的
loader进行处理 - exclude:排除掉哪些文件
use配置
options
- name: placeholder占位符
- “[name].[ext]”,保持原名打包输出
- “[name]_[hash].[ext]”,后面加上hash值
- outputPath:输出目录
常用loader
- file-loader: 加载文件资源,如 字体 / 图片 等,具有移动/复制/命名等功能;
- url-loader: 通常用于加载图片,可以将小图片直接转换为 Date Url,减少请求;
- babel-loader: 加载 js / jsx 文件, 将 ES6 / ES7 代码转换成 ES5,解决兼容性问题;
- ts-loader: 加载 ts / tsx 文件,编译 TypeScript;
- style-loader: 将 css 代码以
<style>标签的形式插入到 html 中; - css-loader: 分析
@import和url(),引用 css 文件与对应的资源; - postcss-loader: 用于 css 的兼容性处理,具有众多功能,例如 添加前缀,单位转换 等;
- less-loader / sass-loader: css预处理器,在 css 中新增了许多语法,提高了开发效率;
file-loader
把识别出的资源模块,移动到指定的输出⽬目录,并且返回这个资源在输出目录的地址(字符串)
npm install --save-dev file-loader
rules: [// ...,{test: /\.(png|jpe?g|gif)$/,use: {loader: "file-loader",options: {// placeholder 占位符 [name] 源资源模块的名称// [ext] 源资源模块的后缀name: "[name]_[hash].[ext]",//打包后的存放位置outputPath: "./images"// 打包后文件的 urlpublicPath: './images',}}}]
url-loader
- 可以处理理
**file-loader**所有的事情 - 但是遇到图片格式的模块,可以选择性的把图片转成
base64格式的字符串,并打包到js中 - 对⼩体积的图片⽐较合适,⼤图⽚不合适。
rules: [...,{test: /\.(png|jpe?g|gif)$/,use: {loader: "url-loader",options: {// placeholder 占位符 [name] 源资源模块的名称// [ext] 源资源模块的后缀name: "[name]_[hash].[ext]",//打包后的存放位置outputPath: "./images"// 打包后文件的 urlpublicPath: './images',// 小于 100 字节转成 base64 格式limit: 100}}}]
css-/sass/style-loader 注意顺序←
分析多个css文件,最终合并为一个css文件
把css-loader得到的文件挂载到html文件的head标签里
use: ["style-loader", "css-loader"],
use: ["style-loader", "css-loader", "sass-loader"],
css模块化打包
避免样式冲突
{loader: "css-loader",options: {importLoaders: 2,modules: true,},},
import style from "./index.scss";var img = new Image();img.src = cat;img.classList.add(style.cat);
hash文件
output: {filename: 'bundle.[contentHash:8].js', // 打包代码时,加上 hash 戳path: distPath,},
编写原则:
- 单一原则: 每个 Loader 只做一件事;
- 链式调用: Webpack 会按顺序链式调用每个 Loader;
统一原则: 遵循 Webpack 制定的设计规则和结构,输入与输出均为字符串,各个 Loader 完全独立,即插即用;
plugins
是类似于生命周期函数的一个钩子函数,比如整个打包过程之后调用
常用 plugin
CommonsChunkPlugin: 代码分割;
- ProvidePlugin: 自动加载模块;
- html-webpack-plugin: 加载 html 文件,并引入 css / js 文件;
- extract-text-webpack-plugin / mini-css-extract-plugin: 抽离样式,生成 css 文件;
- optimize-css-assets-webpack-plugin: CSS 代码去重;
- webpack-bundle-analyzer: 代码分析;
- compression-webpack-plugin: 使用 gzip 压缩 js 和 css;
- happypack: 使用多进程,加速代码构建;
HtmlWebpackPlugin
在打包结束后,⾃动生成⼀个html⽂文件,并把打包生成的 js 模块引⼊到该html中
// webpack.config.jsconst HtmlWebpackPlugin = require("html-webpack-plugin");module.exports = {...plugins: [new HtmlWebpackPlugin({title: "My App",filename: "app.html", // 输出的html文件名template: "./src/html/index.html"})]};
在 html 模板中,可以通过 <%=htmlWebpackPlugin.options.XXX%> 的方式获取配置的值
clean-webpack-plugin
MiniCssExtractPlugin抽离压缩css文件
一般在生产环境使用
配置loader
{test: /\.scss$/,loader: [MiniCssExtractPlugin.loader, // 注意,这里不再用 style-loader'css-loader','sass-loader','postcss-loader']}
// 抽离 css 文件new MiniCssExtractPlugin({filename: 'css/main.[contentHash:8].css'})
sourcemap
是一个映射关系
https://www.webpackjs.com/configuration/devtool/
- inline-source-map:将.map文件合并到打包文件中去
- cheap-module-eval-source-map用于开发环境
- cheap-module-source-map用于生产环境)
WebpackDevServer提升开发效率
webpack-cli中已经自带serve了
使用webpack serve命令即可
