前端工程化项目的思考

news2024/11/16 3:42:57

这是一篇个人使用前端工程开发项目的思考,希望可以帮助到你。完全是一篇综合概念应该是很多东西,我也不清楚会有多少字,估计会对刚刚开始的人看起来比较迷,但也是没有办法的事情

  • 1.前端脚本语言开发的作者我想应该也想不到js会发展到今天这样和后端语言一较高下的时候,这一切的起源我想应该就是各大浏览器的发展,那时候刀耕火种js运行在各种浏览器上面,通过各大公司不同的js引擎,有很多不同的ast规范,各种兼容可谓是百家争鸣,现在的市场流行谷歌浏览器,然后谷歌的v8引擎,和node出现,导致js开启处理文本io流字符串各种功能,实现了与其他后端语言一样的服务。

  • 2.node的出现我们从原生的写法创建一个后端项目然后把HTML放入,比如Java的jsp PHP的视图,这些老家伙的书写方法,开始被时代所放弃,出现了基于node的工程化项目。

  1. 1.工程化的过程出现了低级打包工具 高级打包工具,所谓的低级就是只管字符的处理,不管执行,高级就是基于这些编译后的结果,融入了各种服务然后执行,编译各种写法,比如Babel的出现让我们可以使用最新的语法,只需要引入包,使用各种typescript
    js的变体,coffee jsx ts 这些东西的出现,把js的书写和弱项开始弥补,出现了
    postcss Autoprefixer
    让兼容样式写法变成了工具,使用更加方便我们可谓是站在巨人的肩膀上面。

  2. 1.通常现在的项目都是起一个所谓的cli脚手架 是一个综合性很强的集成工具包,融入了框架,样式,资源,服务,打包,编译,处理字符,使用node底层,来帮助我们开发。这一系统的融合,得益于一些流行的npm库,node是这个环境的启动者。

  3. 1.比如我们使用npm run dev所谓自定义的执行脚本命令,也是node读取当前目录或者全局指令注册下的结果,读当前的packagejson文件,然后执行script,如果里面是可执行脚本命令比如node
    index.js,node就会帮你,如果是自定义的比如vue-cli这样的自定义的命令,他会去依赖文件里找bin文件夹寻找可执行的命令,使用commander
    插件来提高自定义cmd操作,bin文件会注册cmd命令在你安装库的使用,如果是全局安装会自动注册,如果是局部也会自动执行,在node的安装过程中,分环境比如本地和生产,很多包也是这样用做区别,安装插件也分全局或者局部,我们也可以自行注册全局的包别名。

  4. 1.使用npm run dev 会触发vue-cli serve 综上这自定义库的自定义命令并不是node自带的,但确实node提供插件可创建的东西,所谓的serve 会开启一个基于net
    http协议的端口 也会启动一个socket
    ws协议,同时在本地客户端生成通信的websocket文件脚本,通常我把cli文件下面的src叫做客户端因为这一部分不会和node有关系,内容是更新于浏览器html内容,除这之外都是服务器node提供操作的地方,但是src里的操作js
    资源 图片 服务 import require async 等等所有的东西都基于高级打包工具,比如webpack。

  5. 1.webpack帮我们处理js vue css img 字体 资源 图片各种 压缩 打包 编译 框架 服务等等,把一切浏览器不认识的东西变成认识的东西,这一切的功能都来自webpack自身的强大,提供了一系统了loader
    plugin。入口文件 开始 就把所有资源处理调用对应的loader 在运行过程中使用plugin来拓展功能,

  6. 1.可编译js并不是他的功能,而是babel在webpack什么的拓展,比如babel-loader,这只是遇见js文件的时候就叫给他,比如vue
    就给到vue-loader 然后返回js 然后又给到babel-loader
    ,遇到css就给到css-loader,很多loader我们不一说明,我们重点描述一下Babel。

  7. 1.交给Babel的js,我们看出一段字符串,一段在非专业人士看起来没有规律的字符串,这一段给到babel。Babel是如何处理的?
    1.其实 babel 的工作流程和编译原理中的编译流程相对简单。我们可以归纳如下几个步骤: 词法分析 语法分析 代码转换 代码生成.
    2.其中分为词法分析和预发分析两步可以合并成解析(parse)过程
    从上图可以看到编译从开始到结束有一个最重要的东西,抽象语法树/AST 的知识,以下简称 AST,babel 编译代码的整个流程都离不开它。

抽象语法树是高级编程语言(Java、JavaScript 等)转换成机器语言的桥梁。解析器会根据 ECMAScript 标准「JavaScript 语言规范」来对代码字符串进行词法分析,拆分成一个个词法单元,再遍历各个词法单元进行语法分析构造出 AST。

词法分析
词法分析阶段是对源代码进行“分词”,它接收一段源代码,然后执行一段 tokenize 函数,把代码分割成被称为 tokens 的东西。tokens 是一个数组,由一些代码的碎片组成,比如数字、标点符号、运算符号等等等等,
词法分析处理网站
在词法分析之后,语法分析会把词法分析得到的 tokens 转化为 AST,有兴趣的可以阅读一下 babel 源码 babel 转化 AST 源码
ast处理网站
@babel/parser 包的 parse 方法传入源代码,进行词法分析合语法分析,最终生成 AST 抽象语法树
@babel/traverse 包 traverse 方法接收 AST 抽象语法树并对其进行遍历(深度遍历),在此过程中对节点进行添加、更新及移除等操作。 这是 Babel 或是其他编译器中最复杂的过程,同时也是插件将要介入工作的地方,插件部分我们后边在讲
@babel/generator 包 generator 方法接收的 AST 抽象语法树转换成字符串形式的代码,同时还会创建源码映射(sourceMap,根据传入的参数控制是否生成 sourceMap)
@babel/traverse 的 traverse 转换过程是深度遍历整颗树对节点进行操作,它会访问树中的所有节点。这时候该方法第二个参数就起到作用了。这个参数是一个对象,对象每个属性是一个钩子函数。这个对象的属性值除了支持 AST 语法树节点的 type 值外,还有 enter,exit;也就是在遍历每个节点的时候会先进入 enter 钩子函数,如果存在该节点对应的钩子函数,还会执行该钩子函数,最后在访问该节点结束的时候执行 exit 钩子函数…

@babel/types,它的作用是创建、修改、删除、查找ast节点。另外从上边知道AST的节点也是分为多种类型,比如ExpressionStatement是表达式、ClassDeclaration是类声明、VariableDeclaration是变量声明等等,同样的这些类型都对应了其创建方法:t.expressionStatement、t.classDeclaration、t.variableDeclaration,也对应了判断方法:t.isExpressionStatement、t.isClassDeclaration、t.isVariableDeclaration。这个插件往往和traverse遍历插件一起使用,因为types只能对单一节点进行操作,一般是在对节点的深度遍历中使用。
babel.types 用做判断深度遍历ast时候处理对应type来提供方便

module.exports = function (babel) {
  return {
    visitor: {
      Identifier(path) {
        console.log(path.type, path.node.name);
      }CallExpression(path) {
        if (
          path.node.callee &&
          babel.types.isIdentifier(path.node.callee.object, { name: "console" })
        ) {
          path.remove();
        }
      },
    },
  };
};

如图的babel.type是核心插件@babel/core提供的,他会把 @babel/parser @babel/traverse @babel/generator @babel/types 集成在一起
依赖如下

"dependencies": {
    "@ampproject/remapping": "^2.1.0",
    "@babel/code-frame": "^7.18.6",
    "@babel/generator": "^7.20.5",
    "@babel/helper-compilation-targets": "^7.20.0",
    "@babel/helper-module-transforms": "^7.20.2",
    "@babel/helpers": "^7.20.5",
    "@babel/parser": "^7.20.5",
    "@babel/template": "^7.18.10",
    "@babel/traverse": "^7.20.5",
    "@babel/types": "^7.20.5",
    "convert-source-map": "^1.7.0",
    "debug": "^4.1.0",
    "gensync": "^1.0.0-beta.2",
    "json5": "^2.2.1",
    "semver": "^6.3.0"
  },
  "deprecated": false,
  "description": "Babel compiler core.",
  "devDependencies": {
    "@babel/helper-transform-fixture-test-runner": "^7.19.4",
    "@babel/plugin-syntax-flow": "^7.18.6",
    "@babel/plugin-transform-flow-strip-types": "^7.19.0",
    "@babel/plugin-transform-modules-commonjs": "^7.19.6",
    "@babel/preset-env": "^7.20.2",
    "@jridgewell/trace-mapping": "^0.3.8",
    "@types/convert-source-map": "^1.5.1",
    "@types/debug": "^4.1.0",
    "@types/gensync": "^1.0.0",
    "@types/resolve": "^1.3.2",
    "@types/semver": "^5.4.0",
    "rimraf": "^3.0.0"
  },

现在流行的vite 或者说 很多cli 都是基于Babel Babel 基于webpack 或者 rollup 提供了自己的拓展,方便他们使用,然后这个核心插件会默认开启读取.babelrc文件里的presets plugins
.babelrc文件内容如下

{
  "presets": ["@babel/preset-env"],
  "plugins": ["./my-babel-plugin/index.js", "./my-babel-plugin/console.js"]
}

index.js内容如下

module.exports = function (babel) {
  return {
    visitor: {
      Identifier(path) {
        console.log(path.type, path.node.name);
      },
    },
  };
};

babel处理ast的过程中我们可以使用它规定的插件规范,提供一些自定义的功能,来使用。
babel插件的规范,
如下所示

const obj = babel.transformFileSync(file, {
  //   babelrc: true,
  plugins: [
    function MyPlugin(babel) {
      return {
        visitor: {
          Identifier(path) {
            console.log(path.type, path.node.name);
          },
        },
      };
    },
  ],
  presets: [function text() {}],
});

babel形参是babel-type提供的 path的在读取到对应ast时候触发的函数 path会获取到对应的当前代码内容对象,然后结合babel-type来验证ast类型 就可以改变当前代码的内容从而变成自己需要的返回结果。

在这里插入图片描述
在这里插入图片描述
可以创建vscode调试文件 来debug结果内容 方便我们开发独立的插件,
babel还提供了插件单元测试 这个可以自行了解。

基于Babel部分的使用是完全融入了webpack你到处可以看见他的身影,就不过多讨论。

webpack 构建 了cli
vite又是怎么构建的 集成了rollup rollup使用了Babel版的rollup 然后还有esbuild 字符串级别操作打包依赖工具,服务还是node。
rollup是用来发布工具库使用的,比如某一个插件js,然后打包各种兼容版本的脚本,比如umd 形式。
可以运行于import 浏览器 引入,如果注意区别了 node环境 那也可以使用 ,因为node目前支持了import。
在这里插入图片描述

webpack其实也可以完成如上打包发布更加可以使用babel来兼容es5,

在这里插入图片描述
两种操作如上图。

处理了js写法,之后启动的服务和public资源用是怎么回事了?

关于cli启动服务和资源运行

在使用的过程中,我们不知道有没有关注执行了vue-cli serve 端口就起了 然后页面也有了,
然后热更新也存在了。
让我们一步步来解释,

基于webpack的配置 首先我们肯定知道 要让命令生效 肯定是离不开node 所谓一个命令必然是执行的一个文件。

  1. vite里是起了一个net http 端口 然后结合请求与资源响应
    来生成页面,比如默认很快就起来了,因为他是通过请求发送再解析文件,比如 xxx/ 根地址输入 会处理对应的路径 然后使用HTML模板
    把入口文件的js执行 然后触发各种请求 然后返回js脚本 来形成单页面内容,也就是后端的node
    有一个机制,对应模块变成了对应请求,各种小模块变成了整合大模块的依赖,比如lodash
    依靠esbuild预编译处理打包依赖,方便后续使用直接读取,也为了保证路径的正确,重写了资源路径 设置了node module的别名。
    至于他的热更新,也是自己通过实现自己的socket与页面通信脚本,每次更新就有一个新的hash产生然后响应给到浏览器页面
    重新响应注入脚本;
  2. webpack是使用node服务一样的 你可以选择使用net http 也可以使用成熟的koa express 来处理资源,
    因为单页面的路由处理需要变成了 history的时候就需要这些服务框架来配合,
    使用不同的综合性工具开发思路与注意的地方是不同的,比如个性化都会提供一些内置的操作和指令来帮助我们使用。
    比如webpack的插件和预编译是自己提供的 根据自己内置的taptable来发出钩子函数来运行。
    vite是集成了rollup插件然后融入了自己的一部分,父类是继承rollup 所以学vite
    必了解rollup,至于esbuild只在启动的时候发挥作用,打包部署运行编译还是rollup提高。
  3. 很多框架不同文件后缀都是得益于操作各种文件里的字符串。使用各种手段来完成对应的转化js植入。
    这是工程化发展到今天我们要做的思考和准备,这一切的根据是node与ast规范 做为根本,这些东西涉及了js引擎 比如v8
    执行的过程,是如何把js处理成ast树,如何通过把ast树编译成最终机器语言认识的东西,在编译的过程里,为了符合规范,提出了各种概念,比如原型,全局变量,作用域,函数,变量类型,各种操作符,这些都是v8处理后
    为了我们方便书写
    提出了概念,所以深入的走下去,热爱的人必然会揭开它的神秘面纱,从而使js更进一步,在各种字符串的处理中,为了方便我们需要学各种正则,如何存的更优雅,需要具备完善的数据结构知识,学习算法来帮助我们更加了解前人之伟大。
    大家输写的变量如何存如何回收,如何处理,如何让函数执行提升,如何让请求发送,如何渲染页面,如何使动画更优化,如何让加载更快,如何让缓存利用起来,如何让我们的项目成为自己的艺术品,如何将js的生态和前沿的东西使用到项目里,这些思考我想回填满作为年轻人的努力青春吧,
    付出多少获取多少,代码就是这样,大家分享这些。

前端未来会怎么样

大家目前涉及了pc端网页 移动端网页 客户端应用 手机app 甚至还有一些web3的技术比如区块,数字孪生,虚拟现实,3D地球,二维地图,三维地图,甚至现在的各种动画三D引擎,webgl,可以说方向众多,但我们的精力是有限的,公司是有业务范围的,所以在熟悉公司开发项目的任务,空闲时间可以学一些其他方向 给自己未来提前打好基础,比如混迹各种群来帮助你我认识流行社区的大佬。
有人说前端是不是要学后端,我只能说curd的操作你用不了一年两年就熟练,但人生有几十年,所以不能将一两年的东西使用好多年吧,在这些时间里必然要为了未知做出探索,涉及后端数据库,安全,服务器,客户端,应用,有人会问这些学的玩吗,我说肯定学不完,那为啥要卷,因为为了填满年轻时候空闲的时间,顺手学点东西,然后提高自己的见识,毕竟如此人生,学也是一辈子,不学也是一辈子,有人忙忙碌碌,就活了前二十年,有人一直坚持学习,活了后面几十年,发光发热,所以我们必然要努力的前进。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/79229.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spark

1 Spark作业提交流程 2 Spark提交作业参数 1)在提交任务时的几个重要参数 executor-cores —— 每个executor使用的内核数,默认为1,官方建议2-5个 num-executors —— 启动executors的数量,默认为2 executor-memory —— executor…

【OpenCV学习】第9课:形态学操作的应用-提取水平线丶垂直线

仅自学做笔记用,后续有错误会更改 理论 图像在进行形态学操作的时候, 可以通过自定义的结构元素实现结构元素对输入图像的一些对象敏感丶对另外一些对象不敏感, 这样就会让敏感的对象改变而不敏感的对象保留输出。 通过使用两个最基本的形态学操作 - 膨…

华为云服务-运维篇-弹性负载均衡

文章目录一、什么是负载均衡二、我们为什么需要负载均衡1、生活中需要它的类似场景2、生活场景中协调者(负载均衡)作用3、协调者(负载均衡)引入后的变化三、华为云平台-如何做负载均衡弹性负载均衡-ELB四、总结一、什么是负载均衡 负载均衡构建在原有网…

【数据挖掘】薪酬分段对应工作经验/学历画柱状图【招聘网站的职位招聘数据预处理】

文章目录一.需求背景1.1 需求分析二.数据处理(对给定职位,汇总薪酬分段对应工作经验要求数据,画柱状图;)2.1 事前准备2,1 处理开始三.数据处理(对给定职位,汇总薪酬分段对应学历要求数据,画柱状图;)四.附源…

吉林大学 超星慕课 高级语言程序设计 实验08 结构化程序设计(2022级)

本人能力有限,发出只为帮助有需要的人。 建议同学们自己写完后再进行讨论。 其中的代码均没能在oj上进行测试,因此可能有误,请谅解。 除此以外部分题目设计深度优先搜索,因此可以分别用递归和堆栈实现,堆栈方法为了…

JavaScript进阶教程——异步编程、封装Ajax

异步编程 什么是同步与异步: 同步:一件事没做完,只能等待,完成之后再去做另一件事 异步: 两件事可以同时进行 前端开发中最常见的两种异步情况: ajax: 向后台请求数据计时器: setInterval se…

Python学习基础笔记四十一——sys模块

sys模块是与Python解释器交互的一个接口。 sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0),错误退出sys.exit(1) sys.version 获取Python解释程序的版本信息 sys.path 返…

ARM Cortex M3处理器概述

Cortex-M3概述 2004年ARM发布作为新型Corex处理器内核系列首款的Cortex-M3处理器。 STM32系列基于专为高性能、低成本、低功耗的嵌入式应用专门设计的ARM Cortex-M内核。 STM32命名规则 STMF103xx系统结构 1.使用高性能的ARM Cortex-M3 32位RISC内核 2.工作频率为72MHZ 3.内…

shell脚本监控文件夹文件实现自动上传数据到hive表

sh createtb.sh “tablename;field1,field2,field3,field4,field5,field6,field7;partition1,partition2” 数据库名:observation (脚本里写死了) 表名:tablename 指定名:field1,field2,field3,field4,field5,field6,f…

分别使用Alpine、Docker制作jdk镜像

目录 制作 jdk 1.0 镜像 ——Docker 1.创建文件夹上传jdk的安装包,和在同级目录下编写Dockerfile文件 2.编写 Dockerfile 文件 3.执行Dockerfile文件,初次依赖镜像的时候会下载相应镜像 优化制作jdk镜像(缩小内存大小)——使用alpine …

【致敬世界杯】球迷(我)和足球的故事

目录 一、第一次接触足球 二、回味无穷的2018世界杯 三、致敬世界杯 3.1 源代码 3.2 思路 3.3 关于图片 一、第一次接触足球 踢足球是一项优秀的运动,它可以锻炼身体,增强团队合作精神,并为人们带来快乐和满足感。回忆起小学时候第一次…

OpenCV和RTSP的综合研究

一、RTSP是什么?用来干什么? RTSP(Real Time Streaming Protocol),RFC2326,实时流传输协议,是TCP/IP协议体系中的一个应用层协议,由哥伦比亚大学、网景和RealNetworks公司提交的IET…

四旋翼无人机学习第14节--PCB Editor简单绘制封装-1

文章目录1 前言1.1 网络获取1.2 封装软件生成1.3 立创商城封装转化1 前言 在之前的博客中,我们绘制了封装所需的焊盘,有了焊盘我们就可以绘制封装啦。当然封装的获取有很多途径,下面我来总结一下。 1.1 网络获取 (有需要的可以下载哦&…

华为eNSP模拟器配置MSTP多实例生成树

传统的stp、rstp有其必然的缺陷 1.统一局域网内所有的vlan共享一个生成树,无法在vlan间实现数据流量的负载均衡。 2.链路利用率低,被阻塞的冗余链路不承载任何流量,造成了带宽的浪费,还可能造成部分vlan报文无法转发。MSTP在它们…

计算机毕业设计springboot+vue基本微信小程序的学习资料共享小程序

项目介绍 前台为用户使用的,包括下面一些功能: ① 资料发布:用户可以将想要共享的资料发布到小程序,供他人购买。 ②搜索 :分为按名称搜索和分类搜索,用户可选择其中一种方式,检索自己所需要的资料。 ③ 查看资料详情:用户可以…

学委必备小工具——筛选未提交人数【python小工具】

问题描述 作为一个学委,通常的任务就是收取班级作业,然后向老师报告当前未交人员的名单 JS版本:实现以一个表格数据查询另一个表格【JS】 之前我已经尝试通过用JS实现了,本质上差别其实也不是很大,只是对于JS来说&…

Java基础之《netty(11)—netty模型》

一、简单说明 1、工作原理示意图 netty主要基于主从Reactors多线程模型做了一定的改进,其中主从Reactor多线程模型有多个Reactor。 2、说明 (1)BossGroup线程维护selector,只关注Accept事件。 (2)当接收到…

[附源码]Node.js计算机毕业设计出版社样书申请管理系统Express

项目运行 环境配置: Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术: Express框架 Node.js Vue 等等组成,B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境:最好是Nodejs最新版,我…

第十一章 特征选择与稀疏学习

11.1 子集搜索与评价 我们将属性称为特征,对当前学习任务有用的属性称为相关特征、没什么用的属性称为无关特征。还有一类特征称为冗余特征,它们所包含的信息能从其他特征中推演出来,冗余特征在很多时候不起作用,去除它们会减轻学…

redis之如何应对并发访问问题

写在前面 本文一起看下Redis的并发访问控制。 1:单线程的Redis为什么会有并发问题 我们知道,Redis是单线程的,为什么还是会有并发问题呢?没错,如果是单命令操作的话肯定没有并发问题,但考虑事务的场景&a…