1 Webpack打包图片
加载图片案例准备
JavaScript // 引入图片模块 import zznhImage from "../img" // 创建img元素 const imgEL = document.createElement('img') imgEL.src = zznhImage document.body.append(imgEL)
比较常用的使用图片的方式是两种:
img元素,设置src属性
其他元素(如div),设置 background-image的css属性;
认识asset module type
我们当前使用的webpack版本是webpack5:
在webpack5之前,加载这些资源我们需要 使用一些loader 如 law-loader url-loader
在webpack5开始,我们可以直接使用 资源模块类型(asset module type)来替代上面这些loader
资源模块类型(asset module type) 通过添加4种新的模块类型,来替换所有这些loader;
asset/resource 发送一个单独的文件并导出URL
之前通过使用file-loader实现
asset/inline 导出一个资源的data URL
之前通过使用 url-loader实现
asset/source 导出资源的源代码
之前通过使用raw-loader实现
Asset 在导出一个 data URI 和发送一个单独的文件之间自动选择
之前通过使用url-loader 并且配置资源体积限制实现
Asset module type的使用
如 加载图片 我们可以使用下面的方式
JavaScript { test:/\.(png|svg|jpe?g|gif)$/ }
但是 如何可以自定义文件的输出路径和文件名呢?
一:修改output,添加assetMouduleFilename属性(比较少)
JavaScript output:{ assetModuleFilename:"abc.png" },
二:在Rule中 添加一个generator属性,并且设置fulename
JavaScript generator:{ // 占位符 // name:指向原来的图片名称 // ext: 扩展名 // hash 哈希值 webpack生成的hash值 filename:"[name]_[hash:8].[ext]" }
介绍几个常用的placeholder:
[ext]:处理文件的扩展名
[name]: 处理文件的名称
[hash]: 文件的内容 使用MD4的散列函数处理,生成一个128位的hash值(32个十六进制)
url-loader的limit效果
开发中 往往是 小的图片需要转换,但是大的图片直接使用图片即可
因为 小的图片转换base64之后可以和页面一起被请求,减少不必要的请求过程,
而 大的图片也进行转换,反而会影响页面的请求速度
我们需要两个步骤来实现:
一:将type修改为asset
二:添加一个parser属性 指定dataUrl条件 添加maxSize属性
2 Webpack打包JS代码
为什么需要babel?
事实上, 在开发中 很少直接去接触babel 但是babel对于前端开发来说 目前是不可缺少的一部分:
开发中 我们想要使用ES6+的语法 想要使用TS 开发React项目 它们都离不开babel的
所以,学习babel对于 理解代码从编写到线上的转变过程 至关重要;
Babel到底是什么?
babel是一个 工具链 主要用于 旧浏览器或者环境中将ECMAScript2015+代码转换为向后兼容版本的Js; 包括 语法转换 源代码转换等
JavaScript [1,2,3].map((n)=>n+1) [1,2,3].map(function(n){ return n+1 })
Babel命令行使用
babel本身可以作为 一个独立的工具 不和webpack等构建工具配置来单独使用
如果我们希望在命令行尝试使用babel 需要安装如下库:
@babel/core: babel的核心代码,必须安装
@babel/cli: 可以让我们在命令行使用babel
JavaScript npm install @babel/cli @babel/core -D
使用babel来处理我们的源代码
src:是源文件的目录
--out-dir:指定要输出的文件夹dist;
JavaScript npx babel src --out-dir dist;
插件的使用
我们需要转换箭头函数 那么我们就可以使用箭头函数转换相关的函数:
JavaScript npm install @babel/plugin-transform-arrow-functions -D npm babel src --out-dir dist --plugin=@babel/plugin-transform-arrow-functions
查看转换后的结果: 发现 const并没有转换成var
因为plugin-transform-arrow-functions并没有提供这样的功能
需要使用plugin-transform-block-scoping来完成这样的功能
JavaScript npm install @babel/plugin-transform-block-scoping -D npx babel src --out-dir dist --plugins=@babel/plugin-transform-block-scoping,@babel/plugin-transform-arrow-functions
Babel的预设preset
如果要转换的内容过多,一个个设置比较麻烦,我们可以使用预设(preset)
安装@babel/preset-env预设:
JavaScript npm install @babel/preset-env -D
执行如下命令:
JavaScript npx babel src --out-dir dist --presets=@babel/preset-env
3 Babel和babel-loader
babel-loader
我们通常会在构建工具中通过配置babel来对其进行使用 如 webpack中
我们就需要去安装相关依赖:
如果之前已经安装了@babel/core,那么这里不需要再安装
JavaScript npm install babel-loader -D
我们可以设置一个规则,在加载js文件时,使用我们的babel
JavaScript module:{ rules:[ { test:/\.m?js$/, use:{ loader:"babel-loader" } } ] }
Babel-preset
webpack根据我们的预设来加载对应的插件列表 讲其传递给babel
如常见的预设有三个:
Env
React
TypeScript
安装preset-env:
JavaScript npm install @babel/preset-env ========================== { test:/\.m?js$/, use:{ loader:"babel-loader", options:{ presets:[ ["@babel/preset-env"] ] } } }
4 Webpack打包Vue
编写App.vue代码
在开发中 会编写Vue相关代码.webpack可以对vue代码进行解析
JavaScript <template> <div> <!-- html --> <h2 class="title">{{title}}</h2> <p class="content">我是内容,哈哈哈哈哈哈</p> </div> </template> <script> export default { data(){ return { title:"我是vue标题" } } } </script> <style> .title { color: blue; font-size: 100px; } .content { color: red; font-size: 30px; } </style>
JavaScript import {createApp} from "..." inmprt App from './vue/...' // Vue代码 createApp(App).mount("#app")
App.vue的打包过程
我们需要vue-loader:
JavaScript npm install vue-loader -D
在webpack的模版规则中进行配置
JavaScript { test:/\.vue$/, loader:"vue-loader" }
@vue/compiler-sfc
打包依然会报错,因为我们必须添加@vue/compiler-sfc来对template进行解析
JavaScript npm install @vue/compiler-sfc -D
另外我们需要配置对应的Vue插件:
JavaScript const {VueLoaderPlugin} = require('vue-loader/dist/index') ------------------------------------------------------------ new VueLoaderPlugin()
重新打包即可支持App.vue的写法
另外 我们也可以编写其他的.vue文件来编写自己的组件;
5 resolve模块解析
resolve用于设置模块如何被解析:
开发中 会有各种各样的模块依赖,这些模块可能来自于自己编写的代码,也可能来自于第三方库
resolve可以帮助webpack从每个require/import语句中 找到需要引入到合适的模块代码
webpack使用 enhanced-resolve 来解析文件路径
webpack能解析三种文件路径:
绝对路径
由于已经获得文件的绝对路径,因此不需要再做进一步解析.
相对路径
使用import或require的资源文件所处的目录 被认为是上下文目录
在import/require中给定的相对路径 会拼接此上下文路径,来生成模块的绝对路径
模块路径
在resolve.modules中指定的所有目录检索模块;
默认值为['node_modules'] 所以默认会从node_modules中查找文件
我们可以通过设置别名的方式来替换初识模块路径
确实 文件还是文件夹
如果是一个文件:
如果文件具有扩展名,则直接打包文件
否则 使用resolve.extensions选项作为文件扩展名解析
如果是一个文件夹:
会在文件夹中根据resolve.mainFiles配置选项中指定的文件顺序查找;
resolve.mianFiles的默认值是['index']
再根据resolve.extensions来解析扩展名
extensions和alias配置
extensions是解析到文件时自动添加扩展名
默认值为['.wasm','.mjs','.js','.json.'];
所以 如果我们代码中像添加加载 vue或者jsx 或者ts等文件时 我们必须自己写上扩展名
另一个非常好用的功能是配置别名alias:
当我们项目的目录结构比较深的时 或者一个文件的路径可能需要../../../这种路径片段
我们可以给某些常见的路径起一个别名
JavaScript resolve:{ extensions:[".wasm",".mjs",".js",".json",".jsx",".jsx",".ts",".vue"], alias:{ "@":resolveApp("./src"), pages:resolveApp("./src/pages"), }, },