学习内容
- WebPack
- 安装,配置,使用
- webpack 基本配置
- 实现模板文件编译处理
- 实时打包
- 各种 loader
- css loader
- img loader
- base64 格式字符串
- babel-loader&preset&plugin关系
- @别名 和 默认后缀设置
WebPack
WebPack是静态资源文件打包机器
- 作用
- 对css文件打包处理
- 对less文件打包处理
- 对ttf文件打包处理
- 对img文件打包处理
- 对es6、es7做降级处理打包
- 对vue文件打包处理
- 以上内容经过webpack可以一次性全部做转码、降级处理,使得开发速度更快、更高效并且打包好的文件内容可以供所有浏览器识别使用,兼容性好
- 适用场景:
- spa(single program application单页面应用程序项目)项目(后台项目、手机移动端),spa项目页面请求数量小于500个
- vue、react、angular都要使用
- 值得一提的是:webpack是nodejs开发出来的
安装配置
- webpack官网:https://webpack.docschina.org/
- 步骤:
- 安装webpack和相关依赖包 yarn add -D webpack webpack-cli
- 在package.json文件中设置如下内容
"scripts":{ "build":"webpack" },
现在就可以在命令行中执行 npm run build 命令应用webpack
- 注意:
- 需要通过-D 开发依赖方式装包,yarn中 -D 和 --dev互为别名,npm中 -D 和 --save-dev互为别名
- 要安装两个依赖包webpack和webpack-cli,后者是前者的内部依赖
- build是自定义名称,scripts和webpack是固定的
运行和开发依赖
- 依赖包的安装分为两种方式:开发 和 运行
- 依赖包在项目生产中充当工具作用的,建议通过开发依赖方式安装,例如webpack
- 依赖包在项目生产完毕上线后都需要使用的,就通过运行依赖方式安装,例如jquery
- 安装运行依赖包(dependencies)
yarn add XXX // 直接装包,没有任何其他参数,旧npm版本中要求设置--save参数 例如jquery通过运行依赖方式安装 yarn add jquery
- 安装开发依赖包(devdependencies)
yarn add XXX --save-dev // 设置额外参数--save-dev(简称为-D) 例如webpack等依赖包通过开发依赖方式安装 yarn add -D webpack
问:依赖包如何区分是开发的还是运行的。
答:在 src/main.js 入口文件中通过require(或es6 import)引入的就是运行依赖包,否则是开发依赖包或在组件中引入的,也是运行依赖包
运行依赖和开发依赖包会分别配置到package.json的 dependencies和 devdependencies 段里边
我们通过软件仓库获得到别人开发的项目代码,如果还需要二次开发,就执行如下指令安装依赖包,其表示要安装全部的依赖包(运行的和开发的)
yarn
如果只是运行别人的项目,不做二次开发,就执行如下指令,表示只安装运行依赖包(去除了不用的开发依赖包,缩减了项目体积,转而运行更快了)
yarn --production
- 注意:
- npm通过开发依赖方式装为: npm i -D xxx 或 npm i --save-dev xxx (-D 与 --save-dev互为别名)
- yarn通过开发依赖方式装为: yarn add -D xxx 或 yarn add --dev xxx (-D 与 --dev互为别名)
- 不设置-D 默认就是运行依赖方式装包
- 开发依赖 在前端开发体现不明显,后端nodejs比较突出
打包实现
- 在src/index.html中注释掉 jquery.js 和 index.js 的引入
<!-- <script src="../node_modules/jquery/dist/jquery.js"></script> <script src="./index.js"></script> -->
- 在 src/index.js 中通过 import ** from ** 的方式引入 jquery
// 通过es6模块化方式,导入jquery(使用require方式导入也是可以的) // (把所有需要被打包的静态文件,都要放到该文件中) import $ from 'jquery' // 页面加载事件 $(function(){ $('li:odd').css('background-color','lightblue') })
- 做打包处理,执行指令 npm run build
打包完毕,就会在根目录生成dist目录,里边有main.js文件,其是jquery.js 和 隔行换色代码index.js 集成的体现
- 在src/index.html中直接引入 dist/main.js的打包文件做应用即可
<!--引入jquery--> <!-- <script src="../node_modules/jquery/dist/jquery.js"></script> --> <!-- <script src="./index.js"></script> --> <script src="../dist/main.js"></script>
- 原理:webpack默认会寻找 src/index.js 文件(本身包括两部内容:jquery.js和 隔行换色代码),编译处理之,并把结果输出到 dist/main.js里边去了
- 注意:
- webpack默认会生成dist目录存储打包文件,后期可以自定义该目录名字
- 打包好的文件名称为main.js,后期也可以自定义该文件名字
配置
打包模式
现在打包时会黄色警告信息,提示没有设置mode模式
- 步骤:
- 在项目根目录创建名称为 webpack.config.js 的配置文件
- 在webpack.config.js中做如下配置
module.exports = { mode: 'development' // 也可以配置为 production };
production:生产模式,打包好的文件内容是优化压缩的 development:开发模式,打包好的文件内容适合开发调试,有适当的空白、回车、注释
- 注意:
- webpack默认配置文件名称为webpack.config.js,也可以自定义为其他名字,但是package.json需要额外再做配置
- 项目开发阶段适合使用 development 开发模式,开发完毕部署上线后使用 production(打包的文件体积小,节省资源)
入口和出口文件
- src/index.js 改名字 为 src/main.js (该文件是项目的主入口程序文件)
- dist/main.js 改名字 为 dist/bundle.js
src/index.js 是被打包的文件,称为“入口文件”
dist/main.js 是打包后的文件,称为“出口文件”
- 步骤:在webpack.config.js文件中做如下内容配置;
const ph = require('path') module.exports = { // 1) 给项目配置入口文件路径名 entry: ph.resolve('./src/main.js'), // 2) 给项目配置出口文件路径名 output: { path: ph.resolve( './dist'), // 定义出口文件"目录" filename: 'bundle.js' // 定义出口"文件名称" } }
- 注意:
- 自行把物理文件src/index.js 的名字修改为 src/main.js 名字
- path模块获得一个文件的绝对路径名有如下两种方式:
- path.join(__dirname,xxx)
- path.resolve(xxx),resolve相比join要更简便,可以不用设置__dirname
- webpack是通过nodejs语言开发的,故在webpack.config.js文件中要通过require方式导入模块
在src/main.js主入口文件倒是可以使用import或require 引入其他文件
编译模板文件
打包时要同时打包入口index.html模板文件,并在打包后的模板文件中自动引入打包好的js文件
- 步骤:
- 安装html-webpack-plugin插件依赖包 yarn add -D html-webpack-plugin
- 在webpack.config.js中给上述插件做配置
const ph = require('path') var HtmlWebpackPlugin = require('html-webpack-plugin'); // 引入插件模块 module.exports = { // 给webpack配置功能插件 plugins: [ new HtmlWebpackPlugin({ // 设置“源模板”文件的路径名 template:ph.resolve('./public/index.html') }) ], }
- 在public/index.html 不要引入任何js文件
- 现在打包处理 npm run build,就会发现在dist目录里边生成了index.html模板文件,内容来自 public/index.html,并且有自动引入打包好的js文件在里边
- 注意:
- 如果不给HtmlWebpackPlugin内部配置template源模板文件,则会生成一个没有任何业务逻辑的、空的html模板文件
- 创建public目录,并把文件 src/index.html 挪到这个目录中
- dist目录文件不要做开发,要去src下边开发应用
实时打包
给webpack开启实时打包功能,使得浏览器可以随时查看修改代码的效果
项目的src目录里边任何一个文件被改动都需要重新打包看效果,工作效率太低 怎么做呢? 答:利用“实时打包”工具实现高科技效果,业务代码随时修改、浏览器随时查看对应效果
- 步骤:
- 安装实时打包依赖包 yarn add -D webpack-dev-server
- 在webpack.config.js文件做如下配置
127.0.0.1 是每个电脑都拥有并且不变的ip地址,直接使用即可,推荐使用
端口号码:12306,理论值:1到65535之间 - 在package.json中做如下配置
"scripts": { "serve": "webpack-dev-server" },
serve:是自定义名称,可以修改为其他
webpack-dev-server:是固定名称 - 现在在项目根目录命令行终端中可以执行 npm run serve 指令,就自动打开浏览器查看项目运行效果了
- 注意:
- npm run serve 会开启一个前台服务,不能关闭,否则没有实时加载效果了
- 实时打包的内容提供者是“内存”,不需要借助物理文件支持,本身也不生成dist目录和相关打包文件
- 实时打包本身有创建了一个http服务,并支持访问
loader
loader是webpack编译处理不同类型文件的工具(本质是函数)
css文件对应 style-loader、 css-loader
less文件对应 style-loader、 css-loader、 less-loader
img文件对应 url-loader 、file-loader
es6、es7文件对应 babel-loader
- 安装使用loader
- 安装loader相关依赖包 yarn add -D css-loader style-loader
- 在webpack.config.js中给loader做如下配置
module.exports = { // 给webpack配置各种loader module: { rules: [ { // 1) css之loader配置 test: /\.css$/, // 正则匹配名字以.css结尾的文件,然后交给如下loader处理 use: ['style-loader', 'css-loader'], } ] } }
- 现在重启实时打包服务(npm run serve),css样式效果就ok了
- 注意:
- style-loader、css-loader有严格的前后设置顺序,不要颠倒
- 有的文件需要配置一个loader、有的需要配置多个,不固定
css-loader 与 style-loader 的不同作用
- 两个loader的作用:
- css-loader:该loader可以实现在主入口js文件中以import/require的方式引入css
- style-loader:该loader可以实现在html运行文档中以style标签的形式嵌入css 内容,使得样式生效
- css-loader第一个顺序执行,style-loader之后再执行
css之loader运行原理:
-
webpack.config.js只要把css相关的loader给配置好,那么import引入的css文件内容就被打包到dist/bundle.js文件里边去了
-
bundle.js文件在执行的时候会通过 style 标签把css样式嵌入到应用程序文档里边
img loader
- 安装loader依赖包 yarn add -D url-loader file-loader
- webpack.config.js配置loader,具体如下:
module.exports = { // 给webpack配置各种loader module: { rules: [ { // 2) img图片之loader配置 test: /\.(png|jpg|gif)$/i, loader: 'url-loader', options: { limit: 8192 } } ] } }
- 现在实时打包服务重启(npm run serve),发现背景图片效果已经呈现
- 注意:file-loader不需要配置,条件满足会自动调用
img loader 解读
相关loader作用
:
file-loader 把符合条件的图片文件重新打包生成在dist目录
url-loader:负责把图片变为字符串使用,并嵌入到应用文档里边,好处:可以节省一个http请求资源
limit作用
:
文件大小 大于limit:8192 字节的,就走 file-loader,
文件大小 小于等于8192 字节的,就走 url-loader
url-loader limit:8192(8k)是判断图片大小的阈值,该阈值建议大小是10k左右
注意
:
-
index.html模板里边设置的**标签图片**不能被webpack处理
-
大小大于10kb的图片不适合变为字符串,不划算,因为图片变为字符串后,大小会更大
- 图片在哪:
- 大图片(大于8192字节):重新生成在dist目录,名字会重新定义
- 小图片(小于等于8192字节):以base64格式字符串集成到打包的bundle.js文件里边,之后以style标签方式植入到运行应用文件里边,本身不会消耗http资源
创建子级目录存储图片
- 给url-loader配置参数,具体如下:
module.exports = { module: { rules: [ { test: /\.(png|jpg|gif)$/i, loader: 'url-loader', options: { limit: 8192, outputPath:'image' // 创建子级目录存储生成的图片 } } ] } }
- 注意:
- 经过上述配置,以后再做物理打包npm run build,大图片就被存储到 dist/image 目录里边去了
- outputPath本身是file-loader的参数,但是可以给url-loader配置,它们内部会自动传递
- base64格式字符串说明
- Base64是一种基于64个可打印字符来表示二进制数据的方法,是二进制数据的封装,一个图片最本质的内容是二进制数据,当前应用级别无法直接表示,需要借助base64格式
babel-loader&preset&plugin关系
不同类型文件在webpack中都有不同的loader做解析处理,es6高级标准对应loader的名称为“babel-loader”,单这个loader也不做具体事宜
- 关系:
- webpack:是大老板
- babel-loader:二级承包商,负责找到preset干活
- preset:对常用plugin做封装,方便安装使用,是三级承包商,负责找到plugin干活
- plugin:每个es6高标准技术都对应一个plugin做降级处理,最底层苦力
- preset:对常用plugin做封装,方便安装使用,是三级承包商,负责找到plugin干活
- babel-loader:二级承包商,负责找到preset干活
- webpack:是大老板
- 在webpack中,不同类型的es6高级语法做降级处理都有独立的工具做编译转换处理,这个工具称为plugin
例如:
let 有独立的plugin做降级
``字符串 有独立的plugin降级
箭头函数 有独立的plugin降级
......
这样一个项目如果使用多种类型的es6高级语法,势必需要安装配置许多plugin,比较繁琐,前辈针对该情况已经有解决方案
有preset机制,preset是针对许多“常用”plugin的集合,这样只需要安装配置preset一个依赖包就可以降级许多es6高级语法
- 注意:
- webpack本身有功能扩展插件plugin,例如html-webpack-plugin
- babel-loader也有plugin的概念
@别名和默认后缀
步骤
- 在之前的VueCLI脚手架项目中执行 指令 vue inspect > output.js (获得webpack的相关配置信息)
- webpack.config.js文件中做如下配置
const ph = require('path') module.exports = { resolve: { alias: { // 配置别名 '@': ph.resolve('./src'), }, // 配置自动识别后缀名 extensions: [ '.js', '.vue', '.json', '.css', '.less' ], }, }
现在在src/main.js中就可以使用@符号,代表src目录绝对路径名,被引入各种类型文件的后缀名字也可以省略了
- 注意:项目中应用程序文件的彼此引入操作并不都是在src/main.js中进行的,有的时候许多目录层次很深的文件也要对其他文件进行引入,使用@符号会极大方便项目的开发,方便文件移植