tarojs

关于Taro

Taro 是一个开放式跨端跨框架解决方案,支持使用 React/Vue/Nerv 等框架来开发 微信 / 京东 / 百度 / 支付宝 / 字节跳动 / QQ / 飞书 小程序 / H5 / RN 等应用。

Taro 3 可以支持转换到 H5、ReactNative 以及任意小程序平台。

Taro环境安装

node version >= 16.20.0 --> nvm 管理 node 版本

安装cli工具

npm install -g @tarojs/cli
# yarn
yarn add global @tarojs/cli

sass安装错误,尝试执行
npm install -g mirror-config-china

查看taro全部版本信息
npm info @tarojs/cli

初始化项目

taro init taroApp

Taro 会默认开始安装项目所需要的依赖,安装使用的工具按照 yarn > cnpm > npm 顺序进行检测

开发编译运行

taro通过不同的命令可以build编译成不同端的代码

编译模式【dev | build】

  1. dev模式(增加 --watch 参数) 将会监听文件修改
    dev 模式生成的文件较大,设置环境变量 NODE_ENV 为 production 可以开启压缩,方便预览,但编译速度会下降
  2. build模式(去掉 --watch 参数) 将不会监听文件修改,并会对代码进行压缩打包。
├── dist                        编译结果目录
|
├── config                      项目编译配置目录
|   ├── index.js                默认配置
|   ├── dev.js                  开发环境配置
|   └── prod.js                 生产环境配置
|
├── src                         源码目录
|   ├── pages                   页面文件目录
|   |   └── index               index 页面目录
|   |       ├── index.js        index 页面逻辑
|   |       ├── index.css       index 页面样式
|   |       └── index.config.js index 页面配置
|   |
|   ├── app.js                  项目入口文件
|   ├── app.css                 项目总通用样式
|   └── app.config.js           项目入口配置
|
├── project.config.json         微信小程序项目配置 project.config.json
├── project.tt.json             抖音小程序项目配置 project.tt.json
├── project.swan.json           百度小程序项目配置 project.swan.json
├── project.qq.json             QQ 小程序项目配置 project.qq.json
|
├── babel.config.js             Babel 配置
├── tsconfig.json               TypeScript 配置
├── .eslintrc                   ESLint 配置
|
└── package.json

编译配置

└── config                      项目编译配置目录
    ├── index.js                默认配置
    ├── dev.js                  开发环境配置
    └── prod.js                 生产环境配置

小程序配置

└── src                         源码目录
    ├── app.js                  项目入口文件
    ├── app.css                 项目总通用样式
    └── app.config.js           项目入口配置

app.config.js 对应小程序规范的全局配置文件 app.json,优势在于它是 JS 文件可以编写逻辑。配置以微信小程序的全局配置为规范

全局样式:
import ‘./app.css’

  1. 页面配置
    page.config.js 对应小程序规范的页面配置文件 page.json,优势在于它是 JS 文件可以编写逻辑。配置以微信小程序的页面配置为规范。

  2. 页面样式
    页面的样式文件可以通过 ES6 规范的 import 进行引入。
    import ‘./index.css’

  3. 页面路由
    页面路由与小程序规范一致,需要在小程序全局配置 app.config.js 中进行配置。

  4. 项目配置
    └──project.config.json 微信小程序项目配置 project.config.json

各类小程序平台均有自己的项目配置文件,Taro 支持对它们进行适配。

Babel 配置
└── babel.config.js Babel 配置

ESLint 配置
└── .eslintrc ESLint 配置

相关命令

查看 Taro 所有命令及帮助
taro --help

查看环境及依赖检测
taro info

诊断项目的依赖、设置、结构,以及代码的规范是否存在问题,并尝试给出解决方案
taro doctor

快速创建新页面
Taro create --name [页面名称]
能够在当前项目的 pages 目录下快速生成新的页面文件,并填充基础代码,是一个提高开发效率的利器。
taro 会尝试同步修改 app.config.js 配置文件中的 pages 字段。

模式与环境变量

默认情况下, 模式 Taro cli 有 2 个模式:

development 模式用于开发时 taro build --type weapp --watch,它等价于
taro build --type weapp --watch --mode development

production 模式用于生产时 taro build --type weapp, 它等价于
taro build --type weapp --mode production

默认情况下 模式 的值,取决于 NODE_ENV 的值(但是反过来说模式的值无法改变 NODE_ENV 的值)。
假设你有开发和生产2 个环境,你可以在项目根目录下新建两个env环境文件:

.env.development # 在 development 模式时被载入
.env.production # 在 production 模式时被载入

环境文件只包含环境变量的“键=值”对:

TARO_APP_API=“https://api.tarojs.com”

请注意,只有以 TARO_APP_ 开头的变量将通过 webpack.DefinePlugin 静态地嵌入到客户端侧的代码中。这是为了避免和系统内置环境变量冲突。

被载入的环境变量我们可以在所有 taro 插件、 config/index.ts配置文件 以及 src 目录下面的项目文件中使用, 例如:

// src/service/request.ts
const request = axios.create({
  baseURL: process.env.TARO_APP_API
};
export default request

在构建过程中,process.env.TARO_APP_API 将会被相应的值所取代。在 TARO_APP_API=“https://api.tarojs.com” 的情况下,它会被替换为 “https://api.tarojs.com”

自定义模式
若默认的模式满足不了需求,你可以在命令上使用参数 --mode 模式名 的方式来指定模式名,以加载某一组环境变量,例如:

taro build --type weapp --mode uat

以上命令表示在构建时会加载 .env.uat 文件中的环境变量.

mode 具体载入规则:

.env # 在所有的环境中被载入
.env.local # 在所有的环境中被载入,但会被 git 忽略
.env.[mode] # 只在指定的模式中被载入
.env.[mode].local # 只在指定的模式中被载入,但会被 git 忽略

只在本地有效的变量
有的时候你可能有一些不应该提交到代码仓库中的变量,尤其是当你的项目托管在公共仓库时。这种情况下你应该使用一个 .env.local 文件取而代之。本地环境文件默认会被忽略,且出现在 .gitignore 中。

.local 也可以加在指定模式的环境文件上,比如 .env.development.local 将会在 development 模式下被载入,且被 git 忽略。

自定义环境变量前缀
前面提到,默认只加载 .env 文件中以 TARO_APP_ 前缀开头的环境变量,你可能想改成自己公司的英文名称作为前缀,@tarojs/cli 提供了 --env-prefix 参数来实现这一需求:

taro build --type weapp --mode development --env-prefix JD_APP_

此时 .env 文件中能被加载的环境变量只能是 JD_APP_ 前缀开头的:

TARO_APP_API=“https://api.tarojs.com” # 不满足前缀,不加载

JD_APP_TEST=“foo” # 满足前缀,加载

但是,有个特殊的环境变量不受自定义前缀配置的影响,始终会被加载,那就是 TARO_APP_ID。

编译配置

const config = {
  // 项目名称
  projectName: 'Awesome Next',
  // 项目创建日期
  date: '2020-6-2',
  // 设计稿尺寸
  designWidth: 750,
  // 设计稿尺寸换算规则
  deviceRatio: {
    640: 2.34 / 2,
    750: 1,
    828: 1.81 / 2,
  },
  // 项目源码目录
  sourceRoot: 'src',
  // 项目产出目录
  outputRoot: 'dist',
  // Taro 插件配置
  plugins: [],
  // 全局变量设置
  defineConstants: {},
  // 文件 copy 配置
  copy: {
    patterns: [],
    options: {},
  },
  // 框架,react,nerv,vue, vue3 等
  framework: 'react',
  // 小程序端专用配置
  mini: {
    postcss: {
      autoprefixer: {
        enable: true,
      },
      // 小程序端样式引用本地资源内联配置
      url: {
        enable: true,
        config: {
          limit: 10240,
        },
      },
      cssModules: {
        enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
        config: {
          namingPattern: 'module', // 转换模式,取值为 global/module
          generateScopedName: '[name]__[local]___[hash:base64:5]',
        },
      },
    },
    // 自定义 Webpack 配置
    webpackChain(chain, webpack) {},
  },
  // H5 端专用配置
  h5: {
    publicPath: '/',
    staticDirectory: 'static',
    postcss: {
      autoprefixer: {
        enable: true,
      },
      cssModules: {
        enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
        config: {
          namingPattern: 'module', // 转换模式,取值为 global/module
          generateScopedName: '[name]__[local]___[hash:base64:5]',
        },
      },
    },
    // 自定义 Webpack 配置
    webpackChain(chain, webpack) {},
    devServer: {},
  },
}

module.exports = function (merge) {
  if (process.env.NODE_ENV === 'development') {
    return merge({}, config, require('./dev'))
  }
  return merge({}, config, require('./prod'))
}

defineConfig 辅助函数

// config/index.ts
import { defineConfig } from '@tarojs/cli'

export default defineConfig({
  // ...Taro 配置
})
  1. 异步配置
    如果配置需要调用一个异步函数,也可以转而导出一个异步函数:
import { defineConfig } from '@tarojs/cli'

export default defineConfig(async (mergin, { command, mode }) => {
  const data = await asyncFunction()
  return {
    // Taro 配置
  }
})
  1. 情景配置
    如果配置文件需要基于 命令 或者不同的 模式 来决定选项,则可以选择导出这样一个函数:
import { defineConfig } from '@tarojs/cli'

export default defineConfig((mergin, { command, mode }) => {
  // mergin 为webpack-mergin, 兼容以前的配置
  // 假如执行的命令为: "taro build --type weapp --mode test"
  // 则 command 的值为 build, mode 的值为 test
  if (mode === 'development') {
    return {
      // dev 独有配置
    }
  } else if (mode === 'test') {
    return {
      // test 独有配置
    }
  } else {
    return {
      // build 独有配置
    }
  }
})

设计稿及尺寸单位

Taro 中尺寸单位建议使用 px、 百分比 %
100px -> 100rpx 微信小程序
100px -> rem单位 h5

API
在编译时,Taro 会帮你对样式做尺寸转换操作,但是如果是在 JS 中书写了行内样式,那么编译时就无法做替换了,针对这种情况,Taro 提供了 API Taro.pxTransform 来做运行时的尺寸转换。

Taro.pxTransform(10) // 小程序:rpx,H5:rem
// config.js
config = {
  mini: {
    postcss: {
      pxtransform: {
        enable: true,
        config: {
          onePxTransform: true,
          unitPrecision: 5,
          propList: ['*'],
          selectorBlackList: [],
          replace: true,
          mediaQuery: false,
          minPixelValue: 0
        }
      }
    }
  }
  h5: {
    postcss: {
      pxtransform: {
        enable: true,
        config: {
          onePxTransform: true, // 设置 1px 是否需要被转换
          unitPrecision: 5, // REM 单位允许的小数位
          propList: ['*'], // 允许转换的属性 ['*']: all  ['*position*'] ['*', '!letter-spacing']
          selectorBlackList: [], // 黑名单里的选择器将会被忽略
          replace: true,  // 直接替换而不是追加一条进行覆盖
          mediaQuery: false, // 允许媒体查询里的 px 单位转换
          minPixelValue: 0, // 设置一个可被转换的最小 px 值
          baseFontSize: 20,
          maxRootSize: 40,
          minRootSize: 20
        }
      }
    }
  }
}

全局配置

app.config.js 文件用来对小程序进行全局配置,配置项遵循微信小程序规范,并且对所有平台进行统一。

注意:

Taro v3.4 之前,app.config.js 里引用的 JS 文件没有经过 Babel 编译。(Taro v3.4 开始支持)
多端差异化逻辑可以使用 process.env.TARO_ENV 变量作条件判断来实现。
app.config.js 不支持多端文件的形式,如 app.weapp.js 这样是不起作用的。

defineAppConfig 宏函数

可以使用编译时宏函数 defineAppConfig 包裹配置对象,以获得类型提示和自动补全,如:

// app.config.ts
export default defineAppConfig({
  pages: ['pages/index/index'],
  window: {
    backgroundTextStyle: 'light',
    navigationBarBackgroundColor: '#fff',
    navigationBarTitleText: 'WeChat',
    navigationBarTextStyle: 'black',
  },
})

通用配置项

在 H5、React Native、所有小程序均支持的配置。

属性 类型 必填 描述
pages String Array 是 页面路径列表
window Object 否 全局的默认窗口表现
tabBar Object 否 底部 tab 栏的表现
subPackages Object Array 否 分包结构配置

pages
用于指定小程序由哪些页面组成

export default {
  pages: ['pages/index/index', 'pages/logs/logs'],
}

window
用于设置小程序的状态栏、导航条、标题、窗口背景色

export default {
  pages: ['pages/index/index', 'pages/logs/logs'],
  window: {
    navigationBarBackgroundColor: '#ffffff',
    navigationBarTextStyle: 'black',
    navigationBarTitleText: '微信接口功能演示',
    backgroundColor: '#eeeeee',
    backgroundTextStyle: 'light',
  },
}

tabBar
如果小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。

subPackages
H5 和 RN 会把 subPackages 合入 pages

启用分包加载时,声明项目分包结构

页面配置

每一个小程序页面都可以使用 .config.js 文件来对本页面的窗口表现进行配置。页面中配置项在当前页面会覆盖全局配置 app.config.json 的 window 中相同的配置项。

文件需要 export 一个默认对象,配置项遵循微信小程序规范,并且对所有平台进行统一。

注意:

Taro v3.4 之前,page.config.js 里引用的 JS 文件没有经过 Babel 编译。(Taro v3.4 开始支持)
Taro v3.4 支持在页面 JS 中使用 definePageConfig 宏函数定义页面配置,代替 page.config.js 文件。
多端差异化逻辑可以使用 process.env.TARO_ENV 变量作条件判断来实现。
page.config.js 不支持多端文件的形式,如 index.weapp.js 这样是不起作用的。

项目配置

各类小程序平台均有自己的项目配置文件:

微信小程序,project.config.json
百度小程序,project.swan.json
抖音小程序,project.config.json
QQ 小程序,project.config.json
支付宝小程序,mini.project.json
京东小程序,暂无发现
飞书小程序,project.config.json

Babel 配置

Taro 项目的 Babel 配置位于根目录的 babel.config.js 文件中,里面默认添加了一个 preset:babel-preset-taro,它会根据项目的技术栈添加一些常用的 presets 和 plugins。

// babel.config.js
module.exports = {
  presets: [
    [
      'taro',
      {
        /** 配置项 */
      },
    ],
  ],
}

babel-preset-taro

babel-preset-taro 会根据当前项目的技术栈,选择性地使用以下的 presets 和 plugins。

  1. 通用
    presets
    @babel/preset-env
    @babel/preset-typescript(TypeScript 环境)
    plugins
    @babel/plugin-transform-runtime
    @babel/plugin-proposal-decorators
    @babel/plugin-proposal-class-properties
    babel-plugin-dynamic-import-node(小程序环境)
  2. React
    presets
    @babel/preset-react
    plugins
    react-refresh/babel

useBuiltIns
默认值:false

有效值:‘entry’ | ‘usage’ | false

useBuiltIns: ‘entry’

优点:全局彻底 polyfill,就算 node_modules 中的依赖存在不兼容的代码,也能成功运行。

缺点:可能会引入冗余代码、影响全局变量。

需要在入口文件 app.js 中引入 core-js:

// src/app.js
import 'core-js'

Babel 会根据 targets,引入对应的 core-js 依赖。例如上述代码会被编译为:

dist/app.js
import 'core-js/modules/es.string.pad-start'
import 'core-js/modules/es.string.pad-end'

useBuiltIns: ‘usage’
信息
优点:按需引入、不会影响全局变量。

缺点:默认不会处理 node_modules 中的依赖,需要手动配置 babel-loader。

useBuiltIns: false
当传入 false 时,会把 @babel/preset-env 的 useBuiltIns 选项设为 false,此时不会引入 core-js。

loose
默认值:false

同时是 @babel/preset-env、@babel/plugin-proposal-class-properties 的 loose 配置项。

debug
默认值:false

@babel/preset-env 的 debug 配置项。

modules
默认值:false

@babel/preset-env 的 modules 配置项。

spec
@babel/preset-env 的 spec 配置项。

configPath
@babel/preset-env 的 configPath 配置项。

include
@babel/preset-env 的 include 配置项。

exclude
@babel/preset-env 的 exclude 配置项。

shippedProposals
@babel/preset-env 的 shippedProposals 配置项。

forceAllTransforms
@babel/preset-env 的 forceAllTransforms 配置项。

decoratorsBeforeExport
@babel/plugin-proposal-decorators 的 decoratorsBeforeExport 配置项。

decoratorsLegacy
默认值:true

@babel/plugin-proposal-decorators 的 lagacy 配置项。

absoluteRuntime
默认值:开发者根目录 node_modules 中的 @babel/plugin-transform-runtime 的路径。

类型:string

@babel/plugin-transform-runtime 的 absoluteRuntime 配置项。

version
默认值:开发者根目录 node_modules 中的 @babel/plugin-transform-runtime 的版本号。

类型:string

@babel/plugin-transform-runtime 的 version 配置项。

dynamic-import-node
备注
可以去掉冗余代码,对于一些严格限制包体大小的场景(比如 PWA 等)有帮助,但这也会去掉页面和组件的懒加载,导致 app.js 过大。

注意:h5 平台默认关闭,其他平台默认开启,小程序默认是不支持动态加载的,可以通过dynamic-import 插件提供该能力。 :::

类型:boolean

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐