安装

Composer安装 yii2 download

1
2
3
4
5
# 基础包 一般推荐这里开始
composer create-project yiisoft/yii2-app-basic yiibase 2.0.12

# 前后台集成的专业包
composer create-project yiisoft/yii2-app-advanced yiiadv 2.0.12

目录权限

1
2
3
chmod 777 runtime
chmod 777 web/assets
chmod 0755 yii

数据迁移

  • 配置数据库连接

打开

1
common\config\main-local.php

  • 创建迁移表
1
./yii migrate/create create_blog_table

blog 是表名

1
advanced\console\migrations
文件位置

  • 执行迁移
1
./yii migrate

gii 代码生成器

需要开启开发者模式

http://localhost:8888/yiiadv/frontend/web/index.php?r=gii

api 调试工具
1
postman

https://www.getpostman.com/apps

路由地址

  • 开启
    1
    
    cponfig\web.php
1
2
3
4
5
6
'urlManager' => [
    'enablePrettyUrl' => true,
    'showScriptName' => false,
    'rules' => [
    ],
],
  • nginx配置
1
2
cd /usr/local/nginx/conf/vhost
vi xxxxx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server {
    listen       80;
    server_name  reson.com;

    location / {
        root   D:/wwwroot/reson/web;
        index  index.html index.php;
        if (!-e $request_filename){
            rewrite ^/(.*) /index.php last;
        }
    }

    location ~ \.php$ {
        root           D:/wwwroot/reson/web;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}
  • apache配置
    1
    
    .htaccess
1
2
3
4
5
6
7
8
9
10
11
Options +FollowSymLinks
IndexIgnore */*

RewriteEngine on

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# otherwise forward it to index.php
RewriteRule . index.php

部署

  • 修改
    1
    
    web/index.php
1
2
3
// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', false);
defined('YII_ENV') or define('YII_ENV', 'prod');
  • 1
    
    runtime
    www 权限
1
chown -R www:www runtime/
  • 修改跨域目录
1
vi /usr/local/nginx/conf/fastcgi.conf
  • 开发环境的部署脚本
1
2
3
4
5
6
7
8
#!/bin/bash

#./bin/dev/deploy.sh

composer install # 它来把 composer 所有的依赖安装好
./init  --env=Development --overwrite=y  # 重新初始化环境配置

# 等等 我们还有许多别的,例如: bower install ,因为我们的静态资源是使用的 bower 来管理的 
  • 线上部署脚本
1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
# file ./bin/prod/deploy.sh

# ... ...  
composer install --prefer-dist --no-dev --no-progress --optimize-autoloader

# 初始化 php 环境变量
./init --env=Production --overwrite=y

# git submodule
git submodule init
git submodule update

控制器 post 关闭
1
Csrf

1
2
3
4
5
6
7
    'components' => [
        'request' => [
            // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
            'cookieValidationKey' => 'EGETcj5HFf1_krlY-gb3rtM5Vcp2mAeS',
            'enableCookieValidation' => false,
            'enableCsrfValidation' => false,
        ],

superagent post 收不到

1
2
3
4
5
6
7
8
9
function toy_update (data, callback) {
    superagent
        .post("/fix-title")
        .type('form')
        .send(data)
        .end(function (err, res) {
            callback(err, res);
        });
}

需要设置

1
.type('form')

AR

http://www.yiichina.com/doc/api/2.0/yii-db-activequery http://www.yiichina.com/doc/api/2.0/yii-db-query http://www.yiichina.com/doc/guide/2.0/db-query-builder

Read More

当前环境

  • RN 0.45

1
https
访问

1
Info.plist
中添加
1
NSAppTransportSecurity
类型
1
Dictionary
。 在
1
NSAppTransportSecurity
下添加
1
NSAllowsArbitraryLoads
类型
1
Boolean
, 值设为
1
YES

添加例外的方式也很简单: 左键

1
Info.plist
选择 open with source code 然后添加类似如下的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>qq.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
        <key>sina.com.cn</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
        </dict>
</dict>

Text 换行问题

  1. 设置属性

    <Text numberOfLines={3} style={indexStyle.rowTitle}>{rowData.item.title}</Text>

  2. 计算宽度

    rowTitle: { width: Dimen.window.width - 100, margin: 5, fontSize: 12 },

图片懒加载
1
react-native-lazyload

https://github.com/magicismight/react-native-lazyload

yarn add react-native-lazyload

1
2
3
4
5
6
<LazyloadScrollView name="lazyload-list" style={indexStyle.container}>
<LazyloadImage
                        host="lazyload-list"
                        style={indexStyle.rowImage}
                        source=/>
</LazyloadScrollView>

remote debugger is in a background tab …

chrome调试器,单独页打开不要跑到后台,就不会出现这个烦人的提示了~

clone对象

1
2
3
4
5
6
7
import _ from 'lodash'

const obj = {
    a:1,
    b:2
}
const newObj = _.cloneDeep(obj);

对两个对象进行验证

1
2
JSON.stringify(obj) == JSON.stringify(newObj)   //true
obj == newObj                                   //false

本地缓存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { AsyncStorage } from 'react-native';

// 设置
let storageKey = `index2:toy:${params.toyType}`;
AsyncStorage.setItem(storageKey, JSON.stringify(dataList), 
    err => {
        if(!err){
            console.log(`AsyncStorage set ok => ${storageKey}`);
        }
    }
);

// 读取
let storageKey = `index2:toy:${toyType}`;
AsyncStorage.getItem(storageKey).then((value) => {
    let jsonValue = JSON.parse(value);
    if(jsonValue!=null){
        console.log(`AsyncStorage get ok => ${storageKey}`);
        dispatch(setupData(jsonValue, params));
    }
});

import 特点

默认文件

1
index.js

判断android还是ios

var Platform = require(‘Platform’); if (Platform.OS === ‘android’) { //todo
}else{
//todo
}

Toast 在Modal中使用 被覆盖

https://github.com/ant-design/ant-design-mobile/issues/547

本机调试 android

  • 查看设备
    1
    
    adb devices
  • 安装
    1
    
    react-native run-android
  • 安装发布
    1
    
    react-native run-android --variant=release
  • 签名
  • 打开开发者菜单
    1
    
    adb shell input keyevent 82
  • 1
    
    Dev Settings
    ->
    1
    
    Debug server host for device
    ->
    1
    
    本机IP:8081
    ->
    1
    
    Reload JS
  • 如果配置完还是白屏 ,重新安装
    1
    
    react-native run-android

Read More

主要构成

  • 1
    
    StackNavigator
    : 类似于普通的Navigator,屏幕上方导航栏
  • 1
    
    TabNavigator
    : 相当于iOS里面的TabBarController,屏幕下方的标签栏
  • 1
    
    DrawerNavigator
    : 抽屉效果,侧边滑出

  • 官方文档

https://reactnavigation.org/docs/intro/

StackNavigator 导航栏

API:

1
StackNavigator(RouteConfigs, StackNavigatorConfig)

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
// 注册导航
const Navs = StackNavigator({
    Home: { screen: Tabs },
    HomeTwo: {
        screen: HomeTwo,  // 必须, 其他都是非必须
        path:'app/homeTwo', 使用url导航时用到,  web app  Deep Linking
        navigationOptions: {}  // 此处设置了, 会覆盖组件内的`static navigationOptions`设置. 具体参数详见下文
    },
    HomeThree: { screen: HomeThree },
    HomeFour: { screen: HomeFour }
}, {
    initialRouteName: 'Home', // 默认显示界面
    navigationOptions: {  // 屏幕导航的默认选项, 也可以在组件内用 static navigationOptions 设置(会覆盖此处的设置)
        header: {  // 导航栏相关设置项
            backTitle: '返回',  // 左上角返回键文字
            style: {
                backgroundColor: '#fff'
            },
            titleStyle: {
                color: 'green'
            }
        },
        cardStack: {
            gesturesEnabled: true
        }
    }, 
    mode: 'card',  // 页面切换模式, 左右是card(相当于iOS中的push效果), 上下是modal(相当于iOS中的modal效果)
    headerMode: 'screen', // 导航栏的显示模式, screen: 有渐变透明效果, float: 无透明效果, none: 隐藏导航栏
    onTransitionStart: ()=>{ console.log('导航栏切换开始'); },  // 回调
    onTransitionEnd: ()=>{ console.log('导航栏切换结束'); }  // 回调
});
  • 参数:

    • title: 导航栏的标题

    • header: 导航栏设置对象
      • visible: 导航栏是否显示
      • title: 导航栏的标题, 可以是字符串也可以是个组件
      • backTitle: 左上角的返回键文字, 默认是上一个页面的title
      • right: 导航栏右按钮
      • left: 导航栏左按钮
      • style: 导航栏的style
      • titleStyle: 导航栏的title的style
      • tintColor: 导航栏颜色
      • cardStack: 配置card stack
    • gesturesEnabled: 是否允许右滑返回,在iOS上默认为true,在Android上默认为false

在组件中设置

1
static navigationOptions
示例:

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
static navigationOptions = {
    title: 'homeThree',
    header: (navigation, defaultHeader) => ({
      ...defaultHeader,  // 默认预设
      visible: true  // 覆盖预设中的此项
    }),
    cardStack: {
        gesturesEnabled: false  // 是否可以右滑返回
    }
};

// 或这样
static navigationOptions = {
    // title: 'Two', // 写死标题
    title: (navigation, childRouter) => {  // 动态标题
        if (navigation.state.params.isSelected) {
            return `${navigation.state.params.name}选中`;
        } else {
            return `${navigation.state.params.name}没选中`;
        }
    },
    header: ({ state, setParams, goBack }) => {
        let right;
        if (state.params.isSelected) {
            right = (<Button title="取消" onPress={() => setParams({ isSelected: false })}/>);
        } else {
            right = (<Button title="选择" onPress={() => setParams({ isSelected: true })}/>);
        }
        let left = (<Button title="返回" onPress={() => goBack()}/>);
        let visible = false;  // 是否显示导航栏
        return { right, left, visible };
    },
    // header: {left: <Button title="返回"/>},
};

StackNavigatorConfig

  • 参数:

    • initialRouteName: 设置默认的页面组件,必须是上面已注册的页面组件
    • initialRouteParams: 初始路由的参数
    • navigationOptions: 屏幕导航的默认选项
    • paths: RouteConfigs里面路径设置的映射

    • mode: 页面切换模式:
      • card: 普通app常用的左右切换
      • modal: 上下切换
    • headerMode: 导航栏的显示模式:
      • float: 无透明效果, 默认
      • screen: 有渐变透明效果, 如微信QQ的一样
      • none: 隐藏导航栏
    • cardStyle: 样式

    • onTransitionStart: 页面切换开始时的回调函数

    • onTransitionEnd: 页面切换结束时的回调函数

TabNavigator 标签栏

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// 注册tabs
const Tabs = TabNavigator({
    Home: {
        screen: Home,
        navigationOptions: {  // 也可以写在组件的static navigationOptions内
            tabBar: {
                label: '首页',
                icon: ({tintColor}) => (<Image source={require('./app/images/home.png')} style={[{tintColor: tintColor},styles.icon]}/>),
            },
        }
    },
    Bill: {
        screen: Bill,
        navigationOptions: {
            tabBar: {
                label: '账单',
               icon: ({tintColor}) => (<Image source={require('./app/images/bill.png')} style={[{tintColor: tintColor},styles.icon]}/>),
            },
        }
    },
    Me: {
        screen: Me,
        navigationOptions: {
            tabBar: {
                label: '我',
                icon: ({tintColor}) => (<Image source={require('./app/images/me.png')} style={[{tintColor: tintColor},styles.icon]}/>),
            },
        }
    }
  }, {
      animationEnabled: false, // 切换页面时是否有动画效果
      tabBarPosition: 'bottom', // 显示在底端,android 默认是显示在页面顶端的
      swipeEnabled: false, // 是否可以左右滑动切换tab
      backBehavior: 'none', // 按 back 键是否跳转到第一个Tab(首页), none 为不跳转
      tabBarOptions: {
          activeTintColor: '#ff8500', // 文字和图片选中颜色
          inactiveTintColor: '#999', // 文字和图片未选中颜色
          showIcon: true, // android 默认不显示 icon, 需要设置为 true 才会显示
          indicatorStyle: {
              height: 0  // 如TabBar下面显示有一条线,可以设高度为0后隐藏
          }, 
          style: {
              backgroundColor: '#fff', // TabBar 背景色
              // height: 44
          },
          labelStyle: {
              fontSize: 10, // 文字大小
          },
      },
});

DrawerNavigator抽屉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const DrawerNav = DrawerNavigator({
    Home: { screen: Home },
    Bill: { screen: Bill },
    Me: { screen: Me },
    HomeTwo: { screen: HomeTwo },
    HomeThree: { screen: HomeThree },
    HomeFour: { screen: HomeFour },
    BillTwo: { screen: BillTwo },
    BillThree: { screen: BillThree }
}, {
    drawerWidth: 200, // 抽屉宽
    drawerPosition: 'left', // 抽屉在左边还是右边
    // contentComponent: CustomDrawerContentComponent,  // 自定义抽屉组件
    contentOptions: {
      initialRouteName: Home, // 默认页面组件
      activeTintColor: 'white',  // 选中文字颜色
      activeBackgroundColor: '#ff8500', // 选中背景颜色
      inactiveTintColor: '#666',  // 未选中文字颜色
      inactiveBackgroundColor: '#fff', // 未选中背景颜色
      style: {  // 样式

      }
    }
});

在StackNavigator中注册后的组件都有navigation这个属性. navigation又有5个参数:navigate, goBack, state, setParams, dispatch, 可以在组件下console.log一下this.props就能看到.

  • this.props.navigation.navigate(‘Two’, { name: ‘two’ }): push下一个页面
    • routeName: 注册过的目标路由名称
    • params: 传递的参数
    • action: 如果该界面是一个navigator的话,将运行这个sub-action
  • this.props.navigation.goBack(): 返回上一页

  • this.props.navigation.state: 每个界面通过这去访问它的router,state其中包括了:
    • routeName: 路由名
    • key: 路由身份标识
    • params: 参数
  • this.props.navigation.setParams: 该方法允许界面更改router中的参数,可以用来动态的更改导航栏的内容

  • this.props.navigation.dispatch: 可以dispatch一些action,主要支持的action有:

    • Navigate:
1
2
3
4
5
6
7
8
9
10
  import { NavigationActions } from 'react-navigation'

  const navigationAction = NavigationActions.navigate({
    routeName: 'Profile',
    params: {},

    // navigate can have a nested navigate action that will be run inside the child router
    action: NavigationActions.navigate({ routeName: 'SubProfileRoute'})
  })
  this.props.navigation.dispatch(navigationAction)
  • Reset: Reset方法会清除原来的路由记录,添加上新设置的路由信息, 可以指定多个action,index是指定默认显示的那个路由页面, 注意不要越界了
1
2
3
4
5
6
7
8
9
10
  import { NavigationActions } from 'react-navigation'

  const resetAction = NavigationActions.reset({
    index: 0,
    actions: [
      NavigationActions.navigate({ routeName: 'Profile'}),
      NavigationActions.navigate({ routeName: 'Two'})
    ]
  })
  this.props.navigation.dispatch(resetAction)
  • SetParams: 为指定的router更新参数,该参数必须是已经存在于router的param中
1
2
3
4
5
6
7
8
  import { NavigationActions } from 'react-navigation'

  const setParamsAction = NavigationActions.setParams({
    params: {}, // these are the new params that will be merged into the existing route params
    // The key of the route that should get the new params
    key: 'screen-123',
  })
  this.props.navigation.dispatch(setParamsAction)
  • 支持以下actions:
    • Navigate:
    • Reset:
    • Back:
    • Set Params:
    • Init:

其他app或浏览器使用url打开次app并进入指定页面. 如浏览器输入url demo4://home/home3直接进入home3页面.

iOS版设置

  • 使用Xcode设置Schemes;

  • 在AppDelegate添加一下代码:

1
2
3
4
5
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
  return [RCTLinkingManager application:application openURL:url
                      sourceApplication:sourceApplication annotation:annotation];
}
  • js组件在注册路由时设置唯一的路径path, 例如Home2:
1
{ screen: Home2, path:'app/Home2' };
  • 在手机浏览器访问demo4://app/Home2, 弹窗选择打开, 就可以打开demo4 app并进到Home2页面了.

Read More

配置RN环境+antdm蚂蚁金服界面库

本机都是在macos下操作

安装包

1
2
3
4
5
6
brew install node
brew install watchman
brew install flow

npm install -g yarn
npm install -g react-native-cli

如果没有 Homebrew

/usr/bin/ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)”

配置
1
yarn
1
npm
国内镜像

参考: https://npm.taobao.org/

  • npm
1
npm --registry https://registry.npm.taobao.org info underscore
  • yarn
1
yarn config set registry https://registry.npm.taobao.org

创建项目

1
react-native init myapp

过程漫长,请先

1
科学上网

运行

1
react-native run-ios

第一次运行,自动配置项目环境,进行编译,时间会有点长,正常将看到

1
ios模拟器
` 启动程序

1
Cmd+D
调出
1
调试面板

加入蚂蚁金服界面库

  • 安装包
1
2
yarn add antd-mobile
yarn add babel-plugin-import -dev
  • 修改
    1
    
    .babelrc

参考: https://github.com/ant-design/babel-plugin-import

1
2
3
4
{
  "presets": ["react-native"],
  "plugins": [["import", { "libraryName": "antd-mobile", "style": true }]]
}
  • 修改
    1
    
    index.ios.js
1
2
3
4
5
6
7
8
9
10
11
import React, { Component } from 'react';
import { AppRegistry } from 'react-native';
import { Button } from 'antd-mobile';

class HelloWorldApp extends Component {
  render() {
    return <Button>Start</Button>;
  }
}

AppRegistry.registerComponent('HelloWorldApp', () => HelloWorldApp);

在模拟器中

1
Cmd+R
重新载入程序

Read More

安装

1
composer require laravel/passport

配置

1
2
3
4
5
6
vi config/app.php

-> providers

Laravel\Passport\PassportServiceProvider::class,

数据库安装

1
php artisan migrate
  • 1
    
    1071坑

错误信息

1
2
  SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table   
  `users` add unique `users_email_unique`(`email`))     

修正, 需要设置默认字符串字段长度

1
2
3
4
5
6
7
8
9
10
11
12
vi aoo/Providers/AppServiceProvider.php

use Illuminate\Support\Facades\Schema;

...

public function boot()
{
    //
    Schema::defaultStringLength(191);
}

成功信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table
Migrating: 2016_06_01_000001_create_oauth_auth_codes_table
Migrated:  2016_06_01_000001_create_oauth_auth_codes_table
Migrating: 2016_06_01_000002_create_oauth_access_tokens_table
Migrated:  2016_06_01_000002_create_oauth_access_tokens_table
Migrating: 2016_06_01_000003_create_oauth_refresh_tokens_table
Migrated:  2016_06_01_000003_create_oauth_refresh_tokens_table
Migrating: 2016_06_01_000004_create_oauth_clients_table
Migrated:  2016_06_01_000004_create_oauth_clients_table
Migrating: 2016_06_01_000005_create_oauth_personal_access_clients_table
Migrated:  2016_06_01_000005_create_oauth_personal_access_clients_table

配置key

1
2
3
4
5
6
7
8
php artisan passport:install

Personal access client created successfully.
Client ID: 1
Client Secret: 0rUr7KwBvfCoAvU8PAnhYjkS3N6HdPf8OlZBMMT8
Password grant client created successfully.
Client ID: 2
Client Secret: YdY3q364Sm2K6UqV2HhkJqaE3yW9oeZ1ksg3VMjV

##

Read More

本机环境

  • lnmp 1.4
  • centos 6.9
  • php 5.6

安装 lnmp集成环境

  • lnmp.org https://lnmp.org/install.html
1
wget -c http://soft.vpser.net/lnmp/lnmp1.4.tar.gz && tar zxf lnmp1.4.tar.gz && cd lnmp1.4 && ./install.sh lnmp

创建项目

1
2
3
laravel new blog
or
composer create-project --prefer-dist laravel/laravel blog

安装 composer

1
The Process class relies on proc_open, which is not available on your PHP installation.

在php.ini中,找到disable_functions选项,看看后面是否有 proc_open proc_get_status 函数被禁用了,如果有的话,去掉即可

修改nginx配置

1
2
3
4
5
6
7
cd /usr/local/nginx/conf/vhost/
vi host...

        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }
        

调试方便打开php.ini配置

生产环境请关闭

1
2
vi /usr/local/php/etc/php.ini
display_errors = On

添加新站点

  • 客户机添加host测试网址配置
1
vi /private/etc/hosts
  • centos添加新站点
1
lnmp vhost add

修改跨域目录

项目目录下的

1
.user.ini
保持不变,我们做加法。

1
2
3
4
5
6
7
vi /usr/local/nginx/conf/fastcgi.conf

生产环境,加入你的项目地址
fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root/:/tmp/:/proc/:/home/wwwroot/default/blog";

如果本机测试开发,直接注释本行
# fastcgi_param PHP_ADMIN_VALUE ...

配置目录权限

1
2
3
4
5
6
chattr -i blog/public/.user.ini
chown -R www:www blog/
chattr +i blog/public/.user.ini
cd blog/
chmod -R 775 storage
chmod -R 775 bootstrap

配置key

1
php artisan key:generate

重启环境

1
lnmp reload

文档

  • https://laravel.com/
  • https://docs.golaravel.com/docs/5.4/installation/

Read More

Composer

参考

安装

  • 下载包
1
2
3
4
5
php -r "copy('https://install.phpcomposer.com/installer', 'composer-setup.php');"

php composer-setup.php

php -r "unlink('composer-setup.php');"
  • 全局安装
1
2
3
4
5
6
7
8
// macos
// composer.phar 文件移动到 /usr/local/bin/
sudo mv composer.phar /usr/local/bin/composer

// windows
// composer.phar 复制到 php.exe 在同一级目录
// 在 PHP 安装目录下新建一个 composer.bat 文件
@php "%~dp0composer.phar" %*

修改镜像

1
composer config -g repo.packagist composer https://packagist.phpcomposer.com

Read More

Shadowsocks

setup

1
2
3
yum install -y python-setuptools #安装setuptools 
easy_install pip #安装pip
pip install shadowsocks #安装package

config

1
2
3
4
5
6
7
8
9
10
11
12
13
vi /etc/shadowsocks.json

{
 "server":"your server ip",
 "local_address": "127.0.0.1",
 "local_port":1080,
  "port_password": {
     "8080": "password"
 },
 "timeout":300,
 "method":"aes-256-cfb",
 "fast_open": false
}

run

ssserver -c /etc/shadowsocks.json -d start #启动 ssserver -c /etc/shadowsocks.json -d stop #停止

boot

1
2
vi /etc/rc.d/rc.local
ssserver -c /etc/shadowsocks.json -d start

nscd hosts缓存

1
2
3
4
5
6
yum install -y nscd
/etc/rc.d/init.d/nscd start
/etc/rc.d/init.d/nscd restart

vi /etc/nscd.conf
enable-cache hosts yes

dns

1
2
3
4
5
6
7
vi /etc/sysconfig/network-scripts/ifcfg-eth0
dns1=8.8.8.8
dns2=8.8.4.4

vi /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4

Read More

技术栈

react-router@2.x + redux-saga + redux

Features

todoList

  • 支持多入口
  • 静态文件加戳
  • dev-server配置
  • 目录结构优化
  • webpack配置拆分
  • 使用react-router路由
  • fetch语法支持
  • 静态文件输出
  • 打包后js文件过大
  • HMR热更新
  • css打包存在问题
  • 验证多less文件的合并情况
  • 图片目录
  • css压缩
  • 代码拆分

参考

1
2
3
4
- [React + Redux 最佳实践](https://github.com/sorrycc/blog/issues/1)
- [react-molin](https://github.com/Molin123/react-molin)
- [dva](https://github.com/dvajs/dva)
- [redux-saga](https://github.com/superRaytin/redux-saga-in-chinese)

Read More

技术栈

React技术栈

基础

  • react15
  • es6
  • flex
  • less
  • sass
  • TypeScript

插件

  • redux

    • redux-saga https://github.com/superRaytin/redux-saga-in-chinese
  • mobx
  • react-router4
  • fetch

框架

  • dva

    https://github.com/dvajs/dva

  • react-molin

    https://github.com/Molin123/react-molin

组件

  • antd-mobile

    https://mobile.ant.design/components

编译

  • webpack2
  • gulp
  • ESlint
  • mock

    https://juejin.im/post/58ff1fae61ff4b0066792f6e https://www.easy-mock.com/

  • swagger

    http://swagger.io/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- 组件收集
    - https://github.com/brillout/awesome-react-components
    - [devarchy](https://devarchy.com/react)

- Mobile
    - [mobile.ant](https://mobile.ant.design/index-cn)
    - [OnsenUI](https://onsen.io/)
    - [amazeui](http://amazeui.org/)
    - [TouchstoneJS](http://touchstonejs.io/)
    - [reactionic](http://reactionic.github.io/)
    - [React-UI](http://www.react-d.com/)

- PC
    - [material-ui](http://www.material-ui.com/)
    - [Elemental UI](http://elemental-ui.com/)
    - [React Bootstrap](https://react-bootstrap.github.io/)
    - [reactstrap](https://github.com/reactstrap/reactstrap)
    - [Grommet](https://grommet.github.io/)
    - [Antd](https://ant.design/index-cn)
    - [react.semantic-ui](http://react.semantic-ui.com/)

Read More