Skip to content

Commit

Permalink
Merge branch 'master' of github.com:NervJS/taro
Browse files Browse the repository at this point in the history
  • Loading branch information
Pines-Cheng committed Apr 22, 2019
2 parents 17fea1f + d0b8e77 commit f87c5ce
Show file tree
Hide file tree
Showing 37 changed files with 2,317 additions and 1,153 deletions.
40 changes: 30 additions & 10 deletions packages/taro-cli/src/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,16 +258,26 @@ function wxPluginWatchFiles () {
// 最后删除 output/plugin
const names = glob.sync(`${outputPath}/${PLUGIN_ROOT}/**/*`)
if (names.length) {
const jsNames = glob.sync(`${outputPath}/${PLUGIN_ROOT}/!(npm)/**/*.js`)
const jsNames = glob.sync(`${outputPath}/${PLUGIN_ROOT}/{,!(npm)/**/}*.js`)
const ioPromises = jsNames.map(async name => {
let content = await fs.readFile(name)
content = content.toString()
let shouldWrite
const replacement = content.replace(/['|"](\.\.\/)+npm\/.+?['|"]/g, str => {
shouldWrite = true
return str.replace('../', '')

let isShouldBeWritten
let replacement = content.replace(/['|"]((\.\.\/)+)npm\/.+?['|"]/g, (str, $1) => {
isShouldBeWritten = true
return $1 === '../' ? str.replace('../', './') : str.replace('../', '')
})
if (shouldWrite) await fs.writeFile(name, replacement)

const REG_PLUGIN_DEPS = RegExp(`['|"](/${PLUGIN_ROOT}.+)['|"]`, 'g')
replacement = replacement.replace(REG_PLUGIN_DEPS, (str, $1) => {
if (Util.REG_FONT.test($1) || Util.REG_IMAGE.test($1) || Util.REG_MEDIA.test($1)) {
return str.replace(RegExp(`^['|"]/${PLUGIN_ROOT}`, 'g'), str => str.replace(`${PLUGIN_ROOT}`, ''))
}
return str
})

if (isShouldBeWritten) await fs.writeFile(name, replacement)
})
await Promise.all(ioPromises)

Expand Down Expand Up @@ -359,12 +369,22 @@ async function buildWxPlugin ({ watch }) {
const ioPromises = names.map(async name => {
let content = await fs.readFile(name)
content = content.toString()
let shouldWrite
const replacement = content.replace(/['|"]((\.\.\/)+)npm\/.+?['|"]/g, (str, $1) => {
shouldWrite = true

let isShouldBeWritten
let replacement = content.replace(/['|"]((\.\.\/)+)npm\/.+?['|"]/g, (str, $1) => {
isShouldBeWritten = true
return $1 === '../' ? str.replace('../', './') : str.replace('../', '')
})
if (shouldWrite) await fs.writeFile(path.join(appPath, name), replacement)

const REG_PLUGIN_DEPS = RegExp(`['|"](/${PLUGIN_ROOT}.+)['|"]`, 'g')
replacement = replacement.replace(REG_PLUGIN_DEPS, (str, $1) => {
if (Util.REG_FONT.test($1) || Util.REG_IMAGE.test($1) || Util.REG_MEDIA.test($1)) {
return str.replace(RegExp(`^['|"]/${PLUGIN_ROOT}`, 'g'), str => str.replace(`${PLUGIN_ROOT}`, ''))
}
return str
})

if (isShouldBeWritten) await fs.writeFile(path.join(appPath, name), replacement)
})
await Promise.all(ioPromises)

Expand Down
7 changes: 0 additions & 7 deletions packages/taro-components-rn/.expo/settings.json

This file was deleted.

83 changes: 13 additions & 70 deletions packages/taro-components-rn/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,87 +2,30 @@

Alo, alo! Bilibilibilibibili~

<details>
<summary>关于 Icon 的使用</summary>

> <del>IOS: 如果你要用到 `Icon`,请先把 `libART.a` 引进去,步骤如下:</del>
> <del>`open ios/AwesomeProject.xcodeproj` 在xcode中打开项目,拖拽 `node_modules/react-native/Libraries/ART/ART.xcodeproj` 到左侧栏的 `Libraries` 下;选中项目左侧栏中的根节点,然后在 `Build Phases``Link Binary with Libraries` 添加 `libART.a`</del>
> 为了尽可能地减少用户需要的操作,斟酌再三,目前方案改成:IOS使用图片来实现 Icon。
</details>
## 特别鸣谢

Picker 组件的重写,copy 了部分 [ant-design-mobile-rn](https://github.com/ant-design/ant-design-mobile-rn) 的组件代码,同时也给予了不少组件实现的思路。

## Example

[组件演示(视频480p)](http://storage.jd.com/temporary/%E7%BB%84%E4%BB%B6%E6%BC%94%E7%A4%BA480p.mov)

> 由于在开发环境中用到 `create-react-native-app` 的模式,所以**务必**`dependencies` 的方式安装 `react-native``expo`,查看例子期间,务必保证它们待在 `dependencies` 下哦。
>
> 设置 package.json 中的 `main``node_modules/expo/AppEntry.js`
- [Expo版本清单](https://expo.io/--/api/v2/versions),这里可以看到每个版本Expo对应的版本关系,**这很重要**

```bash
npm start

npm run ios

# 启动安卓模拟器
emulator @YOUR_AVD_NAME
npm run android
```

可能遇到的问题:
# 安装依赖
yarn

- IOS:在启动模拟器时挂起时,请先下载 `Expo版本清单` 中的 `iosUrl`,把下载解压后的文件夹添加 `.app` 后缀放进 `~/.expo/ios-simulator-app-cache`
- IOS:遇到 `Error: Process exited with non-zero code: 60` 时,擦除内容和设置再重新运行。
- IOS:遇到 `React Native Version Mismatch` 时,说明 ReactNative 的版本跟 expoSDK 的版本不匹配,装一个匹配的版本就好了。
- Android:遇到 `Error running adb: No Android device found.` 时,请先下载 `Expo版本清单` 中的 `androidUrl` 放到 `~/.expo/android-apk-cache` 下。
# 编译源码
npm run build

最后,当然你觉得麻烦的话::
# 例子目录安装依赖
cd TCRNExample
yarn

你完全可以用 `react-native-cli` 初始化一个项目,然后把 `src` 目录整个复制到这个项目下来引用查看例子。
# 启动 Android
react-native run-android
# 启动 iOS
react-native run-ios
```

## About code comments

- ✔ Support
- ✘ Not support
- \- Would not support

## Todo list

> FS = Fully Support
> PS = Partially Support
> MS = Minimum Support
- 视图容器
- [x] view | MS
- [x] scroll-view | PS
- [x] swiper | PS
- 基础内容
- [x] icon | FS
- [x] text | PS
- [x] rich-text | FS
- [x] progress | FS
- 表单内容
- [x] button | PS
- [x] checkbox | FS
- [x] form | PS(without RESET)
- [x] input | PS
- [x] label | PS(without FOR)
- [x] picker | PS
- [x] radio | FS
- [x] slider | PS
- [x] switch | FS
- [x] textarea
- 导航
- 媒体组件
- [ ] audio
- [x] image | PS
- [ ] video
- [ ] camera
- 其他
- [ ] tabbar
6 changes: 6 additions & 0 deletions packages/taro-components-rn/TCRNExample/rn-cli.config.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
const path = require('path')
const blacklist = require('metro').createBlacklist

module.exports = {
extraNodeModules: {
react: path.resolve(__dirname, 'node_modules/react'),
'react-native': path.resolve(__dirname, 'node_modules/react-native')
},
getBlacklistRE () {
return blacklist([
/TCRNExample\/node_modules\/react-native\/.*/
])
},
getProjectRoots () {
return [
path.resolve(__dirname),
Expand Down
8 changes: 8 additions & 0 deletions packages/taro-components-rn/__mocks__/fileMock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const path = require('path')

/**
* REF: https://jestjs.io/docs/en/webpack
*/
module.exports = (src, filename, config, options) => {
return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';'
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from 'react'
import * as React from 'react'
import { View, Text, Animated, Image, TouchableOpacity } from 'react-native'
import { shallow } from 'enzyme'
import sinon from 'sinon'
import * as sinon from 'sinon'
import { Button } from '../src'

describe('<Button />', () => {
it('render default', () => {
const wrapper = shallow(<Button />)
const wrapper = shallow(<Button>BUTTON</Button>)
expect(wrapper.find(Text)).toHaveProperty('length', 1)
})

Expand All @@ -17,6 +17,7 @@ describe('<Button />', () => {

it('simulates trigger loading', () => {
const wrapper = shallow(<Button />)
// @ts-ignore
const spy = sinon.spy(wrapper.instance(), 'animate')
expect(spy.calledOnce).toBe(false)
wrapper.setProps({ loading: true })
Expand All @@ -25,12 +26,12 @@ describe('<Button />', () => {
expect(spy.calledOnce).toBe(true)
})

it('type warn of loading', () => {
const wrapper = shallow(<Button type="warn" loading />)
const opaqueTypeRes = wrapper.find(Image).at(0).prop('source')
expect(opaqueTypeRes).toBe(1)
expect(Image.resolveAssetSource(opaqueTypeRes).uri).toMatch(/file:\/\//)
})
// it('type warn of loading', () => {
// const wrapper = shallow(<Button type="warn" loading />)
// const opaqueTypeRes = wrapper.find(Image).at(0).prop('source')
// expect(opaqueTypeRes).toBe(1)
// expect(Image.resolveAssetSource(opaqueTypeRes).uri).toMatch(/file:\/\//)
// })

it('disabled button', () => {
const wrapper = shallow(<Button disabled />)
Expand Down Expand Up @@ -60,7 +61,7 @@ describe('<Button />', () => {
})

it('plain and disabled button', () => {
const wrapper = shallow(<Button disabled plain />)
const wrapper = shallow(<Button disabled plain>BUTTON</Button>)
expect(wrapper.find(Text).get(0).props.style).toEqual(
expect.arrayContaining([
expect.objectContaining({
Expand All @@ -71,7 +72,7 @@ describe('<Button />', () => {
})

it('type primary and disabled', () => {
const wrapper = shallow(<Button type="primary" disabled />)
const wrapper = shallow(<Button type="primary" disabled>BUTTON</Button>)
expect(wrapper.find(Text).get(0).props.style).toEqual(
expect.arrayContaining([
expect.objectContaining({
Expand All @@ -84,6 +85,7 @@ describe('<Button />', () => {
it('onClick', () => {
const spy = sinon.spy()
const wrapper = shallow(<Button onClick={spy} />)
// @ts-ignore
wrapper.find(TouchableOpacity).at(0).props().onPress()
expect(spy.calledOnce).toBe(true)
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react'
import * as React from 'react'
import { View, TouchableWithoutFeedback } from 'react-native'
import { shallow } from 'enzyme'
import sinon from 'sinon'
import * as sinon from 'sinon'
import { Label, Checkbox, CheckboxGroup } from '../src'
import renderer from 'react-test-renderer'
import * as renderer from 'react-test-renderer'

describe('<Checkbox />', () => {
describe('<Checkbox />', () => {
Expand All @@ -29,6 +29,7 @@ describe('<Checkbox />', () => {
const wrapper = shallow(
<Checkbox onChange={onChange} />
)
// @ts-ignore
wrapper.find(TouchableWithoutFeedback).at(0).props().onPress()
expect(onChange.calledOnce).toBe(true)
expect(wrapper.state('checked')).toBe(true)
Expand All @@ -39,6 +40,7 @@ describe('<Checkbox />', () => {
const wrapper = shallow(
<Checkbox onChange={onChange} disabled={true} />
)
// @ts-ignore
wrapper.find(TouchableWithoutFeedback).at(0).props().onPress()
expect(onChange.calledOnce).toBe(false)
expect(wrapper.state('checked')).toBe(false)
Expand All @@ -57,12 +59,12 @@ describe('<Checkbox />', () => {
<Label><Checkbox value={2} /></Label>
</CheckboxGroup>
)
wrapper.find(Checkbox).at(0).props().onChange({ checked: true })
wrapper.find(Checkbox).at(0).props().onChange!({ checked: true, value: 0 })
expect(spy.calledOnce).toBe(true)
wrapper.find(Checkbox).at(0).props().onChange({ checked: false })
wrapper.find(Checkbox).at(0).props().onChange!({ checked: false, value: 0 })
expect(spy.calledTwice).toBe(true)
wrapper.find(Checkbox).at(1).props().onChange({ checked: true })
wrapper.find(Checkbox).at(2).props().onChange({ checked: true })
wrapper.find(Checkbox).at(1).props().onChange!({ checked: true, value: 1 })
wrapper.find(Checkbox).at(2).props().onChange!({ checked: true, value: 2 })
expect(spy.callCount).toBe(4)
})
})
Expand Down
83 changes: 0 additions & 83 deletions packages/taro-components-rn/__tests__/icon.spec.js

This file was deleted.

Loading

0 comments on commit f87c5ce

Please sign in to comment.