Taro 1.x升级2.x 需要的配置和bug的解决

1. 版本:升级版本Taro 1.3.34 至 2.0.4

升级原因:由于项目刚开始时Taro还在1.x时代,后来Taro更新很快,在使用过程中也发现需要升级Taro版本来减小打包出来的小程序包的大小(微信小程序限制,每个包必须2M以下)。升级到2.x之后的Taro,对于微信小程序的打包使用了webpack,因此可以更方便地安装各种webpack plugins:比如 webpack-bundle-analyzer 来分析包大小。升级之后的Taro也会修复更多taro 原生的bug。

参考文章: https://aotu.io/notes/2020/01/08/taro-2-0/index.html,里面介绍了升级之后的优势,以及如何配置webpack plugin。

2. 升级必须的配置修改

加上目录结构

对于config/index.js文件中的配置,参考上面的文章配置:

  • 编译配置调整
  // 小程序配置从 weapp 改为 mini,可以删掉很多小配置
  • 异步编程调整

    Taro 2.0 中开启 async functions 支持不再需要安装 @tarojs/async-await,而是直接通过 babel 插件来获得支持。

    在项目根目录下安装包 babel-plugin-transform-runtimebabel-runtime

    $ yarn add babel-plugin-transform-runtime --dev
    $ yarn add babel-runtime
    

    随后修改项目 babel 配置,配置插件 babel-plugin-transform-runtime

    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'
        }]
      ]
    }
    
  • 添加webpack-bundle-analyzer (optional)

  • 添加减少lodash包的plugin,因为lodash全部引入太大(optional)

  • 减小moment包(optional)

index.js文件如下:

/* eslint-disable */
const path = require('path')
const webpack = require('webpack') //减小moment包的时候用,不然不用加
const env = process.env.NODE_ENV

const settingsPath = `styles/${env}`

const config = {
  projectName: 'taro-upgrade',
  date: '2021-01-11',
  //这里设置taro屏幕大小,根据自己的需求,默认的是750;不是必须
  designWidth: 375,
  deviceRatio: {
    '375': 1 / 2,
    '640': 2.34 / 2,
    '750': 1,
    '828': 1.81 / 2
  },
  //根目录的别称;按需,不是必须
  alias: {
    '@': path.resolve(__dirname, '..', 'src'),
  },
  sourceRoot: 'src',
  outputRoot: 'dist',
  babel: {
    sourceMap: true,
    presets: [
      ['env', {
        modules: false
      }]
    ],
    plugins: [
      'lodash',
      'transform-decorators-legacy',
      'transform-class-properties',
      'transform-object-rest-spread',
      //添加transform-runtime,升级必须
      ['transform-runtime', {
        helpers: false,
        polyfill: false,
        regenerator: true,
        moduleName: 'babel-runtime'
      }
      ]
    ]
  },
  defineConstants: {
  },
  mini: {
    //按需引入plugins,不是必须
    webpackChain(chain) {
      process.env.analyzer && chain.plugin('analyzer')
        .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, [])
      //lodash减小size的plugin,在通常情况下可以加。但是如果使用了lodash中比较不常用的方法,压缩尺寸会导致某些方法不能正常工作;的确我们项目后续有一个bug就是因为这里用了这个插件减小了包,而导致方法报错。最终这个plugin被移除了。
      chain.plugin('LodashModuleReplacementPlugin')
        .use(require('lodash-webpack-plugin'), [{
          shorthands: true,
          cloning: true,
          collections: true,
          exotics: true,
          guards: true,
          coercions: true,
          paths: true
        }])
      //减小moment的包
        chain.plugin('momentReplacementPlugin')
        .use(new webpack.ContextReplacementPlugin(
          /moment[\\\/]locale$/,
          /^\.\/(zh-cn)$/
          ),
        )
    },
    postcss: {
      autoprefixer: {
        enable: true,
        config: {
          browsers: [
            'last 3 versions',
            'Android >= 4.1',
            'ios >= 8'
          ]
        }
      },
      pxtransform: {
        enable: true,
        config: {

        }
      },
      url: {
        enable: true,
        config: {
          limit: 10240 // 设定转换尺寸上限
        }
      },
      cssModules: {
        enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
        config: {
          namingPattern: 'module', // 转换模式,取值为 global/module
          generateScopedName: '[name]__[local]___[hash:base64:5]'
        }
      }
    },
    imageUrlLoaderOption: {
      //4.2中有个bug与这个配置有关。
    },
    sassLoaderOption: {
      includePaths: [
        //由于项目中,不同环境下部分style不同,所以这里按照环境load了样式。
        path.resolve(__dirname, '../src/styles'),
        path.resolve(__dirname, '../src/', settingsPath)
      ],
    }
  },
  //该项目是小程序only,所以h5的配置不需要了
}

//这里也是根据环境导出不同环境的配置。
module.exports = function (merge) {
  return merge({}, config, require(`./${env}`))
}

3. 测试需要加babel@7的包

Taro-UI 官方引入了babel 7用于UI测试,因为babel-jest需要babel7.x以上版本的支持。

但是,由于Taro本身使用的是babel 6.x,为了不混淆编译,需要配置babel.config.js 如下:

/* eslint-disable import/no-commonjs */
const apis = require('@tarojs/taro-h5/dist/taroApis')

module.exports = {
  presets: [
    [
      '@babel/env',
      {
        spec: true,
        useBuiltIns: false
      }
    ],
    [
      '@babel/preset-typescript',
      {
        isTSX: true,
        allExtensions: true,
        jsxPragma: 'Nerv.createElement'
      }
    ]
  ],
  plugins: [
    ['@babel/plugin-proposal-decorators', { 'legacy': true }],
    '@babel/plugin-proposal-class-properties',
    [
      '@babel/plugin-transform-react-jsx',
      {
        pragma: 'Nerv.createElement'
      }
    ],
    ['@babel/plugin-proposal-object-rest-spread'],
    [
      'babel-plugin-transform-taroapi',
      {
        apis,
        packageName: '@tarojs/taro-h5'
      }
    ]
  ]
}

其它参考:如果用ts-jest编译jsx会报错,只能用于简单的逻辑测试的编译(纯javascript),这里有UI测试,不能使用 https://github.com/kulshekhar/ts-jest/issues/937

4. 升级之后带来的bugs,逐一击破

4.1 有一个组件的样式不生效

  • 现象:升级之后发现一个在Taro1.x编译后有样式的组件,在新版本下不显示样式,查看dist发现也没有生成对应的.wxss文件,

  • 原因:后来排查原因发现,这个component的样式文件componentA.scss被两个不同的组件直接引用了(import了两个地方),而查看官方文档可以发现

某些组件样式失效了#

在升级到 2.x 后可能会遇到某些组件的样式失效了,这是因为 2.x 中默认将所有被超过 1 个文件引用的公共样式抽离到了 common 文件中,该文件默认会被 app 引入,而由于小程序组件默认不能接受公共,所以会导致样式失效,可以通过为组件配置 addGlobalClass 来解决,或者也可以通过自己配置 Webpack 禁止抽离公共样式。

  • 解决方法:保证component的样式不被多个组件重复调用。

4.2 TaroCanvasDrawer使用本地图片画图失败

  • 原因:由webpack url-loader转换图片为base64格式引起
import demoImage from '@/assets/demo.png'

export default class Demo extends component {
  state = {
    config: {
      width: 750,
      height: 1000,
      images: [
        {
          x: 0,
          y: 0,
          width: 375,
          height: 1000,
          //就是这里出错了!!!webpack url-loader把这个图片url变成了base64格式,导致taroCanvasDrawer无法识别这种格式。解决方法是禁用url-loader转换。
          url: demoImage
        }
      ]
    }
  }
  
  render() {
    return (
      
    )
  }
}

  • 解决方法,在config/index.js中配置

    // more code config in mini: {}
      imageUrlLoaderOption: {
          limit: 0
        },
    

4.3 -webkit-box-orient: vertical 编译后被移除

  • 原因:autoprefixer的issue: https://github.com/postcss/autoprefixer/issues/1141

根据上面的issue,解决方法是在样式中添加注释:

.demo-box {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  /* autoprefixer: ignore next */
  -webkit-box-orient: vertical;
  overflow: hidden;
}

但是!!!添加注释的方法,在npm start之后是可行的,在npm run build之后依旧失效了!!!build

之后还是被移除了。

  • 解决方法:不放在scss中,把这个样式放在inline style里:

    return (
      
        text
      )
    

你可能感兴趣的:(Taro 1.x升级2.x 需要的配置和bug的解决)