Skip to content

Commit

Permalink
feat(taro-tt): 增加头条小程序运行时适配框架
Browse files Browse the repository at this point in the history
  • Loading branch information
luckyadam committed Nov 25, 2018
1 parent 7991846 commit 9296268
Show file tree
Hide file tree
Showing 17 changed files with 1,244 additions and 1 deletion.
1 change: 1 addition & 0 deletions lerna.json
Expand Up @@ -25,6 +25,7 @@
"packages/taro-weapp",
"packages/taro-swan",
"packages/taro-alipay",
"packages/taro-tt",
"packages/taro-webpack-runner",
"packages/postcss-plugin-constparse",
"packages/eslint-config-taro",
Expand Down
3 changes: 3 additions & 0 deletions packages/taro-tt/README.md
@@ -0,0 +1,3 @@
# @tarojs/taro-tt

多端解决方案头条小程序端基础框架
2 changes: 2 additions & 0 deletions packages/taro-tt/index.js
@@ -0,0 +1,2 @@
module.exports = require('./dist/index.js').default
module.exports.default = module.exports
50 changes: 50 additions & 0 deletions packages/taro-tt/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions packages/taro-tt/package.json
@@ -0,0 +1,31 @@
{
"name": "@tarojs/taro-tt",
"version": "1.2.0-beta.2",
"description": "Taro toutiao framework",
"main": "index.js",
"files": [
"dist",
"src",
"index.js",
"package.json"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "rollup -c rollup.config.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/NervJS/taro.git"
},
"keywords": [
"taro"
],
"author": "O2Team",
"license": "MIT",
"dependencies": {
"@tarojs/taro": "1.2.0-beta.2",
"@tarojs/utils": "1.2.0-beta.2",
"lodash": "^4.17.10",
"prop-types": "^15.6.1"
}
}
74 changes: 74 additions & 0 deletions packages/taro-tt/rollup.config.js
@@ -0,0 +1,74 @@
const { join } = require('path')
const resolve = require('rollup-plugin-node-resolve')
const babel = require('rollup-plugin-babel')
const common = require('rollup-plugin-commonjs')
const alias = require('rollup-plugin-alias')
const cwd = __dirname

const baseConfig = {
input: join(cwd, 'src/index.js'),
external: ['nervjs'],
output: [
{
file: join(cwd, 'dist/index.js'),
format: 'cjs',
sourcemap: true,
exports: 'named'
},
{
file: join(cwd, 'dist/taro-tt.js'),
format: 'umd',
name: 'TaroTt',
sourcemap: true,
exports: 'named'
}
],
plugins: [
alias({
'@tarojs/taro': join(cwd, '../taro/src/index'),
'@tarojs/utils': join(cwd, '../taro-utils/dist/index')
}),
resolve({
preferBuiltins: false
}),

common({
include: 'node_modules/**'
}),
babel({
babelrc: false,
presets: [
['@babel/preset-env', {
modules: false
}]
],
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-object-rest-spread',
['@babel/plugin-transform-react-jsx', {
'pragma': 'Nerv.createElement'
}]
]
})
]
}
const esmConfig = Object.assign({}, baseConfig, {
output: Object.assign({}, baseConfig.output, {
sourcemap: true,
format: 'es',
file: join(cwd, 'dist/index.esm.js')
})
})

function rollup () {
const target = process.env.TARGET

if (target === 'umd') {
return baseConfig
} else if (target === 'esm') {
return esmConfig
} else {
return [baseConfig, esmConfig]
}
}
module.exports = rollup()
104 changes: 104 additions & 0 deletions packages/taro-tt/src/component.js
@@ -0,0 +1,104 @@
import { enqueueRender } from './render-queue'
import { updateComponent } from './lifecycle'
import {
internal_safe_get as safeGet
} from '@tarojs/taro'
// #组件state对应小程序组件data
// #私有的__componentProps更新用于触发子组件中对应obsever,生命周期componentWillReciveProps,componentShouldUpdate在这里处理
// #父组件传过来的props放到data.__props中供模板使用,这么做的目的是模拟reciveProps生命周期
// 执行顺序:组件setState -> 组件_createData() -> 对应的小程序组件setData(组件更新)-> 子组件的__componentProps.observer执行
// -> 触发子组件componentWillReciveProps,更新子组件props,componentShouldUpdate -> 子组件_createData -> 子组件setData

class BaseComponent {
// _createData的时候生成,小程序中通过data.__createData访问
__computed = {}
// this.props,小程序中通过data.__props访问
__props = {}
__isReady = false
// 会在componentDidMount后置为true
__mounted = false
nextProps = {}
_dirty = true
_disable = true
_pendingStates = []
_pendingCallbacks = []
$componentType = ''
$router = {
params: {}
}

constructor (props = {}, isPage) {
this.state = {}
this.props = {}
this.$componentType = isPage ? 'PAGE' : 'COMPONENT'
}
_constructor (props) {
this.props = props || {}
}
_init (scope) {
this.$scope = scope
}
setState (state, callback) {
if (state) {
(this._pendingStates = this._pendingStates || []).push(state)
}
if (typeof callback === 'function') {
(this._pendingCallbacks = this._pendingCallbacks || []).push(callback)
}
if (!this._disable) {
enqueueRender(this)
}
}

getState () {
const { _pendingStates, state, props } = this
const stateClone = Object.assign({}, state)
delete stateClone.__data
if (!_pendingStates.length) {
return stateClone
}
const queue = _pendingStates.concat()
this._pendingStates.length = 0
queue.forEach((nextState) => {
if (typeof nextState === 'function') {
nextState = nextState.call(this, stateClone, props)
}
Object.assign(stateClone, nextState)
})
return stateClone
}

forceUpdate (callback) {
if (typeof callback === 'function') {
(this._pendingCallbacks = this._pendingCallbacks || []).push(callback)
}
updateComponent(this)
}

// 会被匿名函数调用
__triggerPropsFn (key, args) {
const keyChain = key.split('.')
const reduxFnPrefix = '__event_'
const reduxFnName = reduxFnPrefix + keyChain.shift()
// redux标识过的方法,直接调用
if (reduxFnName in this) {
const scope = args.shift()
let fn
if (keyChain.length > 0) {
fn = safeGet(this[reduxFnName], keyChain.join('.'))
} else {
fn = this[reduxFnName]
}
fn.apply(scope, args)
} else {
// 普通的
const keyLower = key.toLocaleLowerCase()
this.$scope.triggerEvent(keyLower, {
__isCustomEvt: true,
__arguments: args
})
}
}
}

export default BaseComponent
45 changes: 45 additions & 0 deletions packages/taro-tt/src/create-app.js
@@ -0,0 +1,45 @@
function createApp (AppClass) {
const app = new AppClass()
const weappAppConf = {
onLaunch (options) {
app.$app = this
app.$app.$router = app.$router = {
params: options
}
if (app.componentWillMount) {
app.componentWillMount()
}
if (app.componentDidMount) {
app.componentDidMount()
}
},

onShow (options) {
Object.assign(app.$router.params, options)
if (app.componentDidShow) {
app.componentDidShow()
}
},

onHide () {
if (app.componentDidHide) {
app.componentDidHide()
}
},

onError (err) {
if (app.componentDidCatchError) {
app.componentDidCatchError(err)
}
},

onPageNotFound (obj) {
if (app.componentDidNotFound) {
app.componentDidNotFound(obj)
}
}
}
return Object.assign(weappAppConf, app)
}

export default createApp

0 comments on commit 9296268

Please sign in to comment.