Giter VIP home page Giter VIP logo

blog's People

Contributors

zoeyyoung avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

blog's Issues

构建一个 React Redux CRUD 应用的 STEP

A Guide For Building A React Redux CRUD App

不错的总结,大概在创建一个功能模块的时候都要有这几个步骤,记录下几个问题

STEP 1 — Write Detailed Mocks For Each Page And Phases.

用到的软件:balsamiq-mockups

Mac 下可以用 brew cask 安装:brew cask install balsamiq-mockups

因为所有页面都采用AJAX请求来加载数据,因此都同时需要设计“Success(成功)”,"Loading(加载中)","Error(错误)"阶段的页面

STEP 2 — Divide Each Page Into Components

拆分组件通常比较简单

Redux Terms

  • “Actions” And “States”
  • “Action Creators”
  • “Dispatching an Action”

PATTERN: Dealing With Async Actions

在处理异步请求时,通常具有如下的模式:

Initial State

{postsList:{posts:[], loading:false, error:null}}

Actions

1.“FETCH_OBJ”(for loading) 加载数据,设置加载中状态

{postsList:{posts:[], loading:true, error:null}}

2.“FETCH_OBJ_SUCCESS” 数据请求成功时分发

{postsList:{posts:[post1, post2], loading:false, error:null}}

3.“FETCH_OBJ_FAILURE” 数据请求失败时分发

{postsList:{posts:[], loading:false, error:{err: "Error Msg"}}}

4.“OBJ_RESET”(to cleanup dirty previous state)

{postsList:{posts:[], loading:false, error:null}}

只有一个小问题,就是如何区分是无数据,还是未加载?业务可能需要在无数据时显示特定的提示。追加一个数据是否为空的字段?扩展 loading 状态?

STEP 3 — List State and Actions For Each Component (AND For Each Phase)

列出所有可能改变组件展示的状态作为 States,并确定初始 state,确定可能的 Actions

这步通常大概一下就可以了

STEP 4 — Create Action Creators For Each Action

STEP 5 — Write Reducers For Each Action

这两步注意到一点,就是异步请求没有使用redux-thunk,在Container中分别使用了三个 Action Creator :

export function fetchPosts() {
  const request = axios({
    method: 'get',
    url: `${ROOT_URL}/posts`,
    headers: []
  });

  return {
    type: FETCH_POSTS,
    payload: request
  };
}

export function fetchPostsSuccess(posts) {
  return {
    type: FETCH_POSTS_SUCCESS,
    payload: posts
  };
}

export function fetchPostsFailure(error) {
  return {
    type: FETCH_POSTS_FAILURE,
    payload: error
  };
}

如果使用redux-thunk,就可以组合成下面的一个 ActionCreator :

export function fetchPosts() {
  return dispatch => {
    dispatch({
      type: FETCH_POSTS,
    });
    axios({
      method: 'get',
      url: `${ROOT_URL}/posts`,
      headers: []
    }).then(response => {
      if (!response.error) {
        return dispatch({
          type: FETCH_POSTS_SUCCESS,
          payload: response
        });
      }
      dispatch({
        type: FETCH_POSTS_FAILURE,
        payload: error
      });
    });
  };
}

Redux Term: “Presentational” and “Container” Components

STEP 6 — Implement Every Presentational Component

实现所有展示型组件

STEP 7 — Create Container Component For Some/All Presentational Component

创建容器组件

STEP 8 — Finally Bring Them All Together

之前把 containers 理解成 pages 应该是错误的,一个 page 通常是由多个 containers 组成的

由于这个错误理解,把一些本应该是 container 的东西放到了 components 中 😵


有一定经验后,现在大概步骤看起来都很简单,不过在不熟悉之前还是走了不少弯路的

React Native

React Native项目github地址: https://github.com/facebook/react-native

React Native项目官网文档: http://facebook.github.io/react-native/docs/getting-started.html

遇到的问题

directory not found for option '-F/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.0.sdk/Developer/Library/Frameworks' "

http://stackoverflow.com/questions/30827022/xcode-7-library-search-path-warning/32620919

Tutorial里的fetchWeb API 的一部分

**a�ppKey修改??**AppDelegate.m文件

static registerComponent(appKey, () => Component);

�**闪屏界面修改?**LaunchScreen.xib文件

示例项目:

https://github.com/ColinEberhardt/ReactNative-PropertyFinder

Unit Testing

describe块称为"测试套件"(test suite),表示一组相关的测试
it块称为"测试用例"(test case),表示一个单独的测试,是测试的最小单位
测试框架 Mocha 实例教程

埋点

关于埋点组内有两种观点:

  • 一种是多多益善[1]:全部点击事件都埋了才能避免因为没有埋点导致无法进行统计;
  • 一种是有针对性的埋[2]:埋那么多无意义的点干啥;

目前我还是倾向于第二种观点

https://www.zhihu.com/question/23078534

埋点从来就不是一个技术活,而是一个需要对市场分析,用户体验,客户需求都要有所了解的活。

Webpack配置

Webpack 配置需要区分 dev 还是 pro;

线上环境需要更多性能上的优化;开发环境则要考虑热加载、自动刷新等;

区分NODE_ENV

  • "production" 线上环境
  • "development" 开发环境
Config DEV PRO
context Default: process.cwd()
entry o o
output o o
output.filename '[name].js' o o
output.path o o
output.publicPath
output.chunkFilename
output.sourceMapFilename
output.devtoolModuleFilenameTemplate
output.devtoolFallbackModuleFilenameTemplate
output.devtoolLineToLine
output.hotUpdateChunkFilename
output.hotUpdateMainFilename
output.jsonpFunction
output.hotUpdateFunction
output.pathinfo o x
output.library
output.libraryTarget
output.umdNamedDefine
output.sourcePrefix
output.crossOriginLoading
module
module.loaders o o
module.preLoaders, module.postLoaders
module.noParse
automatically created contexts defaults module.xxxContextXxx
resolve
resolve.alias
resolve.root
resolve.modulesDirectories
resolve.fallback
resolve.extensions Default: ["", ".webpack.js", ".web.js", ".js"]
resolve.packageMains
resolve.packageAlias
resolve.unsafeCache
resolveLoader
resolveLoader.moduleTemplates
externals
target
bail
profile Capture timing information for each module x o
cache enabled by default in watch mode o x
debug o x
devtool cheap-module-eval-source-map o x
devServer o x
node
amd
loader Custom values available in the loader context
recordsPath, recordsInputPath, recordsOutputPath
plugins o o

Loaders

Plugins

做什么 用什么 DEV PRO
定义全局变量 webpack.DefinePlugin o o
清理目录 Clean Webpack Plugin x o
拷贝目录/文件 Copy Webpack Plugin o o
生成单独的样式文件[非内联] Extract Text Plugin For Webpack o o
文件去重 webpack.optimize.DedupePlugin x o
打成多个包(通用库文件打包) webpack.optimize.CommonsChunkPlugin o o
webpack.optimize.OccurrenceOrderPlugin o o
压缩文件 webpack.optimize.UglifyJsPlugin x o
生成HTML文件 HtmlWebpackPlugin o o
webpack.HotModuleReplacementPlugin o x
加载完成后直接打开浏览器 Open Browser Webpack Plugin o x

启用source-map

devtool: 'cheap-module-eval-source-map'

Babel 6 import export default 问题

在Babel 5的时候,我们可以这样写

// foo.js
export default {
  foo: 'foo',
  bar: 'bar',
};

// bar.js Babel 5
import foobar, { foo, bar } from './foo';
console.log(foo); // 'foo'
console.log(bar); // 'bar'
console.log(foobar); // { foo: 'foo', bar: 'bar' }

但是到Babel 6的时候,foobar的值为undefined

之前一直不明白为啥Babel 6要改掉这种import default的方式,今天终于通过一个例子想通了

// foo.js
export const foo = 'foo-g'; // 1)
export default {
  foo: 'foo', // 2)
  bar: 'bar',
};

// bar.js Babel 5
import foobar, { foo, bar } from './foo';
console.log(foo); // 'foo-g'
console.log(bar); // undefined 这种时候bar就被隐藏了
console.log(foobar); // { foo: 'foo', bar: 'bar' }
import foobar from './foo'; 相当于 import { default as foobar } from './foo';

import foobar from './foo'; 相当于 import { default as foobar } from './foo';

那么写出import { bar, default as foobar } from './foo';感觉就有点怪怪的了

【OSX】命令行中使用 Sublime Text [打开/新建][文件/文件夹]

[注:如果使用oh-my-zsh,那么直接在插件列表里面添加sublime,就可以使用st来打开文件]

在命令行中查找文件时,经常会想直接查看文件内容、编辑文件或打开文件夹

如果用的是atom,直接就有快捷方式:

  • atom . 打开当前目录
  • atom 文件名 打开文件

Sublime Text 需要自己加这个快捷方式:

先确认环境变量PATH

> printenv | grep bin
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

创建快捷方式

sudo rm /usr/local/bin/subl
sudo ln -s /Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl /usr/local/bin/subl

然后就可以在命令行中直接用S�ublime Text打开目录或文件了:smile:

  • subl . 打开当前目录
  • subl 文件名 打开文件

《重来》

引言篇

互联网公司素来以疯狂招聘、大把烧钱、华丽落败而广为人知

😂

开局篇

卸负篇

哪来的从错误中学习

这个有点意思,通常说的失败是成功之母,这里说的是成功过的人再次成功的概率大,失败并不是成功的先决条件

计划即瞎猜

只有在做一件事的过程中,才能掌握更多的相关信息,没有人能够未卜先知。千万不要在行动之前就作出重大的决定。
无计划地工作看上去挺悬,但是盲目遵循不切实际的计划,后果则更可怕。

这个主要讲的是只需要制定短期的计划,经常计划。

行动篇

进阶篇

【安装/配置/使用】Sonar

文档:http://docs.sonarqube.org/display/SONAR/Documentation

Get Started in Two Minutes http://docs.sonarqube.org/display/SONAR/Get+Started+in+Two+Minutes

Sonar简介

Sonar是一个用于代码质量管理的开源平台,用于管理源代码的质量,可以从七个维度检测代码质量

通过插件形式,可以支持包括java,C#,C/C++,PL/SQL,Cobol,JavaScrip,Groovy等等二十几种编程语言的代码质量管理与检测

sonarQube能带来什么?

Developers' Seven Deadly Sins

  1. 糟糕的复杂度分布
  2. 重复
  3. 缺乏单元测试
  4. 没有代码标准
    • sonar可以通过PMD,CheckStyle,Findbugs等等代码规则检测工具规范代码编写
  5. 没有足够的或者过多的注释
    • 没有注释将使代码可读性变差,特别是当不可避免地出现人员变动时,程序的可读性将大幅下降
    • 而过多的注释又会使得开发人员将精力过多地花费在阅读注释上,亦违背初衷
  6. 潜在的bug
  7. 糟糕的设计(原文Spaghetti Design,意大利面式设计)
    1. 通过sonar可以找出循环,展示包与包、类与类之间的相互依赖关系
    2. 可以检测自定义的架构规则
    3. 通过sonar可以管理第三方的jar包
    4. 可以利用LCOM4检测单个任务规则的应用情况
    5. 检测耦合
    6. 关于Spaghetti Design:http://docs.codehaus.org/display/SONAR/Spaghetti+Design

通过sonar可以有效检测以上在程序开发过程中的七大问题

SonarQube安装

预置条件

  1. 已安装JAVA环境
  2. 已安装有MySQL数据库(其它数据库也可以) [非必须]

下载地址:http://www.sonarqube.org/downloads/

下载SonarQube与SonarQube Runner

中文补丁包下载:http://docs.codehaus.org/display/SONAR/Chinese+Pack (有点旧)

1. 数据库配置【非必须】

进入数据库命令

# mysql -u root -p
mysql> CREATE DATABASE sonar CHARACTER SET utf8 COLLATE utf8_general_ci;
mysql> CREATE USER 'sonar' IDENTIFIED BY 'sonar';
mysql> GRANT ALL ON sonar.* TO 'sonar'@'%' IDENTIFIED BY 'sonar';
mysql> GRANT ALL ON sonar.* TO 'sonar'@'localhost' IDENTIFIED BY 'sonar';
mysql> FLUSH PRIVILEGES;

2. 安装sonar与sonar-runner

将下载的sonarqube-5.2.zip包解压至_/etc/sonarqube_

将下载的sonar-runner-dist-2.4.zip包解压至_/etc/sonar-runner_

添加SONAR_HOMESONAR_RUNNER_HOME环境变量,并将SONAR_RUNNER_HOME加入PATH

export SONAR_HOME=/etc/sonarqube
export SONAR_RUNNER_HOME=/etc/sonar-runner
export PATH=$PATH:$SONAR_HOME/bin/macosx-universal-64:$SONAR_RUNNER_HOME/bin

修改sonar配置文件

编辑_<install_directory>/conf/sonar.properties_文件,配置数据库设置,默认已经提供了各类数据库的支持

这里使用mysql,因此取消mysql模块的注释

#vi sonar.properties
sonar.jdbc.username:sonar  
sonar.jdbc.password:sonar  
sonar.jdbc.url:jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true  
# Optional properties
sonar.jdbc.driverClassName:com.mysql.jdbc.Driver  

修改sonar-runner的配置文件

切换至sonar-runner的安装目录下,修改_sonar-runner.properties_

根据实际使用数据库情况取消相应注释

#Configure here general information about the environment, such as SonarQube DB details for example  
#No information about specific project should appear here  
#----- Default SonarQube server  
sonar.host.url=http://localhost:9000  
#----- PostgreSQL  
#sonar.jdbc.url=jdbc:postgresql://localhost/sonar  
#----- MySQL  
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8  
#----- Oracle  
#sonar.jdbc.url=jdbc:oracle:thin:@localhost/XE  
#----- Microsoft SQLServer
#sonar.jdbc.url=jdbc:jtds:sqlserver://localhost/sonar;SelectMethod=Cursor
#----- Global database settings
sonar.jdbc.username=sonar
sonar.jdbc.password=sonar
#----- Default source code encoding
sonar.sourceEncoding=UTF-8
#----- Security (when 'sonar.forceAuthentication' is set to 'true')
sonar.login=admin
sonar.password=admin

3.添加数据库驱动

除了Oracle数据库外,其它数据库驱动都默认已经提供了,且这些已添加的驱动是sonar唯一支持的,因此不需要修改

如果是Oracle数据库,需要复制JDBC驱动至_<install_directory>/extensions/jdbc-driver/oracle_目录

4.启动服务

(添加环境变量后可直接运行)

# sonar.sh start    启动服务
# sonar.sh stop    停止服务
# sonar.sh restart 重启服务

至此,sonar就安装好了

访问http:\localhost:9000即可

5.sonar中文补丁包安装

中文包安装

安装中文补丁包可以通过访问http:\localhost:9000,打开sonar后,进入更新中心安装

或者下载中文补丁包后,放到_SONARQUBE_HOME/extensions/plugins_目录,然后重启SonarQube服务

使用SonarQube Runner分析源码

预置条件

已安装SonarQube Runner且环境变量已配置,即sonar-runner命令可在任意目录下执行

1. 在项目源码的根目录下创建sonar-project.properties配置文件

以android项目为例:

sonar.projectKey=android-sonarqube-runner  
sonar.projectName=Simple Android project analyzed with the SonarQube Runner
sonar.projectVersion=1.0
sonar.sources=src
sonar.binaries=bin/classes
sonar.language=java
sonar.sourceEncoding=UTF-8
sonar.profile=Android Lint

注:要使用Android Lint

规则分析需要先访问http:\localhost:9000更新中心添加Android Lint插件,使其可以分析Android Lint规则

JavaScript

# Required metadata    
sonar.projectKey=org.sonarqube:javascript-simple-sq-scanner    
sonar.projectName=JavaScript :: Simple Project :: SonarQube Scanner    
sonar.projectVersion=1.0    
# Comma-separated paths to directories with sources (required)    
sonar.sources=src    
# Language    
sonar.language=js    
# Encoding of sources files    
sonar.sourceEncoding=UTF-8

注:需要添加JavaScript Lint插件 http://docs.sonarqube.org/display/PLUG/JavaScript+Plugin

2. 执行分析

切换到项目源码根目录,执行命令# sonar-runner

分析成功后访问http:\localhost:9000即可查看分析结果

不同参数的意思:

http://docs.codehaus.org/display/SONAR/Analysis+Parameters

不同项目的源码分析示例下载:

https://github.com/SonarSource/sonar-examples

与IDE关联

最后,当然了,得与IDE相关联,才能更方便地实时查看

以Eclipse为例,请见:http://docs.sonarqube.org/display/SONAR/SonarQube+in+Eclipse

结合intellij使用:https://github.com/sonar-intellij-plugin/sonar-intellij-plugin

附:

Karma

karma 测试框架的前世今生

https://github.com/karma-runner/karma

真正要理解内容还有点多,慢慢来

When should I use Karma?

  • You want to test code in real browsers.
  • You want to test code in multiple browsers (desktop, mobile, tablets, etc.).
  • You want to execute your tests locally during development.
  • You want to execute your tests on a continuous integration server.
  • You want to execute your tests on every save.
  • You love your terminal.
  • You don't want your (testing) life to suck.
  • You want to use Istanbul to automagically generate coverage reports.
  • You want to use RequireJS for your source files.

Redux

Getting Started with Redux

(Redux作者录制,视频详解了 Todos 这个示例的由来,入门看这个很有帮助「如果能听懂英文」)

awesome-redux =》这里面的文章都能过一遍也就差不多了

文档&库

Redux中文文档
redux
react-redux
redux-thunk
redux-logger

Provider 的作用:传递Store

connect()的作用:生成容器组件

import { connect } from 'react-redux';

const mapStateToProps = (state) => ({
  xxx: stateXXX
})
const mapDispatchToProps = (dispatch) => {
  return {
    xxx: (xxx) => {
      dispatch(actionCreatorXXX)
    }
  };
}
const ContainerComponent = connect(mapStateToProps, mapDispatchToProps)(Component);

中间件

http://camsong.github.io/redux-in-chinese/docs/advanced/Middleware.html

It provides a third-party extension point between dispatching an action, and the moment it reaches the reducer.

基本形式

store => next => action => {
  ...
  let result = next(action)
  ...
  return result
}

工具

Chrome 插件 Redux DevTools

Docker + Karma + Chrome Unit Test

在测试机(CentOS release 6.5)上跑单元测试的时候遇到这个问题

# npm test
...
START:
28 04 2016 05:44:47.156:INFO [karma]: Karma v0.13.22 server started at http://localhost:9876/
28 04 2016 05:44:47.169:INFO [launcher]: Starting browser Chrome
28 04 2016 05:44:47.171:ERROR [launcher]: No binary for Chrome browser on your platform.
  Please, set "CHROME_BIN" env variable.

Finished in 0 secs / 0 secs
...

即没有安装Chrome

查了一圈,主要是使用 xvfb 这个东西

最后使用了下面的 docker image:

https://hub.docker.com/r/markadams/chromium-xvfb-js/

主要起作用的脚本

https://github.com/mark-adams/docker-chromium-xvfb/blob/master/images%2Fbase%2Fxvfb-chromium

语言的战争

下面是《黑客与画家》中比较喜欢的一篇

编程语言解析:什么是编程语言?为什么它们现在很热门?

编程语言的一个重要特点:一个操作所需的代码越多,就越难避免bug,也越难发现它们。

语言的战争

应该使用哪一种语言?关于这个问题,现在有很多争论。部分原因是,如果你长期使用某种语言,你就会慢慢按照这种语言的思维模式进行思考。所以,后来当你遇到其它任何一种有重大差异的语言,即使那种语言本身并没有任何不对的地方,你也会觉得它极其难用。缺乏经验的程序员对于各种语言优缺点的判断经常被这种心态误导。

一些黑客只喜欢自己用的语言,反感其他所有的语言。另一些黑客则说所有的语言都一样。事实介于这两个极端之间。语言之间确实有差别,但是很难确定地说哪一种语言是最好的。这个领域依然还在快速发展。

对这点比较赞同是因为接触过的部分专门写前端的程序员,对于JS引入其它语言的特性有点小反感;
我到是希望各种语言的基础语法能够更加趋同一些,这样在切换使用语言的时候就不至于感到痛苦了;

面向对象编程

有两种程度的面向对象编程:某些语言允许你以这种风格编程,另一些语言则强迫你一定要这样编程。
你应该使用允许你面向对象编程的语言。至于你最后到底用不用则是另外一个问题了。

关于这点JS还是比较自由的;

Code Style & ESLint

ESLint 是什么

The pluggable linting utility for JavaScript and JSX. http://eslint.org

关键词:支持插件扩展、配置可继承、可自定义规则、支持React/JSX/ES6

可配置的错误等级 error level

  • 0 - turn the rule off 【禁用】
  • 1 - turn the rule on as a warning (doesn't affect exit code) 【警告】
  • 2 - turn the rule on as an error (exit code will be 1) 【错误】

因为配置可继承,因此比较方便的使用方式是采用比较流行的风格指南,然后根据团队需求配置

比较火的代码风格指南: airbnb

其中包含了react/jsx风格指南:https://github.com/airbnb/javascript/tree/master/react

对应的ESLint配置:https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb

安装说明:

Our default export contains all of our ESLint rules, including EcmaScript 6+ and React. It requires eslint and eslint-plugin-react.

  1. npm install --save-dev eslint-config-airbnb eslint-plugin-react eslint
  2. add "extends": "airbnb" to your .eslintrc
  • 不想包含react lint时,继承"airbnb-base";
  • 不需要es6支持时,继承"airbnb-base/legacy";

添加es7支持

�npm install --save-dev babel-eslint

示例配置文件:.eslintrc(继承airbnb)

{
  "extends": "airbnb",
  "parser": "babel-eslint",
  "globals": {
    "__DEV__": true
  },
  "ecmaFeatures": {
    "experimentalObjectRestSpread": true
  },
  "rules": {
    "react/jsx-quotes": 0,
    "jsx-quotes": [2, "prefer-double"]
  }
}

忽略不想检测的文件

添加_.eslintignore_文件:

node_modules/*
build/*

输出html报告

  1. npm install -g eslint-config-airbnb eslint-plugin-react eslint babel-eslint
  2. eslint -f html src/** > eslint-report.html

可用报告形式:http://eslint.org/docs/user-guide/formatters/

项目的error、�warning数统计

https://www.npmjs.com/package/eslint-stats

$ eslint --format node_modules/eslint-stats/byError.js src/**

可用报告:byError、byWarning、byErrorAndWarning、byErrorAndWarningStacked、byFolder

结合编辑器使用

Atom https://github.com/AtomLinter/linter-eslint

Sublime Text 参考: http://jonathancreamer.com/setup-eslint-with-es6-in-sublime-text/

其它集成:http://eslint.org/docs/user-guide/integrations

添加�git hook

https://github.com/dwyl/learn-pre-commit

使用pre-commit库

npm i -D pre-commit

在package.json中添加配置

{
  ...
  "scripts": {
    "eslint": "eslint -c ./MyApp/.eslintrc $(git diff --cached --name-only | grep -e \\MyApp/src/.*.js$)"
  },
  "pre-commit": [
    "eslint"
  ],
  ...
}

关于eslint的博文

http://csspod.com/getting-started-with-eslint/

【坑】Navigator.sendBeacon

会导致遇到这个坑的背景大概如下:

  1. 单页应用
  2. 用户不能主动刷新

HEHE,所以排查了好久

https://www.w3.org/TR/beacon/

If the User Agent limits the amount of data that can be queued to be sent using this API and the size of data causes that limit to be exceeded, this method returns false.

好抽象,没有说具体怎么限制的,限制多少 - -

https://nikcodes.com/2014/12/16/squeezing-the-most-into-the-new-w3c-beacon-api/

The specification allows the browser to refuse to send the beacon data (thus returning false) if it deems you’re trying to send too much. At this point, Chrome is the only browser that limits the amount of data that can be sent. Its limit is set at right around 64 KB (65,536 bytes exactly).

http://stackoverflow.com/questions/28989640/navigator-sendbeacon-data-size-limits

var url = 'http://jsfiddle.net?sendbeacon';
var n = 65536; // sendBeacon limit for Chrome v40 on Windows (2^16)

// this method courtesy of http://stackoverflow.com/questions/14343844/create-a-string-of-variable-length-filled-with-a-repeated-character
var data = new Array(n+1).join('X'); // generate string of length n

if(!navigator.sendBeacon(url, data)) {
   alert('data limit reached');
}

http://iherebydecree.com/archive/id/964

Finally, some browsers have a data limit of how much data, per page view, can be sent by the sendBeacon API. In my testing I have noticed that this only includes actual POST body data, so you can still send quite a lot on the query string if you want.

File Structure For React/Redux Applications

关于文件结构组织,不管是后端开发还是前端开发,大概都有两种倾向,一种是根据功能分[1],一种是根据业务实体分[2]

从去年9月份[2015]至今年2月份[2016],项目先从[1�]迁移至[2]又迁移回[1],也是瞒折腾的 😓

个人认为使用redux时第[1]种是比较合适的;必竟redux是单一store,如果采用实体分会导致没有用单一store的思路来思考,将action局限有只能更新部分state【这个问题和同事争论了很多次】

在使用第[2]种时经常遇到的问题就是不知道一块内容到底应该放到哪个位置,可能既属于这块业务又属于另一块业务,互有交叉,这种时候就比较纠结;采用第[1]种方式时就少了些纠结;

不过从目前的经验来看,不管用什么方法都不影响文件查找,善用编辑器查找就行;

最影响文件查找及debug的是之前一堆的_index.js_文件;这个问题有两种处理方式:

  • 一种是不使用index.js,在目录下添加package.json文件,设置main;
  • 另一种是仍保留index.js,只不过只是用来export出真正的module;

[目前使用的方式是大部分直接创建组件文件,部分index.js,事实上不利于未来样式的组件化,目前样式部分还是采用传统的方式把整个项目所有的样式都放在一个目录中,偶尔会出现样式的冲突]

�src
├── actions
├── a�dapts
├── assets
├── components
├── constants
├── containers
├── core
├── helpers
├── reducers
├── resource
├── server.js
├── store
├── styles  [X] => 个人倾向styles组件化
└── templates

redux-form

�题外话

表单处理可以做得很简单,也可以做得很复杂;

简单的情况就是前端完全不做验证,把验证直接交给后台;其实目前都是通过ajax提交表单数据,并不存在页面刷新跳转,这样做除了可能会多发请求,其它并没有什么问题;

还是老观念,后台验证是必须的,前台验证是优化;必竟绕过前端验证去提交表单是比较容易的;

事实上,如果是正常的用户,通常不会有太多输入错误;而在前端添加验证代码会引入两个问题:1)多出许多验证逻辑代码,增加了复杂度;2)后端验证不全面,可能出现部分非前端提交的非法数据;

当然,如果能优化,又不会在业务中穿插许多验证逻辑代码,何乐尔不为呢

目前的做法

  • 因为验证逻辑太乱,并没有完全正确可参考的需求文档,目前大部分是直接让后端来验证,出现问题只需要改后台;
  • 将部分验证放在Action中做,在提交请求之前对表单数据进行验证,如果出现验证错误直接发送保存失败的Action(与请求返回错误结构一致),可以减少发送请求;这样的优点是业务组件中完全不需要参杂验证逻辑,组件只需关心简单的事情(输入&提交&显示错误消息);缺点就是可能不符合部分需求场景(即时验证?不过也有W�orkAround);
function �save(data) {
  // 在提交到后台之前进行表单验证
  if (validateFail) {
    return {
      type: ActionType.SAVE_FAIL,
      message,
    };
  }
  return dispatch => {
    CallApi(data).then(res => {
      if (res.status === 0) {
        dispatch({
          type: ActionType.SAVE_SUCCESS,
        });
      } else {
        dispatch({
          type: ActionType.SAVE_FAIL,
          message: res.message,
        });
      }
    });
  };
}

一直计划学习一下redux-form是怎么干这件事情的

https://github.com/erikras/redux-form

【坑】Clone Date

在1月31日的时候无意中发现系统的一个BUG

原因是旧项目代码写了一段非常SB的代码

�function �cloneDate(date) {
  var _date = new Date();
  _date.setFullYear(date.getFullYear());
  _date.setMonth(date.getMonth());
  _date.setDate(date.getDate();
  return _date;
}

在平常这段代码没什么问题,当月末的时候问题就来了,因为下个月的天数比这个月短,因此当把月份设置成2月,而�date还是31的时候,就会变成3月2日;

var date = new Date('2016-02-01');
var _date = new Date('2016-01-31');  // 当前日期
_date.setFullYear(date.getFullYear());
console.log(_date.toString()); // "Sun Jan 31 2016 08:00:00 GMT+0800 (CST)"
_date.setMonth(date.getMonth());
console.log(_date.toString()); // "Wed Mar 02 2016 08:00:00 GMT+0800 (CST)"
_date.setDate(date.getDate());
console.log(_date.toString()); // "Tue Mar 01 2016 08:00:00 GMT+0800 (CST)"

说SB的原因是压根不知道这个函数存在的意义~

升级控福利 npm-check

https://github.com/dylang/npm-check

Check for outdated, incorrect, and unused dependencies.

项目开发一段时间后总是有一堆已经过期或有好几个版本更新的包,之前通常是一个个确认的,早该想到怎么可能没有这种工具呢,只要一个命令就能直观的知道哪些包没用了,哪些包可以更新,赞!

具体用法README里面已经写得很详细啦,甚至PR里面还有中文翻译

React + Webpack + Karma + Mocha + Babel 单元测试配置

安装

  1. 安装 karma
  2. 安装 karma cli,用于在终端使用karma
    npm install karma-cli -g
  3. 安装 chai (或其它断言库),chai-enzyme
  4. 安装 babel-loader,用于支持JSX和ES6
  5. 安装 karma-coverage
  6. 安装 istanbul-instrumenter-loader
  7. 安装 enzyme 用于测试React组件

通常需要安装四种类型的插件

插件类型 使用的插件 备注
frameworks karma-mocha 用于结合使用mocha和Karma,依赖 mocha 测试框架
reporters karma-mocha-reporter
launchers karma-chrome-launcher、karma-phantomjs-launcher
preprocessors karma-webpackkarma-sourcemap-loader 用于结合使用karma和webpack(用于预处理),依赖 webpack
npm install karma mocha chai chai-enzyme karma-mocha karma-mocha-reporter karma-chrome-launcher  webpack karma-webpack karma-sourcemap-loader karma-coverage babel-loader enzyme --save-dev

phantomjs-prebuilt?

配置

两个文件:

  • karma.conf.js
  • tests.webpack.js

配置文件参考 react-karma-babel-webpack-code-coverage

How to implement testing + code coverage on React with Karma, Babel, and Webpack

Configuration File 文档

《深入浅出Node.js》

第一遍先了解了大概,需要再读一遍来理解细节

  • 第1章 Node简介
  • 第2章 模块机制
  • 第3章 异步I/O
  • 第4章 异步编程
  • 第5章 内存控制
  • 第6章 理解B�uffer
  • 第7章 网络编程
  • 第8章 构建Web应用
  • 第9章 玩转进程

服务模型的变迁:同步-›复制进程-›多线程-›事件驱动

需要解决两个问题:

  • 如何充分利用多核CPU服务器?
  • 如何保证进程的健壮性和稳定性?

保证多个处理单元工作量公平的策略叫负载均衡

总结

每个进程只做一件事,并做好一件事,将复杂分解为简单,将简单组合成强大

在Node进程管理之外,还需要用监听进程数量或监听日志的方式确保整个系统的稳定性

  • 第10章 测试
  • 第11章 产品化

《Don't Make Me Think》

之前看过第二版,有点久了所以印象不是很深刻,花了一个周末看了一遍第三版,主要的变动是引入了移动端部分的,接下去花点时间思考一下

指导原则

第一章 别让我思考 —— Krug 可用性第一定律

其实通篇都在讲这个问题

关于链接和按钮,印象比较深是目前设计讲究简洁,因此许多可点的地方并不是很明显,必须把鼠标放上去,变成手形才知道 “哦,原来这里可以点”,那在平板上看的时候用户知不知道可点了?

作为开发人员如果不是自己开发的模块,可能都要试一试才知道是可点的

如果你不能做到让一个页面不言而喻,那么至少应该让它自我解释。

确定你没有做错的几件事

第8章 农场主和牧牛人应该是朋友 —— 为什么大部分关于可用性的争论是在浪费时间,如何避免这种情况

如果只有他们自己在进行设计,Web开发团队在可用性问题的决策方面并不是那么成功。很多团队一直在花大量宝贵的时间一次次地重复着同样的问题。

目前项目的需求由产品来提出,经常开发人员会对需求提出质疑,场景有点类似这章里面形容的

比较蛋疼的是作为开发人员没有接触过客户,不了解客户是怎么想的

职位情绪:每种职位的人的喜好都不一样,CEO、设计师、开发人员、业务拓展人员,这通常也是他们成为某种角色的原因

只有一种方式能决定谁是正确的:[可用性]测试

React Starter Kit

React Starter Kit https://github.com/kriasoft/react-starter-kit

Runtime Components

Development Tools

Docs

React Style Guide

要点:

文件结构 Folder Structure

  • Place each component in a separate folder
  • Avoid having shared resources between components (css, images etc.)
  • Keep all components' folders in the same parent folder (avoid nesting) =》这条有点不理解
/src/components/Navigation/icon.svg
/src/components/Navigation/Navigation.css
/src/components/Navigation/Navigation.js
/src/components/Navigation/Navigation.test.js
/src/components/Navigation/Navigation.ru-RU.css
/src/components/Navigation/package.json

CSS类命名方式 CSS Class Names

组件名 Navigation
组件名--状态 Navigation--modifier
组件名-元素名 Navigation-item
组件名-元素名--状态 Navigation-item--modifier

React Components

  • Use Babel transpiler for your source code
  • Use ES6 classes for creating new React components
  • Use higher-order components to extend the functionality of existing components

使用Yeoman安装:

npm install -g yo
npm install -g generator-react-fullstack
yo react-fullstack

疑问:

为什么要用两种Lint:eslint和jscs?有什么好处?

《精通Web Analytics 2.0》

第1章 Web Analytics 2.0的新世界

数据困境:缺乏数据,不能做出完整的决策;而有了大量的数据,仍然只能得到极少的深入分析见解。

第1章就提到了我目前遇到的困境,收集到了一堆的点击流数据,却只有极少的分析

因为收集的所有数据都只描述了“是什么”(What),而没有说明“为什么”(Why)

知道“发生什么”很重要,然而更重要的是知道“为什么”

Web Analytics 2.0定义为:

分析自身以及竞争对手的定量与定性的数据,为用户以及潜在用户不断改善网站体验,并将其转化为你所期望的结果(线上与线下的目标)。

image

Web Analytics 2.0 多级策略与工具,强调**“多样性”**战略

策略 工具 备注
点击流数据 是什么 Google Analytics
多目标产出分析 有多少
试验与测试 为什么 Google Website Optimizer 已经不存在了
客户的反馈 为什么
竞争情报 其他方面 Google Ad Planner => Google Display Planner
分析见解

一个网站要提供的产出有3个方面:

  • 增加收入
  • 降低成本
  • 提高用户满意度与忠诚度

如果想获得管理者的重视,你必须关注多目标产出分析。

第2章 选择网站分析系统的最佳战略

第一步:选择网站分析系统前需要回答的3个关键问题

  • 问题1:需要报表,还是需要分析
  • 问题2:我们的优势在IT方面、业务方面,还是两方面都有优势
  • 问题3:我只需要解决点击流数据,还是需要整个Web Analytics 2.0

第二步:系统选定之前问供应商的10个问题

  • 问题1:你们的工具/解决文案与 Yahoo ! 和 Google 的免费分析工具之间有什么区别
  • 问题2:你们是否是 100% 的 ASP?是否提供本地安装版本的系统?你们计划提供本地安装版本吗?
  • 问题3:你们使用什么样的数据捕获机制
  • 问题4:你们能计算使用你们工具的总成本吗
  • 问题5:你们能提供什么样的支持服务?哪些支持服务是免费的,哪些是付费的?免费服务是否是全天候的
  • 问题6:你们的系统当中哪些功能允许对数据进行族群细分
  • 问题7:有哪些方式可以将你们系统的数据导入到公司内部系统
  • 问题8:你们的系统提供了哪些功能可以将其他来源的数据集成到系统
  • 问题9:你们是否可以列举2~3个目前正在规划的新的系统功能,保证你们的系统未来3年领先于竞争对手;
  • 问题10:最近两家客户与你们解除合同的原因是什么?他们中谁还在使用你们的系统?我们可以给这些客户打个电话吗

第三步:识别网站分析系统(如何有效地试用分析系统)

提到了一点,让实习生(或VP)试用,其实每次有新的实习生的时候,应该先让试用一下系统,提出一些建议,不了解业务的人经常能提出有意义的建议

校验数据(数据不可能完全吻合,但很有意思!):比较试运行中几个工具之间的数据,并让供应商来解释各工具之间数据存在差异的原因。

哈哈,这个比较重要,在项目中同时使用两套工具,然后发现了公司内部统计工具的BUG。:smile:

如果没有比较,可能会一直以为数据是正确的。

第四步:确定合作前的谈判——详细检查供应商提供的合同服务条款

第3章 点击流分析的精彩世界:指标

网站分析指标不断演变,从原先的 hit 到 PV 到访问量。而现在,则是产出。

8 个关键网站指标

访问 (Visits) 与访客 (Visitors)

  1. 访问
  2. 独立访客
    • 每日独立访客、每周独立访客、每月独立访客都会因为选择的时间段不同而不准确
    • 绝对唯一访客应该接近真实用户数

网页停留时间与网站停留时间

跳出率

退出率

退出率是指不管从哪个页面进入网站,而在这个页面退出的访问比率;
跳出率是指仅从这个页面进入网站,没有做任何事,就在这个页面退出网站的访问比率。

转化率

参与度

优秀指标的4个特性

  1. 简单
  2. 相关
  3. 及时
  4. 即时有用性

Avinash 关于网站成功的3个教训

  1. 不要过分追求完美
  2. 要做到少而精
  3. 重视网站指标的生命周期

关键指标的战略性对策

第一,确定最关键因素,主要是用来通过关键指标提示问题所在。第二个对策,合理利用自定义报表,对于自定义报表的讨论与争论能让人对网站的表现更为了解。最后一条,要从宏观方面把握整个网站的表现,而不要过于纠缠细节的方面。

从宏观上理解网站

问题1:有多少访客来我们的网站?
问题2:访客是从哪儿来的?
问题3:你希望访客在网站上做什么?
问题4:访客实际上在网站上做了些什么?

第4章 点击流分析的精彩世界:实践操作

项目杂谈

参与了大半年的项目,经过了两次大的重构,终于有点走上轨道了,总结了半年下来提出的一些被忽视到需要执行的或还在沉睡中的意见:

  • 在刚参与项目的时候,首先就提出了【编码规范的问题】,这个问题我以为不是问题,理所当然应该执行的,还是图样图森破,不是每个人都在意代码长啥样的(这点一直钦佩老外们的认真,有的开源项目不止使用一种Lint);本来这个问题在第一期代码重构的时候就可以得到解决,但是由于没有话语权,后面专门提了需求来搞这个事;
  • 二手项目中的API是在Store中调用的,【关于在Action中调用API的问题】,比较早就提出的,不过没有说服其他人,最后第一期重构后的代码还是有在Component中调用的,有在Store中调用的;最近第二期重构引入Redux才统一在Action中调用;
  • 考虑到项目有采用Redux进行改写的计划,提出了可以直接采用Re�ducer编写Flux Store的意见,有两块新需求都直接采用了Reducer的方式来写,减少了后面的工作量;
  • 【关于React的升级问题】,在刚参与项目时就提出了,当时github上的React项目基本上都已经采用React 0.14了,参与的项目还采用0.12;升级基于两点考虑:
    • 1)对于这种更新比较快,偶尔有接口变更的框架,如果几个版本不更新,最后更新的代价就会越来越大;0.14还保留了许多即将废弃的接口,到了0.15会将这些接口废弃掉,到时候代码更多,改的代码更大;
    • 2)大部分组件已经采用了新版的React来编写,不升级意味着放弃对这些组件的更新与使用;
  • 【关于构建问题】,在接手的时候主流就是直接使用webpack进行构建,不过没有话语权,提过几次,自己搞了个只采用webpack打包的分支,后面由另外的成员把这件事干了,但是目前还未应用到项目中;
  • 【关于Redux Action的使用上】,有一些观念上的不同,这个问题讨论了好几次,思路总是不一样,根本原因还是没有理解Redux的**,这点我和Redux作者的思路还是比较一致的;
  • 【关于注释】~这个问题其实不用讨论的,虽然我也漏了很多注释,不过如果有需求还是会补上的;
  • 【关于样式组件化】,目前还是没有提上日程,似乎还不能接受;
  • 【关于服务器推送】,这个老早就提了,呵呵,因为是多端的应用,经常会出现数据不一致的问题,又没有提供刷新的功能,不知道怎么想的;

拥抱变化,有预见性,能提前做准备,感觉这几点我做得还是比较好的;不好的地方还是表达力与影响力,不过影响力又有点微妙,当你职级较高的时候自然别人会听到你的声音,而你职级较低的时候,声音好像自动被过滤了;

nginx

使用brew安装

$ brew install nginx
==> Downloading https://homebrew.bintray.com/bottles/nginx-1.8.1.el_capitan.bo
...
==> Pouring nginx-1.8.1.el_capitan.bottle.tar.gz
Error: The `brew link` step did not complete successfully
The formula built, but is not symlinked into /usr/local
Could not symlink share/man/man8/nginx.8
/usr/local/share/man/man8 is not writable.

You can try again using:
  brew link nginx
==> Caveats
Docroot is: /usr/local/var/www

The default port has been set in /usr/local/etc/nginx/nginx.conf to 8080 so that
nginx can run without sudo.

nginx will load all files in /usr/local/etc/nginx/servers/.

To have launchd start nginx at login:
  ln -sfv /usr/local/opt/nginx/*.plist ~/Library/LaunchAgents
Then to load nginx now:
  launchctl load ~/Library/LaunchAgents/homebrew.mxcl.nginx.plist
Or, if you don't want/need launchctl, you can just run:
  nginx
==> Summary
🍺  /usr/local/Cellar/nginx/1.8.1: 7 files, 946.2K

根据Error信息,执行:

$ sudo chown -R `whoami` /usr/local
$ brew link nginx
Linking /usr/local/Cellar/nginx/1.8.1... 2 symlinks created

其它

brew install gcc

Redux 测试

A�ctions

对于直接返回Action对象的,没有其它预处理的Action Creator实在没什么好测的

关键测包含异步调用的

R�educers

作为纯函数,测试起来也比较简单

Components

如果用的R�eact其实就是React组件测试

Redux文档-编写测试

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.