前端工程化思想

工程化的意义

一家公司想要实现盈利,就需要各个岗位的人分工合作,对各个岗位的管理就是组织管理, 组织管理的目标就是发挥资源的最大效能, 组织管理也需要各种工具, 以降低管理成本, 提高组织效能, 比如SOP, 打卡器...

前端工程化就是前端这个岗位的管理工具, 让不同能力的工程师可以顺利的参与产品开发, 降低开发成本, 提高开发效率

模块化

模块化的思想就是分解和聚合, 分解契合的是主观规律(学科分类), 聚合契合的是客观规律(合作攻关)

函数模块化
// 判断数据是否是素数
function isPrime(n) {
  
}
// 数组排序
function sort(arr) {
  
}
// 筛选数组中的素数后排序
function getSortEndPrimies(arr) {
  const newArr = []
  for(let i = 0; i < arr.length;i++) {
    if(isPrime(arr[1])) {
      newArr.push(arr[i])
    }
  }

  return sort(newArr)
}
文件模块化

在JS中, 函数的模块是很成熟的, 但是文件的模块化存在全局污染和依赖混乱的问题

模块化要解决的就是文件级别的分解和聚合问题, 拆分的时候能够隐藏内部实现, 不污染全局, 聚合的时候, 依赖不要混乱,明确表达依赖关系

// 数组排序
function sort(arr) {
  console.log("降序排序!");

}
// 变量
var name = '张三'
// 数组排序
function sort(arr) {
  console.log('升序排序!');
}
// 打印name
function priName() {
  console.log(name);
}
<body>
  <script src="./1.js"></script>
  <script src="./2.js"></script>
  
  <script>
    // 全局变量污染
    // 同名的方法发生覆盖
    sort() // '降序排序'

    // 依赖关系混乱
    // 无法看出文件的依赖关系 
    priName() // '张三'
  </script>
</body>

模块化标准
CommonJS:
  • 简称CJS, 是比较早的, 比较成熟的社区解决方案
  • 运行时: 只有代码运行期间才确定依赖关系
if(xxx) {
  // 运行到这一行代码, 才确定依赖关系
  const a = require('./1.js')
} else {
  const b = require(./'2.js')
}
  • 不利于代码的优化
Ecmascript Module:
  • 简称ESM, 是官方的模块化解决方案
  • 编译时: 代码编译期间就确定了依赖关系
// 代码不远行, 也知道依赖关系
import xxx from './1.js'
// 动态导入: ESM也支持运行时, 但是用的少
import('./2.js')
  • 有利于代码的优化
其他标准:
  • AMD, CMD, UMD, 都已经很少使用
具体实现

标准只是一些规则, 标准的落实要由各种环境去实现, 不同环境支持的标准不一样

浏览器: 只支持ESM标准

node : 支持CJS和ESM标准

构建工具: 不同的构建工具支持的标准不同, 但是webpack, vite, cli都是同时支持CJS和ESM

包管理

所谓包就是一系列模块的集合, 模块化的最小单元就是函数, 其次是文件(模块), 最大单元就是包

  1. 包和框架在概念上是相近的,都是提供一些列方法, 帮助我们更好的开发
  2. 在代码结构上是完全不同的:
  • 包不限制代码结构, 只要引入包就可以使用相关方法, 比如react/jquery/lodash
  • 框架限制代码结构, 要在特定的地方书写特定的代码, 比如vue/uni-app

包管理器

包管理器就是解决使用包的一系列问题, 比如包的下载, 包的卸载 包的升级, 包的发布, 版本控制等

官方的包管理器是npm, npm提供了cli(命令行)工具, 第三方也有GUI(图形化)工具

基于npm还衍生出了yarn和pnpm, 也是很常用的

JS工具链

虽然JS本身也在不断迭代, 但是面对复杂的工程化问题, 我们还是需要使用更多的工具, 提高开发体验

1.兼容性问题

API兼容

随着JS版本的迭代, 一些新的API增强了开发能力, 但是新的API在老版本中不能使用, 这就是API兼容问题

  1. 解决API兼容问题的思路, 就是polyfill(翻译: 垫片或者填充物), 流行的工具就是core-js
  2. 他的作用也很简单, 老版本中缺失add方法, 我就定义一个add方法然后填充进去, 这样就抹平了版本的API差异
  3. 但是core-js并不是万能的, 如果API需要环境的支持, 就没办法通过垫片的方法解决, 不过这种情况很少出现

语法兼容

扩展运算符... / 解构 / async和await 这些新的语法, 在老版本中不支持, 这就是语法兼容问题

  1. 解决语法兼容问题的思路, 就是语法转译, 把高级语法转成普通语法
  2. 不同的语法要用不同的工具做兼容性处理
  3. 有专门做扩展运算符兼容的工具, 也有专门做async/await兼容的工具 ...
2.语言缺陷

所有的语言都有自己的特点, 同时也会有自己的缺点, 通过工具可以优化这些的短板, 核心思想也是语法转译

  1. jsx语法<h1>xxxx</h1> 转译为 Rreact.createElement('h1', 'xxxx') 普通语法
  2. ts语法通过 tsc 工具转译为js语法
3.babel

通过工具解决问题是很爽的事情, 但是那么多的工具都要手动安装配置, 就会非常繁琐, 所以就出现了整合工具

  1. 目前流程的工具是babel, 他提供了各种预设, 当然也支持自定义, 就可以快速使用一系列工具, 解决各种问题
  2. 预设就是默认的一堆插件, 用的最多的预设就是@babel/preset-env

CSS工具链

总体来说CSS存在两类问题, 语法缺失(循环, 判断, 拼接) 和 功能缺失(颜色函数, 数学函数. 自定义函数)

  1. sass/less/style等语言是css的超集, 扩展了css的能力,
  2. 这些语言有自己的编译器,通过编译器可以把代码编译成浏览器识别的css代码
  3. postcss是后编译器的一种, 可以对css代码进一步优化
  4. postcss本身不处理代码, 通过配置插件, 实现不同的处理效果, 常见插件有:
  • autoprefixer: 自动添加厂商前缀
  • cssnano: 压缩css体积
  • purgecss: 移除未使用的css
  • css module: css模块化

构建工具

现代的开发过程中, 开发和维护的工程与运行时的工程是不一致的, 所以需要构建工具帮助我们进行结构转译

常见的构建工具
  1. webpack, rollup, esbuild, turbopack, snowpack, grunt, gulp, Rspack
  2. 这些构建工具的作用都是一样的, 就是进行结构转译
  3. 在转译的过程中, 构建工具要考虑三个问题
  • 哪种工程更适合开发和维护
  • 哪种工具更适合运行时
  • 如何转译(打包)
  1. 以上那么多的构建工具, 无非是在这三个层面有不同的考虑
webpack
1. 打包过程:

把入口文件转换成字符串, 构建AST(抽象语法树), 识别出导入语句, 通过模块查找规则, 识别模块间的依赖关系

指定入口文件

指定路径别名

2. 开发服务器:

如果每次修改代码, 都需要打包, 再运行打包结果, 就太麻烦了, 所以webpack内嵌了开发服务器

  1. 开发服务器的名称webpack-dev-server, 使用了express技术
  2. live server插件用的也是这个开发服务器
  3. 开发服务器的作用就是托管静态资源, 通过服务地址就可以访问静态资源, 并且支持HMR(热更新)

3. 文件指纹

文件指纹主要影响缓存, 首次访问资源, 服务器会返回资源, 为了提高加载速度, 浏览器会缓存资源, 当资源变化时, 缓存的资源也要更新, 就是通过文件指纹的对比实现的

资源一旦变化, 文件指纹就会重新生成, 所以浏览器会请求新的资源, 实现资源的更新

4. css modules

打包会合并css, 为了防止css合并过程中可能的类名冲突, 就需要对类名进行处理

5. 源码地图

源码地图记录着源码和打包代码的对应关系, 可以方便我们对代码进行断点调试

  • 设置fasel可以关闭源码地图
  • 也可以设置其他模式

脚手架

脚手架是对构建工具的进一步封装, 提供交互界面和工程模板, 简化构建工具的配置和使用

常见的脚手架: vue-cli vite cra umijs

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值