比木白-Taro

微信小程序框架Taro

2.0升级压缩微信小程序包体积增大比较多

原因

最近taro框架由1.x升级至了2.0版本,变化比较大的就是编译这一块儿,增加了按需加载runtime第三方依赖,需要下载第三方按需加载依赖包babel-plugin-transform-runtime以及babel-runtime,编译器也进行了优化,新增了@tarojs/mini-runner编译依赖,使得编译优雅了许多,而且利用webpackChain配置,可以配置更多的webpack插件,比如说上面提到的ContextReplacementPlugin剔除某些外部依赖不打入至包内,再比如说webpack-bundle-analyzer这种可以监听打包之后包体积大小,进行可视化的第三方依赖都可以方便进行使用。

但是实际效果,打包之后的体积比较与1.x版本,足足增大了400kb左右,导致我业务开发的小程序体积包从1.4M窜升至1.8M,uglify和csso压缩JS以及css的工具明显也不如之前1.x版本实用,开启压缩和不开启的实际效果,体积几乎没什么变化。

由此基于小程序要上线,我又退回至1.x的最后一个版本,也许是@tarojs/mini-runner刚开发不久,编译依赖不够成熟吧。

升级至2.0.6之后,这个问题有了不小的改善,Taro官方使用SplitChunksPlugin默认将打包分为四部分’runtime’,’vendors’,’taro’以及’commons’,分别代表的是懒加载、除了taro以外的在超过2个的入口模块都引入的第三方外部依赖包、taro除了taro以外的在超过2个的入口模块都引入的第三方外部依赖包以及在超过2个的入口模块都引入的公共业务部分。除了这些,taro还支持自己配置webpackChain SplitChunksPlugin自定义拆包。

升级至2.1.0之后,这个问题基本有了彻底的改善,但是需要修改package.json scripts命令,将全局环境变量NODE_ENV更改为production,将开发环境代码打包、压缩、缓存以及多进程配置置为生产环境配置,加入至’dev:weapp’命令中,当然添加参数的方式有多样,可以用cross-env,也可以用yargs,这里我使用的是cross-env。

taro-ui UI组件库的大小也改善了很多,尤其是支持了按需加载UI组件库方面,但是这里又出现了一个问题,taro-ui UI组件库在taro 2.1.0以后的版本生产环境也就是我所说的yarn run build:weapp,也可以使用我上述所说的将全局环境变量置为production,之后’dev:weapp’的方式,公共样式就不会导入进来,此bug在taro 2.1.5版本修复。我提的taro issue

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//如果是taro,这种使用react对接多端的框架,则是使用webpackChain
//2.0.6配置,config目录下的index.js
{
//...
mini: {
commonChunks: ['runtime', 'vendors', 'common'],
webpackChain(chain, webpack) {
chain.optimization.splitChunks({
minChunks: 2,
minSize: 0,
name: 'vendors',
maxInitialRequests: Infinity,
chunks: 'all',
cacheGroups: {
common: {
minChunks: 2,
name: 'common',
chunks: 'initial',
priority: 1
},
vendors: {
minChunks: 2,
name: 'vendors',
test: (module)=>{
return /[\\/]node_modules[\\/]/.test(module.resource);
},
chunks: 'initial',
priority: 10
}
}
});
}
}
}

2.1.0版本将开发环境代码置为生产环境代码,彻底解决2.0之后打包过大的问题

微信小程序中转义换行问题

原因

开发微信小程序时,发现后台返回的某一些字符串当中含有\n换行符,实际意义是为了让字符串在换行符的位置上进行换行展示,在PC端或者移动端开发中,我们可以使用\<br/>来置换字符串中所有的\n换行符,而在小程序中,就感觉有一些手足无措。
于是查阅资料,找到了解决方案。

详情

  1. 在微信小程序中view标签中的任何可转义的字符,都不可以进行转义,只有在text标签中,且属性decode为true的情况下,才可以将转义字符进行转义。

  2. 字符串中的\n换行符,实际上为\n,故需要匹配字符串中所有的\n字符串,然后进行替换为\n换行符。

harmony
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//Taro项目中的例子    
class Demo extends Component {
//...
render() {
//这样就可以在页面中显示
//我叫尹文楷,
//我今年十二岁了,
//我喜欢写代码.
let value = '我叫尹文楷,\\n我今年十二岁了,\\n我喜欢写代码.'.replace(/\\n/g, '\n');
return (
<Text decode>
{value}
</Text>
)
}
}

JSX渲染

原因

昨天在写Taro项目的时候,发现taro项目的渲染方法,最前端必须添加render,方可返回JSX,要是不添加render,编译时就会报错。而且不支持静态策略模式返回JSX,也会匹配不到语法而报错,所以就不使用策略模式来写了,而是使用判断语句switch来写,然而还是遇到了问题,switch每一个case分支判断语句,必须以{}花括号包裹返回。

另外,在调用渲染JSX的方法时,即使是箭头函数,也不能以解构定义的变量去进行调用,必须以软绑定的形式去进行调用。

使用

harmony
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import Taro, {Component} from '@tarojs/taro';
import {
Image,
View
} from '@tarojs/components';
class Demo extends Component {
constructor(props) {super(props);}
renderShowConent = (type, content) => {
switch(type) {
case 'TEXT': {
return <Text>
{content}
</Text>;
}
case 'IMG': {
return <Image
src={content}
alt={content}
/>;
}
}
};
render() {
const type = 'TEXT',
content = 'yinwenkai';
return (
<View>
{this.renderShowConent(type, content)}
</View>
);
}
}

父子传参

原因

最近在写Taro小程序项目的时候,发现Taro小程序里面父子传参不像想象中的那么简单,尤其是this.props.children和自定义组件参数,实际在编译完之后this.props.children就是\<slot>\</slot>,且在自组件里面使用this.props.children不能解构定义,比如{children} = this.props,必须使用this.props.children,而this.props.children不能为taro-ui的组件,必须为taro内置的原生组件;而自定义组件参数,规则就更多了,参数的命名前缀必须为render,在使用时也不可解构定义,必须使用this.props.render…,自定义组件参数最好不要是函数方法返回组件,而是直接赋值,这样可保万无一失。自定义组件参数既可为内置原生组件也可为taro-ui这种UI组件。

使用

harmony
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import Taro, {Component} from '@tarojs/taro';
import {
View
} from '@tarojs/components';
import PropTypes from 'prop-types';


class Demo extends Component {
static propTypes = {
renderDemo: PropTypes.element
};
constructor(props) {super(props);}
render() {
return (
<View>
{this.props.renderDemo}
{this.props.children}
</View>
)
}
}
export default Demo;
harmony
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import Taro, {Component} from '@tarojs/taro';
import {
View
} from '@tarojs/components';
import PropTypes from 'prop-types';
import {
AtButton
} from 'taro-ui';

import Demo from '../Demo';

class Parent extends Component {
static propTypes = {
renderDemo: PropTypes.element
};
constructor(props) {super(props);}
render() {
return (
<View>
<Demo renderDemo={
<AtButton type='primary'>按钮</AtButton>
}>
<View>
尹文楷,god bless you~
</View>
</Demo>
</View>
)
}
}

export default Parent;