What is the Taro

Taro is a multi-terminal development framework developed by Bump Lab that follows the React syntax specification.

At present, there are various forms of the upper end of the market, such as Web, App (React Native), wechat small program and other popular ends. When business requirements are required to perform on different ends at the same time, it is obviously very expensive to write multiple sets of code for different ends. The ability to write a single set of code that can be adapted to multiple applications is in great demand.

Using Taro, we can only write one set of code, and then compile the source code separately into codes that can run on different ends (wechat applet, H5, App, etc.) through Taro’s compilation tool. Taro also provides syntax detection and automatic completion functions out of the box, effectively improving the development experience and development efficiency.

What do Taro have to offer

Write once, run anywhere

Write a set of code output multi-terminal executable code, save a lot of learning costs and workload.

Taro follows the React syntax standard and converts code files based on the principles of compilation to obtain code that can be run in small programs. React was originally designed for Web development, so you can directly generate code to run on the Web with minor changes. React Native, which also belongs to the React syntax system, can also provide easy support. Similarly, other platforms, such as fast application, Baidu small program, etc., will be compiled and converted to the source code operation, can also obtain the corresponding grammar code under the platform.

Multifaceted development practices

CLI Tool Installation

Install CLI using NPM
$ npm install -g @tarojs/cli
# OR Install the CLI using YARN
$ yarn global add @tarojs/cli
Install the CLI using CNPM
$ cnpm install -g @tarojs/cli
Copy the code

Project initialization

taro init myApp
Copy the code

run

Ensure that the Taro CLI version is consistent with the dependent version of your project, or compile errors or runtime errors may occur. Except h5, all other terminals need to download the corresponding developer tools

1. Wechat mini program# yarn
$ yarn dev:weapp
$ yarn build:weapp
# npm script$NPM run dev: retry p $NPM run build: retry P 2, H5# yarn
$ yarn dev:h5
$ yarn build:h5
# npm script
$ npm run dev:h5
$ npm run build:h5

Copy the code

Other terminals run visible official website

Project configuration file config

dev.js

module.exports = {
    env: {
        NODE_ENV: '"development"'
    },
    defineConstants: {},
    mini: {},
    h5: {
        devServer: {
            proxy: {
                "/": {
                    target: "proxy address",
                    changeOrigin: true}}}}};Copy the code

index.js

const path = require('path')

const config = {
    projectName: "taro-template",
    date: "2020-1-26",
    designWidth: 750,
    deviceRatio: {
        "640": 2.34/2."750": 1,
        "828": 1.81/2},sourceRoot: "src",
    outputRoot: `dist/taro-template-${process.env.TARO_ENV}`,
    alias: {
        "@/service": path.resolve(__dirname, ".."."src/service"),
        "@/utils": path.resolve(__dirname, ".."."src/utils")
    },
    copy: {
        patterns: [
            { from: "src/static/", to: `dist/taro-template-${process.env.TARO_ENV}'} // specify the file to copy]}, Babel: {sourceMap: true,
        presets: [
            [
                "env",
                {
                    modules: false
                }
            ]
        ],
        plugins: [
            "transform-decorators-legacy"."transform-class-properties"."transform-object-rest-spread"["transform-runtime",
                {
                    helpers: false,
                    polyfill: false,
                    regenerator: true,
                    moduleName: "babel-runtime"
                }
            ]
        ]
    },
    defineConstants: {},
    mini: {
        postcss: {
            autoprefixer: {
                enable: true,
                config: {
                    browsers: ["last 3 versions"."Android > = 4.1"."ios >= 8"]
                }
            },
            pxtransform: {
                enable: true,
                config: {}
            },
            url: {
                enable: true,
                config: {
                    limit: 10240 // Set conversion size upper limit}}, cssModules: {enable: false// The default isfalse, to use the CSS Modules functiontrue
                config: {
                    namingPattern: "module"Global/Module generateScopedName:"[name]__[local]___[hash:base64:5]"
                }
            }
        }
    },
    h5: {
        publicPath: "/",
        staticDirectory: "static",
        output: {
            filename: "js/[name].[hash:8].js",
            chunkFilename: "js/[name].[chunkhash:8].js"
        },
        imageUrlLoaderOption: {
            limit: 5000,
            name: 'static/images/[name].[hash].[ext]'
         },
        miniCssExtractPluginOption: {
            filename: "css/[name].[hash:8].css",
            chunkFilename: "css/[name].[chunkhash:8].css"
        },
        postcss: {
            autoprefixer: {
                enable: true,
                config: {
                    browsers: ["last 3 versions"."Android > = 4.1"."ios >= 8"]
                }
            },
            cssModules: {
                enable: false// The default isfalse, to use the CSS Modules functiontrue
                config: {
                    namingPattern: "module"Global/Module generateScopedName:"[name]__[local]___[hash:base64:5]"}}}}}; module.exports =function (merge) {
    if (process.env.NODE_ENV === "development") {
        return merge({}, config, require('./dev'));
    }
    return merge({}, config, require('./prod'));
};

Copy the code

prod.js

module.exports = {
    env: {
        NODE_ENV: '"production"'}, defineConstants: {}, mini: {}, h5: {/** * If the H5 side is too large after compilation, you can use the webpack-bundle-Analyzer plug-in to analyze the package volume. * webpackChain (chain) {* chain.plugin('analyzer')
         *     .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, [])
         * }
         */
    }
};
Copy the code

Multiterminal practice

Requirements vary somewhat from side to side, with differences in page style, interaction style, and page logic, and you need to execute different code depending on the environment in which you compile it.

Built-in environment variables

process.env.TARO_ENV

It is used to determine the current compilation type. There are currently eight values: APPellate/swan/Alipay/h5 / rn/tt/QQ/QuickApp, which can be used to write different codes in different environments.

  • Different ends reference different resources
if(process.env.TARO_ENV === 'weapp'){
    require('path/to/weapp/name')}else if(process.env.TARO_ENV === 'h5'){
    require('path/to/h5/name')}Copy the code
  • Used in JSX, different ends load different components
render() {return (
        <View>
            {process.env.TARO_ENV === 'weapp' && <ScrollViewWeapp />}
            {process.env.TARO_ENV === 'h5' && <ScrollViewH5 />}
        </View>
    )
}
Copy the code

Unified interface multiterminal files (supported from version 1.2.17)

Although built-in environment variables can solve most cross-end problems, the code will be filled with logical decisions, affecting the maintainability of the code, and also making the code ugly. To solve this problem, Taro provides another cross-end development method as a complement since 1.2.17.

Developers can address cross-end differences by using multi-end files with a unified interface. For this function, if there are differences between multiple end, so developers can amend the file into a type of naming the original file name + end, to the different foreign maintain uniform interface file code, and references are still import the original filename file, Taro at compile time, depending on the need to compile platform type, The loaded file is changed to a file with the file name of the corresponding end type, so as to achieve the purpose of loading corresponding files on different ends.

The end type corresponds to the value of process.env.taro_env

There are two common usage scenarios

1. Multi-terminal components

If there is a test component with wechat applets and two different versions of H5, the code can be organized as follows.

The test.js file, which is the default form of the test component, is compiled into the version used by both ends of the wechat applet, h5L. Test.h5.js file, which is the H5 version of the test component. Test.app.js file, which is the app version of the test component.

The three files, externally exposed is a unified interface, they accept the same parameters, only internal implementation of the code for their respective platforms. Use the same method as before, import is not the filename with the end type, during compilation will automatically recognize and add the end type suffix

import Test from '.. /.. /components/test'

<Text argA={1} argA={2} />
Copy the code

2. Multi-terminal scripts

Similar to multiterminal components, if you need to write different script logic code for different ends, you can do the same, even if the multiterminal file is the same as the external interface.

For example WeChat small program with Taro. SetNavigationBarTitle to set the page title, H5. Use the document title, then can encapsulate a setTitle method to recover the difference between two platforms.

Add set_title.h5.js as follows

export default function  setTitle(title){
    document.title = title
}
Copy the code

Add set_title.app.js. The code is as follows

import Taro from '@tarojs/taro'
export default function setTitle(title){
    Taro.setNavigationBarTitle({
        title
    })
}
Copy the code

When called, use the following

import setTitle from '.. /utils/set_title'
setTitle('Page title')
Copy the code

Using different pages in app.js (supported since version 1.3.11)

Return different pages depending on the environment

config:Config = {
    "pages":preval`
        module.exports = (function() {
            if(process.env.TARO_ENV === 'weapp') {
                return [
                    '/pages/index/index']}if(process.env.TARO_ENV === 'swan') {return [
                    '/pages/indexswan/indexswan']}})() '}Copy the code

Conditional compilation of styles (1.3+ version support)

Conditional compilation of style files

Assume the following files exist in the directory:

-index.scss
-index.rn.scss
Copy the code

When a JS file references the style file: import ‘./index.scss’, RN will find and introduce index.rn. SCSS, while other platforms will introduce: index.scss, which makes it easier for people to write cross-end styles and better compatibility with RN.

Conditional compilation of style files

To make it easier for people to write style code across styles, a style conditional compilation feature has been added

Specific platform Reservation

/ *#ifdef %PLATFORM% */Style code /*#endif */
Copy the code

Specific platform culling

/ *#ifndef %PLATFORM% */Style code /*#endif */
Copy the code

Multiple platforms can be separated by Spaces

Multi-endpoint synchronous debugging (supported from version 1.3.5)

Starting with version 1.3.5, it is possible to create a dist directory with the same name as the target platform to be compiled, and to add results in the dist/ appellate directory, for example, when you compile wechat appellate programs. The final results are in the dist/ appellate directory. To achieve the purpose of multi-terminal synchronous debugging, the config/index.js configuration is as follows:

outputRoot:`dist/${process.env.TARO_ENV}`
Copy the code

IO /2, AOtu. IO /notes/2018/…