webpack基础
webpack简介 :
-
webpack是什么?
本质上,webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具。
作用 :用于分析并打包代码,支持所有类型文件的打包,且能够压缩代码,提高加载速度。
-
webpack核心概念 :
entry
: 指示 webpack 应该使用哪个模块,来作为构建其内部 依赖图(dependency graph) 的开始。output
: 指示webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件。loader
: 让 webpack 能够去处理其他类型(非JavaScript
和JSON
文件)的文件,并将它们转换为 有效模块,以供应用程序使用,以及被添加到依赖图中。plugins
: 可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量。mode
: 指示使用相应模式配置development
和production
,可以启用 webpack 内置在相应环境下的 优化。其默认值为production
。
webpack基本用法 :
-
入口文件 :webpack 入口文件为
index.js
-
运行命令 :
2.1 初始化 :
npm init
或yarn init
2.2 安装依赖包 :
-
全局安装 :
npm i webpack webpack-cli -g
或yarn add webpack webpack-cli -g
-
本地安装 :
npm i webpack webpack-cli -D
或yarn add webpack webpack-cli -D
2.3 编译打包命令 (无配置文件时) :
- 开发环境 :
webpack ./src/index.js -o ./build/built.js --mode=development
(webpack 会以./src/index.js
为入口文件开始打包 , 打包后输出到./build/built.js
整体打包环境为开发环境) - 生产环境 :
webpack ./src/index.js -o ./build/built.js --mode=production
(webpack 会以./src/index.js
为入口文件开始打包 , 打包后输出到./build/built.js
整体打包环境为生产环境)
2.4 运行打包输出的文件 :
node .\build\built.js\main.js
2.5 打包文件用于网页上 :借助
index.html
文件,引入打包后的main.js
文件,即可在网页上运行。2.6 配置
scripts
(自定义命令):-
此时运行命令改为
yarn build
或npm run build
"scripts": { "build": "webpack" }
-
-
可直接处理文件格式 :
3.1 webpack 能 直接处理
js/json
资源 ;3.2 webpack 不能 直接处理
css/img
等其他资源 ; -
环境异同 :
4.1 生产环境和开发环境将 ES6 模块化编译成浏览器能识别的模块化 ;
4.2 生产环境比开发环境多一个压缩 js 代码。
-
编译打包执行流程图 :
webpack配置 :
-
配置文件 :webpack 的默认配置文件为
webpack.config.js
-
规范 :构建工具都是基于
nodejs
平台运行的 , 模块化采用commonjs
-
基本配置 :
// resolve 用来拼接绝对路径 // path - nodejs 内置路径模块 const { resolve } = require('path') // commonjs 导出规则 module.exports module.exports = { // webpack 配置 // 入口文件 entry: './src/index.js', // 输出 output: { // 输出文件名 filename:'built.js', // 输出路径 // __dirname - nodejs 的变量, 代表当前文件的目录绝对路径 path: resolve(__dirname,'build') }, // loader 的配置 module: { rules: [ // 详细 loader 的配置 ] }, // plugins 的配置 plugins: [ { // 详细 plugins 的配置 } ], // 模式 mode: 'development', // 开发模式 // mode: 'production' // 生产模式 }
-
loader 的基础使用 :
-
下载
-
loader 的详细配置 :
2.1 test 定义文件格式 ;
2.2 use 数组里面添加 loader 名
module: { rules: [ // 详细 loader 的配置 { // test - 匹配的文件格式 test: /正则表达式/, // 例如: /.文件类型$/ // use - 使用的 loader use: [ // loader 名的数组, 例如: "xxx-loader", "xxxx-loader" // use 数组中 loader 执行顺序: 从右到左, 从下到上依次执行 ] ] },
>>> 注意:
rules
里面每个对象是独立的, 不可复用, 若两个独立的对象需要使用相同的loader
, 必须多次书写 -
-
plugins 的基础使用 :
-
下载
-
引入
-
plugins 的使用 :插件一般是类/构造函数 , 调用格式 :new 插件变量名()
// 引入插件并用变量名保存 const { 插件变量名 } = require('插件名') plugins: [ // 详细 plugins 的配置 { /* new 插件变量名({ 插件配置信息 }) */ } ],
-
-
-
编译打包命令 (有配置文件时) :
webpack
实例 :
所有实例运行均在 webpack 5.0
环境下
-
新建实例文件夹,运行
npm init
或yarn init
命令,得到初始化包管理文件package.json
-
运行
npm i webpack webpack-cli -D
命令,初始化webpack
打包环境 -
文价夹中新建
build
文件夹放置打包后的资源,新建src
文件夹放置打包前的资源,src
文件夹中新建index.js
文件作为入口文件,新建webpack.config.js
文件配置 webpack
webpack打包样式资源 :
-
src
文件下新建index.css
文件:body, html { margin: 0; padding: 0; height: 100%; background-color: pink; }
-
src
文件下新建index.less
文件:#title { color: #fff; }
-
index.js
文件引入样式资源:// 引入样式资源 import './index.css'; import './index.less'
-
webpack.config.js
文件主要配置如下:const { resolve } = require('path') module.exports = { entry: './src/index.js', output: { filename: 'built.js', path: resolve(__dirname,'build') }, module: { // loader 的配置 rules: [ { test: /\.css$/, // 匹配 css 文件 use: [ // 使用的 loader 'style-loader', // 创建 style 标签, 将 js 中的样式资源进行插入, 添加到 head 中生效 'css-loader' // 将 css 文件变成 commonjs 模块加载 js 中, 里面内容是样式字符串 ] }, { test :/\.less$/, // 匹配 less 文件 use: [ 'style-loader', 'css-loader', 'less-loader' // 将 less 文件编译成 css 文件 ] } ] }, plugins: [], mode: 'development', }
-
build
文件夹中新建index.html
文件显示打包后的效果:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1 id="title">webpack 打包样式资源</h1> <!-- 引入打包后的文件 --> <script src="./built.js"></script> </body> </html>
效果如下:
webpack打包HTML资源 :
-
src
文件下新建index.html
文件:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>webpack</title> </head> <body> <h1 id="title">hello, html</h1> </body> </html>
-
webpack.config.js
文件主要配置如下:const { resolve } = require('path') // 引入插件 const HTMLWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: './src/index.js', output: { filename: 'built.js', path: resolve(__dirname, 'build') }, module: { rules: [{}] }, plugins: [ // plugins 的详细配置 // html-webpack-plugin // 功能: 默认会创建一个空的HTML, 自动引入打包输出的所有资源(js/css) // 需求: 需要有结构的HTML文件 new HTMLWebpackPlugin ({ // 复制 ./src/index.html 文件, 并自动引入打包输出的所有资源(js/css) template: './src/index.html' // 复制文件路径 }) ], mode: 'development' }
-
html-webpack-plugin
插件在上述配置后会自动在build
文件夹中复制./src/index.html
文件生成index.html
文件并引入所有打包后的资源:效果如下:
webpack打包图片资源:
一、css 中通过 url 引入图片资源(有坑,主要是版本问题):
-
src
文件下新建index.html
文件:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>webpack</title> </head> <body> <!-- 创建三个盒子保存图片 --> <div id="box1"></div> <div id="box2"></div> <div id="box3"></div> </body> </html>
-
src
下新建assets
文件夹,放入图片: -
src
文件下新建index.less
文件:// 引入三张图片 #box1{ width: 100px; height: 100px; background-image: url('./assets/vue.jpg'); background-repeat: no-repeat; background-size: 100% 100%; } #box2{ width: 200px; height: 200px; background-image: url('./assets/react.png'); background-repeat: no-repeat; background-size: 100% 100%; } #box3{ width: 300px; height: 300px; background-image: url('./assets/angular.jpg'); background-repeat: no-repeat; background-size: 100% 100%; }
-
index.js
文件引入样式资源:import './index.less';
-
webpack.config.js
文件主要配置如下:const { resolve } = require('path') // 引入插件 const HTMLWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: './src/index.js', output: { filename: 'built.js', path: resolve(__dirname, 'build') }, module: { rules: [ { test: /.less$/, // 使用多个 loader use: ['style-loader', 'css-loader', 'less-loader'] }, { // 处理图片资源 test: /.(jpg|png|gif)$/, // 使用一个 loader loader: 'url-loader', options: { // 图片大小小于 8kb, 就会被 base64 处理 // 优点: 减少请求数据(减轻服务器压力) // 缺点: 图片体积会更大(文件请求速度更慢) limit: 8 * 1024, } } ] }, plugins: [ new HTMLWebpackPlugin ({ template: './src/index.html' }) ], mode: 'development' }
>>> 使用单个 loader 用 loader 即可,使用多个 loader 用use 值为传入所需所有 loader 的数组
-
html-webpack-plugin
插件在上述配置后会自动在build
文件夹中复制./src/index.html
文件生成index.html
文件并引入所有打包后的资源:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>webpack</title> <script defer src="built.js"></script></head> <body> <!-- 创建三个盒子保存图片 --> <div id="box1"></div> <div id="box2"></div> <div id="box3"></div> </body> </html>
>>> 此时页面为一片空白
>>> 为什么此时
url-loader
不起效 ?翻阅文档发现最新版的
webpack 5.0
移除了url-loader
,新增Asset Modules
资源模块,利用asset/inline
导出一个资源的data URI
>>> 解决方案:
-
利用
webpack 5.0
新增Asset Modules
资源模块,默认导出1.1 修改
webpack.config.js
文件配置如下:const { resolve } = require('path') const HTMLWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: './src/index.js', output: { filename: 'built.js', path: resolve(__dirname, 'build') }, module: { rules: [ { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }, // 不书写默认为 asset 处理 { test: /\.(png|svg|jpg|jpeg|gif)$/i, type: 'asset/resource', }, // 可省略 ] }, plugins:[ new HTMLWebpackPlugin({ template:'./src/index.html' }) ], mode:'development' }
1.2 打包文件效果:
1.3 网页效果:
-
利用
type: 'javascript/auto'
使用webpack 4.0
语法,并增加配置esModule:false
启用 CommonJS 模块语法2.1 修改
webpack.config.js
文件配置如下:const { resolve } = require('path') const HTMLWebpackPlugin = require('html-webpack-plugin') module.exports = { entry:'./src/index.js', output:{ filename:'built.js', path:resolve(__dirname,'build') }, module:{ rules:[ { test:/\.less$/, use:['style-loader', 'css-loader', 'less-loader'] }, { // 处理图片资源 test:/\.(jpg|png|gif)$/, // 使用一个 loader // 下载 url-loader file-loader (url-loader 依赖于 file-loader) loader: 'url-loader', // 使用 webpack 4.0 语法 type: 'javascript/auto', options: { // 图片大小小于 8kb, 就会被 base64 处理 // 优点: 减少请求数据(减轻服务器压力) // 缺点: 图片体积会更大(文件请求速度更慢) limit: 8 * 1024, esModule:false } } ] }, plugins:[ new HTMLWebpackPlugin({ template:'./src/index.html' }) ], mode:'development' }
2.2 打包文件效果:
>>> 由于只有
react.png
文件大于8kb
,其余均被base64
处理了,所以打包文件中仅有一张png
图片文件2.3 网页效果:
>>> 总结:在css中通过url引入图片资源,用
url-loader(webpack4)
、asset(webpack5)
处理
-
二、html 中创建 img 标签引入图片资源:
-
src
文件下新建index.html
文件:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>webpack</title> </head> <body> <!-- 创建三个 img 标签显示图片 --> <img id="box1" src="./assets/vue.jpg" alt=""> <img id="box2" src="./assets/react.png" alt=""> <img id="box3" src="./assets/angular.jpg" alt=""> </body> </html>
-
src
下新建assets
文件夹,放入图片: -
src
文件下新建index.less
文件:#box1{ width: 100px; height: 100px; background-repeat: no-repeat; background-size: 100% 100%; } #box2{ width: 200px; height: 200px; background-repeat: no-repeat; background-size: 100% 100%; } #box3{ width: 300px; height: 300px; background-repeat: no-repeat; background-size: 100% 100%; }
-
index.js
文件引入样式资源:import './index.less';
-
webpack.config.js
文件主要配置如下:5.1 利用
url-loader
处理:const { resolve } = require('path') const HTMLWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: './src/index.js', output: { filename: 'built.js', path: resolve(__dirname,'build') }, module: { rules: [ { test: /.less$/, // 使用多个 loader use: ['style-loader', 'css-loader', 'less-loader'] }, { // 处理图片资源 test: /\.(jpg|png|gif)$/, // 使用一个 loader loader: 'url-loader', type: 'javascript/auto', options: { // 图片大小小于 8kb, 就会被 base64 处理 // 优点: 减少请求数据(减轻服务器压力) // 缺点: 图片体积会更大(文件请求速度更慢) limit: 8 * 1024, // 关闭 url-loader 的 ES6 模块化, 使用 CommonJS 解析 esModule: false // 给图片重命名 // [hash: 10] 取图片 hash 值前10位 // [ext] 取文件原来扩展名 name: '[hash: 10].[ext]' } }, { test: /.html$/, // 处理 html 文件的 img 图片 (负责引入 img, 从而能被 url-loader 或 asset module 进行处理) loader: 'html-loader', }, ] }, plugins: [ new HTMLWebpackPlugin ({ template: './src/index.html' }) ], mode: 'development' }
>>> 因为
url-loader
默认使用ES6
模块化解析, 而html-loader
引入图片是CommonJS
模块化, 直接解析会出问题[object Module]
, 因此需要关闭url-loader
的ES6
模块化5.2 利用
asset module
处理:const { resolve } = require('path') const HTMLWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: './src/index.js', output: { filename: 'built.js', path: resolve(__dirname,'build') }, module: { rules: [ { test: /.less$/, // 使用多个 loader use: ['style-loader', 'css-loader', 'less-loader'] }, // 不书写默认为 asset 处理 { test: /\.(png|svg|jpg|jpeg|gif)$/i, type: 'asset/resource', }, // 可省略 { test: /.html$/, // 处理 html 文件的 img 图片 (负责引入 img, 从而能被 url-loader 或 asset module 进行处理) loader: 'html-loader', }, ] }, plugins: [ new HTMLWebpackPlugin ({ template: './src/index.html' }) ], mode: 'development' }
-
html-webpack-plugin
插件在上述配置后会自动在build
文件夹中复制./src/index.html
文件生成index.html
文件并引入所有打包后的资源:6.1 打包文件效果:
6.2 网页效果:
webpack打包其他资源(字体图标):
-
src
文件下新建index.html
文件:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>webpack</title> </head> <body> <span class="iconfont icon-add"></span> <span class="iconfont icon-bottom"></span> <span class="iconfont icon-attachment"></span> <span class="iconfont icon-chart-pie"></span> </body> </html>
-
在阿里矢量图标库下载图标文件,在
src
文件下引入iconfont.css
,并引入其依赖文件(一般iconfont.css
中@font-face
中的src
内部的文件即为其依赖文件)引入后文件结构如下:
-
webpack.config.js
文件主要配置如下:3.1 利用
file-loader
处理const { resolve } = require('path') const HTMLWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: './src/index.js', output: { filename: 'built.js', path: resolve(__dirname, 'build') }, module: { rules: [ { test: /.css$/, use: ['style-loader', 'css-loader'] }, // 打包其他资源(除 html/css/js 资源以外的资源) { // 排除 html/css/js 资源 exclude: /.(css|js|html)$/, type: 'javascript/auto', loader: 'file-loader', options:{ esModule: false // 关闭 url-loader 的 ES6 模块化, 使用 CommonJS 解析 } } ] }, plugins: [ new HTMLWebpackPlugin({ template:'./src/index.html' }) ], mode: 'development' }
3.2 利用
webpack 5.0
默认处理const { resolve } = require('path') const HTMLWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: './src/index.js', output: { filename: 'built.js', path: resolve(__dirname, 'build') }, module: { rules: [ { test: /.css$/, use: ['style-loader', 'css-loader'] } ] }, plugins: [ new HTMLWebpackPlugin({ template:'./src/index.html' }) ], mode: 'development' }
-
html-webpack-plugin
插件在上述配置后会自动在build
文件夹中复制./src/index.html
文件生成index.html
文件并引入所有打包后的资源:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>webpack</title> <script defer src="built.js"></script></head> <body> <span class="iconfont icon-add"></span> <span class="iconfont icon-bottom"></span> <span class="iconfont icon-attachment"></span> <span class="iconfont icon-chart-pie"></span> </body> </html>
-
打包文件效果:
5.1 利用
file-loader
处理
5.2 利用 webpack 5.0
默认处理
6. 网页效果:
在 webpack 5 之前,通常使用:
raw-loader
将文件导入为字符串url-loader
将文件作为 data URI 内联到 bundle 中file-loader
将文件发送到输出目录资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换所有这些 loader:
asset/resource
发送一个单独的文件并导出 URL。之前通过使用file-loader
实现。asset/inline
导出一个资源的 data URI。之前通过使用url-loader
实现。asset/source
导出资源的源代码。之前通过使用raw-loader
实现。asset
在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用url-loader
,并且配置资源体积限制实现。
>>> 总结:webpack 5.0
新增 资源模块(asset module)
是一种模块类型,它允许使用资源文件(字体,图标等)而无需配置额外 loader。