记一次微信小程序从原生到Taro的迁移

原创
小哥 2年前 (2023-05-15) 阅读数 41 #大杂烩

前言

之前小程序用原生开发的,业务比较简单的时候是采用原生开发是比较高效的,但是随着业务的沉淀,场景逐渐复杂化,后续的维护及开发就会感觉到吃力。于是考虑采用taro框架, 我这里用的是 taro(react)工程模板,下面记录一下工程配置及一些问题。

  1. taro 项目拉取

这里比较简单,注意一下自己node 环境(>=12.0.0),按官网流程走下来即可:
Taro-快速开始-安装及使用

# 1. 使用 npm 安装 CLI
$ npm install -g @tarojs/cli

# 2. 命令创建模板项目
$ taro init myApp

#3. 按自己需要选择项目配置信息

  1. eslint规则配置(可选)

模板中自带的检验规范用不习惯,公司内部自有一套eslint规则,这里提一下替换方式提供参考。

  • 删除项目根目录的 .eslintrc 文件
  • 执行 npm install --save-dev eslint-config-dsued eslint babel-eslint eslint-plugin-react eslint-plugin-import eslint-plugin-jsx-a11y
  • 在根目录新建 .eslintrc.js 文件,将下方代码拷贝进去

    module.exports = { extends: dsued, globals: { ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: true, page: true, REACT_APP_ENV: true, DYSDK: true }, rules: { no-underscore-dangle: off, template-curly-spacing: off, indent: off } };

至此配置完成。

  1. 路径别名配置

开发过程中若想使用 @/path/path 方式的路径引入方式,需要进行路径配置:在 config>index.js 文件中添加以下代码:

const path = require(path);

const config = {
  alias: { // 别名设置
    @/components: path.resolve(__dirname, .., src/components),
    @/utils: path.resolve(__dirname, .., src/utils),
    @/service: path.resolve(__dirname, .., src/service)
  }
};
  1. 请求封装

  2. src 目录下新建 service 文件夹;

  3. src->service 文件夹下新增文件 baseUrl.js :

    // src -> service -> baseUrl.js const getBaseUrl = (url) => { let BASE_URL = ; if (process.env.NODE_ENV === development) { // 开发环境 - 根据请求不同返回不同的BASE_URL BASE_URL = https://xxxxxxxxx; } else { // 生产环境 BASE_URL = https://xxxxxxxxx; } return BASE_URL; };

    export default getBaseUrl;

  4. src->service 文件夹下新增文件 interceptors.js :

    // src -> service -> interceptors.js import Taro from @tarojs/taro;

    const HTTP_STATUS = { SUCCESS: 200, CREATED: 201, ACCEPTED: 202, CLIENT_ERROR: 400, AUTHENTICATE: 401, FORBIDDEN: 403, NOT_FOUND: 404, SERVER_ERROR: 500, BAD_GATEWAY: 502, SERVICE_UNAVAILABLE: 503, GATEWAY_TIMEOUT: 504 };

    /**

    • @description 获取当前页url */ const getCurrentPageUrl = () => { let pages = Taro.getCurrentPages(); let currentPage = pages[pages.length - 1]; let url = currentPage.route; return url; };

    const pageToLogin = () => { let path = getCurrentPageUrl(); Taro.clearStorage(); if (!path.includes(login)) { Taro.reLaunch({ url: /pages/login/index }); } };

    const customInterceptor = (chain) => {

    const requestParams = chain.requestParams; Taro.showLoading({ title: 加载中 }); return chain.proceed(requestParams).then(res => { Taro.hideLoading(); // 只要请求成功,不管返回什么状态码,都走这个回调 if (res.statusCode === HTTP_STATUS.NOT_FOUND) { return Promise.reject({ desc: 请求资源不存在 });

    } else if (res.statusCode === HTTP_STATUS.BAD_GATEWAY) {
      return Promise.reject({ desc: 服务端出现了问题 });
    
    } else if (res.statusCode === HTTP_STATUS.FORBIDDEN) {
      Taro.setStorageSync(Authorization, );
      pageToLogin();
      // TODO 根据自身业务修改
      return Promise.reject({ desc: 没有权限访问 });
    
    } else if (res.statusCode === HTTP_STATUS.AUTHENTICATE) {
      Taro.setStorageSync(Authorization, );
      pageToLogin();
      return Promise.reject({ desc: 需要鉴权 });
    
    } else if (res.statusCode === HTTP_STATUS.SERVER_ERROR) {
      return Promise.reject({ desc: 服务器错误 });
    } else if (res.statusCode === HTTP_STATUS.SUCCESS) {
      if (res.data.success) {
        return res.data;
      } else {
        Taro.showToast({
          title: res?.data?.msg || 请求失败,
          icon: none,
          duration: 2000
        });
        return Promise.reject(res.data);
      }
    }

    }).catch(error=> { Taro.hideLoading(); // console.error(error); return Promise.reject(error); }); };

    // Taro 提供了两个内置拦截器 // logInterceptor - 用于打印请求的相关信息 // timeoutInterceptor - 在请求超时时抛出错误。 // const interceptors = [customInterceptor, Taro.interceptors.logInterceptor] const interceptors = [customInterceptor];

    export default interceptors;

  5. src->service 文件夹下新增文件 request.js :

    // src -> service -> request.js import Taro from @tarojs/taro; import getBaseUrl from ./baseUrl; import interceptors from ./interceptors;

    interceptors.forEach(interceptorItem => Taro.addInterceptor(interceptorItem));

    class httpRequest {

    baseOptions(params, method = GET) { let { url, data, param } = params; const BASE_URL = getBaseUrl(url); // let contentType = "application/x-www-form-urlencoded"; let contentType = application/json;charset=UTF-8; contentType = params.contentType || contentType; const option = { url: BASE_URL + url, // 地址 data: data, // 传参 method: method, // 请求方式 timeout: 50000, // 超时时间 header: { // 请求头 content-type: contentType, Authorization: Taro.getStorageSync(Authorization) } }; return Taro.request(option); }

    get(url, data = , param) { let option = { url, data, param }; return this.baseOptions(option); }

    post(url, data, param, contentType) { let params = { url, data, param, contentType }; return this.baseOptions(params, POST); }

    put(url, data = ) { let option = { url, data }; return this.baseOptions(option, PUT); }

    delete(url, data = ) { let option = { url, data }; return this.baseOptions(option, DELETE); }

    }

    export default new httpRequest();

  6. 至此,封装完成,请求使用/再具体文件中发起请求:

    import request from @/service/request;

    // 小程序登陆验证 export const getToken = (params) => request.get(/login/code, params);

  7. 引入 taro-ui

比较简单,按官网流程安装使用即可: taro-ui 快速上手
这里值得需要注意的点:

  • 样式文件需要单独引入,taro-ui 样式文件是scss文件,如果是配置了less的项目需要单独安装一下 npm i @tarojs/plugin-sass -D
  • 如果 taro 版本号是 3.x 以上的话,taro-ui 也需要安装 3.x 以上版本,如: ^3.0.0-alpha.10 ,否则不支持。
  • 若想在taro-ui的 AtIcon 组件中使用外部 iconfont 图标,下载引入前 iconfont 项目设置中前缀需要改为* iconfont-
  • 使用主题覆盖时要注意先后顺序:

    / 先定义变量,再引入 Taro UI 默认样式 / / 改变主题变量,具体变量名可查看 taro-ui/dist/style/variables/default.scss 文件 / $color-brand: #4f8aff; $color-brand-light: #7ba7ff; $color-brand-dark: #3f6ecc;

    / 引入 Taro UI 默认样式 / @import "~taro-ui/dist/style/index.scss";

  1. 在taro中以h5标签的方式写小程序

taro小程序写法标签为 View,Text 等,且每次用标签前都要先引入使用,手感不好,taro v3.3以上版本为我们提供了 plugin-html 插件让我们可以脱离既定的小程序标签,像写h5页面一样开发。

  1. 首先下载安装插件 @tarojs/plugin-html

    yarn add @tarojs/plugin-html

  2. 然后在项目配置中添加使用插件

    // config/index.js config = { // ... plugins: [@tarojs/plugin-html] }

配置完成。

  1. 在taro中引入本地字体文件

taro模板项目中 Taro.loadFontFace 默认配置只能引入在线url,不支持本地字体文件引入,我们需要进行配置:

  1. 在项目配置中添加以下配置

    // config/index.js config = { // ... // 小程序端专用配置 weapp: { module: { postcss: { autoprefixer: { enable: true }, // 小程序端样式引用本地资源内联配置 url: { enable: true, config: { limit: 10240 // 文件大小限制 } } } } }, }

  2. 在全局或需要地方引入字体

    import Taro from @tarojs/taro; import { Component } from react; import BEBAS_1 from ./assert/font/BEBAS-1.ttf;

    class App extends Component {

    componentDidMount() { Taro.loadFontFace({ global: true, family: BEBAS-1, source: BEBAS_1 }); }

    render() { return this.props.children; } }

    export default App;

  3. 在taro中获取小程序中onLoad钩子函数中页面传参

    import Taro from @tarojs/taro; // useEffect(() => { let params = Taro.getCurrentInstance()?.router?.params; if (JSON.stringify(params) !== {}) { } }, []); //

持续沉淀中…

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除

热门