2024前端项目模板集合(一):Taro? Uniapp? 什么才是小程序的最佳工程实践呢?!(内有完整模板请收藏)

前言

在2023年末的这个节点,聊起小程序开发,离不开当前市场占有率最高的两个框架:Taro和Uniapp,那么到底哪个框架更符合当前主流开发,更好,更易用呢?具体的工程该怎么搭建呢?

在回答上诉问题之前,我们先来讲一个故事,并且回答几个问题。

如果太长不看可以直接拉到后面享用模板!

很久很久以前,一个公司要面向用户提供某项业务,得做一个app。开发维护的成本都极其高昂。 后来微信公众号出现,以公众号为流量入口,h5作为业务载体也风靡一时。但是h5毕竟有它的局限性:性能和体验问题使得它始终不能承载太复杂的业务,中小公司还是需要一个app。

后来,由于微信公众号已经承接不了蓬勃发展的需求了,小程序在历史滚滚长河中登场。 它的出现解决了很多掣肘公众号+h5的问题,例如:

  • 性能好,提供了相当原生的用户体验,加载快。
  • 提供wx-sdk,也就具备获取微信提供的泛能力,例如转发、分享等、支付扫一扫等。
  • 依托微信的用户体系和生态。

简单来说就是,微信搞了一个基础,大家在上面做开发可以又吃又拿。在流量池子里玩,别人还给你铲子,那就没什么理由不搞一搞小程序了。

当时几乎每家公司都把自己原来由h5和app承接的业务转移到小程序上,大树底下好乘凉。 但是由于小程序的处于安全和性能考虑的特殊架构,使得一开始在没有小程序框架出现前,小程序的开发体验不是特别好,市面上出现了专门的小程序开发工程师,那这不就是又变相提高了开发成本?

于是Taro、Weapp、Uni-app、Mpvue、Remax等小程序框架出现,但是经过这几年的大浪淘沙,基本就剩下Taro和Uni-app两家了。

一、小程序基础架构

小程序到底是怎么架构的,为啥他的原生开发有如此难用的语法和开发体验?

下图是小程序的架构:

摘一下官方文档:

​网页开发渲染线程和脚本线程是互斥的,这也是为什么长时间的脚本运行可能会导致页面失去响应,而在小程序中,二者是分开的,分别运行在不同的线程中。网页开发者可以使用到各种浏览器暴露出来的 DOM API,进行 DOM 选中和操作。而如上文所述,小程序的逻辑层和渲染层是分开的,逻辑层运行在 JSCore 中,并没有一个完整浏览器对象,因而缺少相关的DOM API和BOM API。这一区别导致了前端开发非常熟悉的一些库,例如 jQuery、 Zepto 等,在小程序中是无法运行的。同时 JSCore 的环境同 NodeJS 环境也是不尽相同,所以一些 NPM 的包在小程序中也是无法运行的。

小程序的架构和普通的浏览器渲染不同,传统的浏览器渲染是单线程的,也就是渲染和逻辑的执行是互斥的,这个大家都学过。但是小程序的架构设计是双线程的设计,页面的渲染和js的逻辑执行是分成两个线程来执行的。同时,为了达到原生app类似的良好体验,小程序的页面的渲染是多页面渲染的(多个webview),可以理解为开了多个浏览器来渲染多个页面,可以参考上图。

那么为什么要使用双线程的架构模式呢? 原因主要有以下几点:

  • 为了很好的注入WXSDK
  • 为了确保安全

WXSDK就是上图和前文所阐述的微信的一些jsApi的集合,提供了微信的丰富原生能力和一些内部的方法。 那这些sdk在传统浏览器的架构中,得通过网络请求的方式去加载,这非常影响用户体验,甚至会出现白屏的情况。而在微信公众号的解决方案是做了离线缓存,一个公众号有一定容量的缓存大小。这样做是改善了用户体验,但是会造成微信的缓存越来越多,想起微信动辄几十个g的空间占用,是不是更加蛋疼了。 所以为了解决这些问题,小程序的出现必将采取新的架构,也就是在native层中往页面动态注入sdk来实现,也就是one weixin one sdk,这样是不是很爽。 当前,不只是sdk,还有底层基础库Service等很多服务都是事先放在Native层中的。

解决SDK的问题,那怎么确保安全呢? 我们知道,js是非常开发和灵活的,与此同时带来的是相对的不安全性。而微信和浏览器端不一样,微信对于安全的要求是要更高一级的,例如操作dom(就存在可能变相获取到用户的敏感数据),网页的跳转等,执行动态脚本等。这些都是不受控的,而微信又希望控制这些过程,以达到安全的目的。于是,就产生了封装一个沙箱来运行js,而不是在webview中运行js的理念。于是在ios采用专门jscore,在安卓上采用x5内核来执行js,也就是逻辑层,就能对js的灵活进行一定的管控。

以上,就是双线程架构的由来,而双线程架构能够使得逻辑的归逻辑,渲染的归渲染,各司其职,安全且原生,看起来是不是十分完美。

但是!

什么都有个但是!

就苦了我们这帮苦哈哈的前端-马上被大厂裁员---或者被ai淘汰---程序员。

小程序的原生开发因此就有了和开发传统webapp不一样的地方,不管是语法还是生态,写起来,真是不太得劲。

直到了英特奈熊-taro 和uni-救世主-app的出现,使得大家能够采用习惯的vue和react语法以及相关的生态来进行小程序的开发。下面我们就就正式展开,如何使用Taro和Uniapp搭建一个规范的前端项目工程。

二、Uniapp篇

我们先来快速搭建一个uniapp的前端工程,该工程采用vue3+vite技术栈,使用uview组件库,使用vscode开发,tyepscript 封装并且使用如下项目规范的工具:

  • eslint: 负责校验代码
  • prettile: 格式化代码
  • stylelint: 校验和格式化样式代码
  • commitlint:校验git提交
  • lint-staged: 只对当前更改的进行校验
  • husky:在提交前做所有的校验

vscode配置

px2rem方案

写一个cli完成这些事情,

cicd, 开发和生产环境的区分和部署 git项目 命名和ui规范 vite配置 npm管理 路由方案 数据存储方案 请求方案 低代码方案 docker和gitlab

1.初始化项目

js 复制代码
//根据uniapp官方文档,快速创建一个vue3+vite项目,并使用vscode开发
npm install -g @vue/cli
npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project

2.使用lint工具链来保证代码风格和质量

为什么要确保代码风格的统一?

在多人的项目开发过程中,代码风格的统一非常重要,因为代码不仅是给机器阅读的,同时也是给人阅读的。为了避免不同风格的代码导致的满屏红和难以阅读维护,同时确保代码的质量,需要一定的规范去约束。

如何统一代码风格和质量?

通过如:eslint prettier stylelint commitlint tsc等主流lint的工具的使用。配合husky lintstaged vscode插件来实现自动化的代码规范的检查和格式化,把语法错误,和低质量代码在开发阶段规避掉。人只需要关注开发逻辑本身,这就是lint的工具链的意义。

2.1 Eslint的使用

简介

ESLint 是在 ECMAScript/JavaScript 代码中识别和报告模式匹配的工具,它的目标是保证代码的一致性和避免错误。

说人话就是,搞一个配置文件,里面有不同的规则(rules),eslint通过这个配置文件来来检验代码的规范是否符合要求。现在常见的规则如:Airbnb JavaScript 代码规范Standard JavaScript 规范Google JavaScript 规范等等,大部分情况下,直接采用以上开发规范就好了。

开始干!先安装eslitnt!

注意:全文的安装包都带有版本号,如想用最新版本会存在版本不兼容导致校验失败的问题。

js 复制代码
yarn add eslint@8.55.0 -D

以及安装如下eslint衍生包

  • @typescript-eslint/eslint-plugin@latest(为了支持TypeScript)
  • @typescript-eslint/parser@lates(为了支持TypeScript)
  • eslint-plugin-vue@latest(为了支持Vue语法的解析)
  • @vue/eslint-config-typescript(Vue官方提供的在Vue项目中使用 TypeScript 时的代码规范检查)
js 复制代码
yarn add eslint-plugin-vue@9.19.2 @typescript-eslint/eslint-plugin@6.14.0 @typescript-eslint/parser@6.14.0 @vue/eslint-config-typescript@12.0.0 -D

在vscode中安装插件prettier和eslint

然后在项目的根目录新建一个.eslintrc.js,然后把以下热乎乎的eslint配置粘贴进去。

注意:下面的配置和上面安装的衍生包是对应的,因为extends中用的别人的配置,所以就要有相应的包来支持,不然就会出现配置不生效的问题。如果要自定义配置,请注意这一点。

js 复制代码
//.eslintrc.js
module.exports = {
  root: true, // 表示这是项目的根 ESLint 配置。
  env: {
    node: true, // 指定环境为 Node.js。
  },
  //extends 用于继承其他配置的属性。你可以基于已有的配置来构建自己的配置,避免从头开始定义所有的规则。也就是抄别人的成熟模板~
  extends: [
    "plugin:vue/vue3-essential", // Vue3 的基本配置规则。
    "eslint:recommended", // 推荐的 ESLint 配置规则。
    "@vue/typescript/recommended", // Vue中 TypeScript 的推荐配置规则。
    "@vue/prettier", // 扩展 Prettier 的 ESLint 配置规则。
    "@vue/prettier/@typescript-eslint", // 扩展 TypeScript 特定规则的 Prettier ESLint 配置。
  ],
  //parserOptions是解析器选项,对eslint语法解析器的能力进行定制
  parserOptions: {
    ecmaVersion: 2020, // 指定要使用的 ECMAScript 版本(在这种情况下为 ES2020)。
    ecmaFeatures: {
      jsx: true, // 启用 JSX 解析。
    },
  },
  //rules-这里就是具体的规则配置拉
  rules: {
    "prettier/prettier": "error", // 强制执行 Prettier 规则,如果不遵循则生成错误。
    "no-console": process.env.NODE_ENV === "production" ? "warn" : "off", // 在开发中允许 console.log,在生产中警告。
    "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off", // 在开发中允许 debugger,在生产中警告。
    "@typescript-eslint/no-unused-vars": [
      "error",
      {
        vars: "local", // 强制局部变量使用。
        args: "none", // 不允许未使用的函数参数。
        varsIgnorePattern: "usePresenter|model|reactive", // 在未使用变量检查中忽略特定变量名。
        caughtErrors: "none", // 不允许未使用的捕获的错误。
      },
    ],
    "@typescript-eslint/no-explicit-any": 2, // 不允许使用 any 作为类型声明。
    eqeqeq: 2, // 强制使用严格相等(=== 和 !==)。
    "max-lines": ["error", 800], // 强制文件的最大行数。
    complexity: ["error", 20], // 强制函数的最大圈复杂度。
    "require-await": "error", // 强制异步函数有 await 表达式。
    "vue/multi-word-component-names": "off", // 禁用 Vue 文件中多词组件名称的规则。
    "@typescript-eslint/no-empty-function": 1, // 警告空函数。
    "no-shadow": "error", // 强制变量名不与其作用域链中的变量名重复。
    "@typescript-eslint/ban-types": "off", // 禁用对特定类型的禁令。
    "@typescript-eslint/no-non-null-assertion": "off", // 禁用对非空断言的禁令。
    "vue/valid-v-model": "off", // 禁用 Vue 文件中 v-model 使用的规则。
  },

  overrides: [
    {
      files: [
        "**/__tests__/*.{j,t}s?(x)", // 对 __tests__ 目录下的文件进行覆盖。
        "**/tests/unit/**/*.spec.{j,t}s?(x)", // 对单元测试文件进行覆盖。
      ],
      env: {
        mocha: true, // 指定 Mocha 测试环境。
      },
    },
  ],
};

同样在根目录配置一个.eslintignore来忽略检测的文件

js 复制代码
.eslintignore
*.sh
node_modules
*.md
*.woff
*.ttf
.vscode
.idea
dist
/public
/docs
.husky
.local
/bin
Dockerfile
/types

配置完.eslintrc.js之后,就完事了吗? 搜德麻跌! 这个配置文件中这个prettier是什么意思?

ok,术业有专攻,eslint可以做两件事:

  • 代码的规范和质量的检查和提示,例如使用未声明的变量、修改const变量、字符串是否是双引号等
  • 按照规范格式化这些不符合要求的代码

prettier在第二件事中,做的比eslint好。因为除了js/ts外,prttier还支持对多种语言进行格式化,如vue、html、css、less、scss、json、jsx等等,是一个比较综合的代码格式化工具,且lint的速度更快。于是,我们一般把格式化这件事情,交给prettier去做。

2.2 prettier和eslintの故事

首先我们安装一下prettier

js 复制代码
yarn add prettier@2.7.1 -D

在项目根目录下新建.prettierrc.js配置文件,然后再把下面第二份热乎乎的配置粘贴进去,并按照你们的团队规范自定义修改

js 复制代码
// .prettierrc.js
module.exports = {
  printWidth: 80, //一行的字符数,如果超过会进行换行,默认为80
  tabWidth: 2,  // 一个 tab 代表几个空格数,默认为 2 个
  useTabs: false, //是否使用 tab 进行缩进,默认为false,表示用空格进行缩减
  singleQuote: false, // 字符串是否使用单引号,默认为 false,使用双引号
  semi: true, // 行尾是否使用分号,默认为true
  trailingComma: "all", // 是否使用尾逗号
  bracketSpacing: true, // 对象大括号直接是否有空格,默认为 true,效果:{ a: 1 }
  htmlWhitespaceSensitivity: "ignore",// 在 HTML 中空格的敏感性,"ignore" 表示忽略空格敏感性
  endOfLine: "auto" // 换行符的风格,"auto" 表示自动识别当前操作系统的换行符风格
};

接下来我们把prettier和eslint一起打配合,各司其职。

细心的朋友发现了,为啥eslint一套规范,prettier一套规范,到底听谁的?不冲突吗?

所以我们得安装如下两个包,来确保校验的归eslint,格式化的归prettier,不能打架!

  • @vue/eslint-config-prettier(用来覆盖eslint本身的规则配置)
  • eslint-plugin-prettier(让prettier来接管eslint --fix也就是代码修复格式化的能力)
js 复制代码
yarn add @vue/eslint-config-prettier@6.0.0 eslint-plugin-prettier@4.2.1 -D

写到这,再回顾之前写的.eslintrc.js的配置中,涉及prettier的部分代表什么意思了。

js 复制代码
//.eslintrc.js
module.exports = {
  ...
  extends: [
    ...
    "@vue/prettier", // 扩展 Prettier 的 ESLint 配置规则。
    "@vue/prettier/@typescript-eslint", // 扩展 TypeScript 特定规则的 Prettier ESLint 配置。
  ],
  //rules-这里就是具体的规则配置拉
  rules: {
    "prettier/prettier": "error", // 强制执行 Prettier 规则,如果不遵循则生成错误。
    ...
  }
};

我们在package.json中定义一个脚本,然后执行 yarn run lint 就可以通过命令行的方式格式化代码了。

js 复制代码
{
  "scripts": { 
    ...
    "lint": "eslint --ext .js,.jsx,.ts,.tsx --fix --quiet ./src", }
}

在开发阶段,我们还可以通过vite插件在开发阶段进行扫描,以命令行的方式展示出代码中的规范问题,并直接定位到源文件。如下图:

先安装插件

js 复制代码
 yarn add  vite-plugin-eslint -D

然后再vite.config.js中进行配置

js 复制代码
import viteEslint from "vite-plugin-eslint"; //1.引入

export default defineConfig({
  plugins: [...省略其他插件, viteEslint()], //2.使用
});

这样重新运行项目,开发时就会有上图的提示了。

2.3 样式的规范-stylelint

先来一个官网的说明

Stylelint 是一个强大、先进的 CSS 代码检查器(linter),可以帮助你规避 CSS 代码中的错误并保持一致的编码风格。 Stylelint 的强大源于:

  • 拥有超过 100 条内置规则 来检查最新的 CSS 语法和功能
  • 支持 插件 以创建你自己的规则
  • 自动 修复 大多数代码格式上的问题
  • 支持创建或扩展 可共享的配置
  • 可定制,让其而符合你的需求
  • 经过 15000 多次的单元测试,保证其健壮性
  • 被大型公司所采用,例如 Google 和 GitHub

我们建议在使用 Stylelint 的同时使用格式化工具 Prettier。代码检查工具和格式化工具是互相补充的,能够辅助你编写一致且正确的代码。

同样,根据官网所说,stylelint也是一个代码检查工具,专注于样式的检查,格式化的部分还是交给prettier来完成。

先安装依赖

  • stylelint
  • stylelint-prettier(stylelint插件,用于集成Prettier格式化工具
  • stylelint-config-prettier(禁用了stylelint中与Prettier冲突的规则
  • stylelint-config-standard(基于stylelint的预定义配置,包含了一系列的标准化的规则和推荐配置
  • stylelint-config-clean-order(它提供了一套规则,用于指定CSS属性排序的顺序
js 复制代码
yarn add stylelint@13.2.1 stylelint-prettier@1.1.2 stylelint-config-prettier@8.0.1 stylelint-config-standard@20.0.0 stylelint-config-clean-order@2.0.0 -D

然后再根目录下新建文件.stylelintrc.js,把以下配置粘贴进去。

这个配置文件指定了 stylelint 的配置选项,具体解释见注释。通过这些配置,stylelint 将遵循 Standard 规范的代码规则,并与 Prettier 格式化工具兼容,同时禁用了一些特定的警告和错误。

js 复制代码
module.exports = {
  processors: [], // 指定要使用的处理器,这里为空数组,表示不使用任何处理器
  extends: [
    "stylelint-config-standard", // 继承了 stylelint-config-standard 配置,即使用了 Standard 规范的代码规则
    "stylelint-prettier/recommended", // 继承了 stylelint-prettier/recommended 配置,即使用了与 Prettier 推荐配置兼容的 stylelint 规则
    "stylelint-config-prettier", // 继承了 stylelint-config-prettier 配置,用于确保 stylelint 和 Prettier 规则的一致性
    "stylelint-config-clean-order", // 继承了 stylelint-config-clean-order 配置,用于定义 CSS 属性的排序规则
  ],
  rules: {
    "prettier/prettier": true, // 启用 prettier/prettier 规则,确保代码与 Prettier 的格式化规则一致
    "at-rule-no-unknown": null, // 禁用对未知@规则的警告或错误
    "no-empty-source": null, // 禁用对空样式表的警告或错误
    "unit-no-unknown": null, // 禁用对未知单位的警告或错误
    "no-descending-specificity": null, // 禁用对特异性下降的警告或错误
    "selector-pseudo-class-no-unknown": null, // 禁用对未知伪类的警告或错误
    "declaration-block-no-duplicate-properties": null, // 禁用对重复属性的警告或错误
    "selector-type-no-unknown": null, // 禁用对未知选择器类型的警告或错误
    "block-no-empty": null, // 禁用对空块的警告或错误
    "font-family-no-missing-generic-family-keyword": null, // 禁用对缺少通用字体系列关键字的警告或错误
    "declaration-block-no-shorthand-property-overrides": null, // 禁用对简写属性覆盖的警告或错误
  },
};

我们在 package.json 中,增加如下的 scripts 配置:

js 复制代码
{
  "scripts": {
    // ...省略其他配置
    // stylelint 命令
    "lint:style": "stylelint --fix \"src/**/*.{css,scss}\""
  }
}

执行yarn run lint:style即可完成样式代码的规范检查和自动格式化。

在 VSCode 中安装Stylelint插件,这样能够在开发阶段样式代码问题,见下图。

同样,vite也有stylelint插件支持,可以实现在终端提示样式问题,如下图

安装vite-plugin-stylelint

js 复制代码
yarn add vite-plugin-stylelint -D //支持vite>=3.0

然后再vite配置文件中配置

js 复制代码
import viteStylelint from 'vite-plugin-stylelint';

{
  plugins: [
    // ...其他插件
    viteStylelint({
      //排除node_modules的文件
      exclude: /node_modules/
    }),
  ]
}

到此就可以在开发阶段实现stylint的格式检查和格式化了。

2.4 在vscode保存时自动格式化

在前面的配置已经实现了对规范的检查和格式化,但是格式化的操作只能通过执行命令行来进行,例如:yarn lint。

这样操作十分麻烦,有没有办法让我们每一次保存文件的时候,都自动格式化代码呢?答案是肯定的。 我们做如下的配置。

未完待续:moropo pnpm、路由跳转,生命周期 组件使用,全局变量配置,piana hooks...

相关推荐
GIS程序媛—椰子7 分钟前
【Vue 全家桶】7、Vue UI组件库(更新中)
前端·vue.js
DogEgg_00114 分钟前
前端八股文(一)HTML 持续更新中。。。
前端·html
ZL不懂前端16 分钟前
Content Security Policy (CSP)
前端·javascript·面试
木舟100920 分钟前
ffmpeg重复回听音频流,时长叠加问题
前端
王大锤439131 分钟前
golang通用后台管理系统07(后台与若依前端对接)
开发语言·前端·golang
想进大厂的小王1 小时前
项目架构介绍以及Spring cloud、redis、mq 等组件的基本认识
redis·分布式·后端·spring cloud·微服务·架构
我血条子呢1 小时前
[Vue]防止路由重复跳转
前端·javascript·vue.js
黎金安1 小时前
前端第二次作业
前端·css·css3
啦啦右一1 小时前
前端 | MYTED单篇TED词汇学习功能优化
前端·学习