- 本项目所有的内容仅仅用于个人学习交流使用,未经授权,禁止任何形式使用
创建目录结构(项目当前正在使用
的目录结构)
Demo
|
|--->src(存放源码)
| |
| |--->widgets(存放基础组建和布局组件)
| | |--->basic(存放基础组建)
| | | |
| | | |--->input(input基础组件)
| | |
| | |
| | |--->view(布局组件)
| |
| |
| |--->pages(存放web模块)
| | |
| | |--->first(模块1或页面1)
| | | |
| | | |--->actions(存放redux的actions)
| | | |
| | | |--->reducers(存放redux的reducers)
| | | |
| | | |--->container(存放容器组件)
| | | |
| | | |--->components(存放展示组件,数据来源只有props)
| | | |
| | | |--->types(定义常量等)
| | | |
| | | |--->index.tsx(导出first容器组件)
| | | |--->index.less(css样式)
| | |
| | |
| | |--->second(模块2或页面2)
| | |(...)
| |
| |
| |--->res(存放图片等资源)
| |
| |
| |
| |--->utils(一些协助项目的通用工具,比如http,getToken等)
|
|
|
|--->tools(基本上是协助开发的工具,比如数据类型转换等,可以用node跑)
|
|
|--->dist(编译后部署代码)
|--->node_modules(安装的依赖包)
|--->(...其他一些配置文件)
进一步精细化的目录(备选目录
)
Demo
|
|
|------>src/app(存放源代码)
| |
| |
| |------>index.js(启动app前的配置项)
| |
| |
| |------>store.js
| |
| |
| |------>home.html
| |
| |
| |------>rootReducer.js
| |
| |
| |------>common(存放通用资源,至少是两个模块都会引用的资源才会放到这里,否者放在模块自己的目录下�)
| | |
| | |
| | |------>globalActions()
| | |
| | |
| | |------>globalReducers()
| | |
| | |
| | |------>globalUtils()
| | |
| | |
| | |------>globalCss()
| | |
| | |
| | |------>res(存放资源)
| | | |
| | | |
| | | |------>images
| | | |
| | | |
| | | |------>fonts
| | |
| | |
| | |------>libs(存放非node_module�方式引入的包)
| |
| |
| |------>modules(存放各个模块)
| | |
| | |
| | |------>first(第一个模块)
| | | |
| | | |
| | | |------>index.js(动态加载渲染路由,如果一次性加载路由,可取消该项)
| | | |
| | | |
| | | |------>main.js(渲染html)
| | | |
| | | |
| | | |------>actions.js
| | | |
| | | |
| | | |------>reducers.js
| | | |
| | | |
| | | |------>components(存放页面级的模块)
| | | | |
| | | | |
| | | | |------>header
| | | | | |
| | | | | |
| | | | | |------>index.js
| | | | | |
| | | | | |------->index.css
| | | | |
| | | | |
| | | | |------>content(同header)
| | | | |
| | | | |
| | | | |------>footer(同header)
| | | |
| | |
| | |
| | |------>second
| | |
| | |
| | |------>third
|
|
|
|------>configs(各种根目录下的配置文件)
|
|------>tools
|
|
|------>static/dist(构建目录)
|
|
|------>node_modules
结论:
通用的东西全部到common目录下查找。
modules目录下�是相互独立的模块。
非业务基础组件拉出去,作为单独的项目。
通用业务组件拉出去,作为单独的项目。
特有组件则单独开发,并存放在compoennets目录下。
非业务组件------>业务组件------>页面------>应用
- 类型变量:使用<>定义或传值
- 泛型,使用泛型时可以显式传递类型;也可以不传递,通过类型推论推导出类型
1、泛型函数
function identify<T>(args: T[]): Array<T> {
return args;
}
2、泛型函数的类型
let myIdentify: <U>(args: U[]) => Array<U> = identify;
还可以,
let myIdentify: {<U>(args: U[]) => Array<U>} = identify;
3、泛型接口
interface GenericIndentityFn {
<T>(arg: T): T;
}
function identify<T>(arg: T): T {
return arg;
}
let myIdentify: GenericIndentityFn = identify;
4、泛型类
- ts 中的对象类型
1、固定类型:该属性一定存在
interface Person {
name: string;
age: number;
}
2、可选属性:该属性可以不存在
interface Person {
name: string;
age: number;
gender?: string;
}
3、任意属性:
interface Person {
name: string;
age: number;
gender?: string;
[key: string]: string;
}
- 类型推论
- type:类型别名关键字
- keyof(索引类型查询操作符):索引类型(Index types)查询
keyof T的结果:T上已知的公共属性名的联合
interface Person {
name: string;
age: number;
}
let personProps: keyof Person; // "name" | "age"
- T[k]:索引访问操作符
- 映射类型:从旧类型中创建新类型的一种方式
-
promise 参考资料
-
fetch
-
plain object:简单对象,既{}或 new Object()
-
js supplant
-
Ajax 技术:异步 javascript xml
1、�从服务器获取数据且不用卸载页面(有益用户体验) 2、ajax通信�与数据格式无关,可以使用xml、json等数据格式(有益网络传输) 3、js中的实现是:XMLHttpRequest 4、FormData类型,表单数据 5、CORS跨域问题: Origin和Access-Controll-Allow-Origin open函数传入绝对地址,可以解决跨域问题 Preflighted Request技术 图像Ping(无法处理响应,只能单向通信) JSONP
-
form 表单
enctype: application/x-www-form-urlencoded 编码所有�字符(默认) multipart/form-data 不对字符编码,二进制 text/plain 空格转换为加号,但不对特殊字符编码
-
js 安全类型检测
前置条件: Object.prototype.toString没有修改; 此方法只对原生对象有效,非原生对象全是Object 方案: Object.prototype.toString.apply(Object); 返回结果类似: "[object Object]","[object Function]","[object JSON]"……
-
作用域安全的构造函数
构造函数 Person,当使用 new 时,this 指针能够正确的指向新创建的对象实例; 但是,当忘记使用 new 时,this 指针就会指向 window 对象,这可能会引起非预期结果。 比如下面的 demo,name 就会覆盖 window 对象的属性 name,引起异常。
// 非安全的demo function Person(name, age, job){ this.name = name; this.age = age; this.job = job; } let p1 = new Person("monkey", 12, "student"); let p2 = Person("wang", 13, "doctor"); alert(windw.name);//wang alert(windw.age);//13 alert(windw.job);//doctor // 作用域安全的demo function Person(name, age, job){ if (this instanceof Person){ this.name = name; this.age = age; this.job = job; } else { return new Person(name, age, job); } }
-
惰性载入函数
-
函数绑定
-
函数柯理化
作用:
用于创建已经设置好了 一个或多个参数的函数。
如题:
fn() ===> 0 fn(2)() ===> 2 fn(2)(7)() ===> 9 fn(2)(5)(7)() ===> 14
实现函数 fn.
思考:
方案一:全局变量控制 let sum = 0; function fn() { if (arguments.length) { sum += arguments[0]; return fn; } return sum; } console.log(fn()); sum = 0; console.log(fn(2)()); sum = 0; console.log(fn(2)(7)()); sum = 0; console.log(fn(2)(7)(5)()); 方案2:将全局变量收敛到局部作用域,比如函数作用域(似乎js也就只有函数作用域了),既柯里化 function curry(fn) { let args = arguments; let outerArgs = Array.prototype.slice.call(args, 1); return function() { let innerArgs = Array.prototype.slice.apply(arguments); let finnalArgs = outerArgs.concat(innerArgs); if (arguments.length) { return arguments.callee; } <!-- 还原outerArgs,类似方案1中的sum --> outerArgs = Array.prototype.slice.call(args, 1); return fn.apply(null, finallyArgs); } } function add() { let length = arguments.length; let sum = 0; while(length > 0) { sum += arguments[--length]; } return sum; } let curriedAdd = curry(add); console.log(curriedAdd()); console.log(curriedAdd(2)()); console.log(curriedAdd(2)(7)()); console.log(curriedAdd(2)(7)(5)());
-
es 新语法特性
1、...:扩展运算符(spread operator) ;剩余操作符(rest operator),解构操作的一种
2、template literals(模板文字):模板文字就是可以嵌入表达式的字符串字符,使用的符号是反勾号(back tick)。
- es1:tagged template literals(标签模板文字)
// tag是一个可以返回任何值(包括函数)的函数,tag函数会自动识别模板字符中的表达式作为�tag函数的其它参数,同时表达式在strings的位置由“”表示,即`${1}${2}a`,此时strings为:["","","a"]
tag`string text ${expression} string text`;
/**
* @desc 返回一个字符串
* @strings {array[strings]} 处理字符串数组
* @personExp {any} 可选,其它数据
* @ageExp {any} 可选,其它数据
*/
const person = "Mike";
const age = 28;
function� myTag(strings, personExp, ageExp){
let str0 = strings[0];
let str1 = strings[1];
let ageStr;
if (ageExp > 99){
ageStr = 'centenarian';
}
else{
ageStr = 'youngster';
}
return str0 + personExp + str1 + ageStr;
}
//此处将${person},${age}自动识别成personExp和ageExp参数,that,is a自动识别存储在strings参数中
var output = myTag`that ${person} is a ${age}`;
console.log(output);//that Mike is a youngster
也可以返回函数:
function template(strings, ...keys){
return (
function(...values){
var dict = values[values.length - 1] || {};
var result = [strings[0]];
keys.forEach(function(key, i){
var value = Number.isInteger(key) ? values[key] : dict[key];
result.push(value, strings[i + 1]);
});
return result.join('');//自动忽略undefined的值
});
}
var t1Closure = template`${0}${1}${0}`;
t1Closure('Y', 'A');//"YAY!"
var t2Closure = template`${0} ${'foo'}!`;
t2Closure('Hello', {foo: 'World'});//"Hello World!"
- Raw strings(原始字符串) strings 参数(即 tag 的第一个参数)默认含有一个 raw 数组,可以访问原始字符串,� 即未处理转义字符的字符串。
function tag(strings, ...values){
console.log(strings.raw[0]);
}
tag`${string text line 1 \n string text line 2}`;
// logs string text line 1 \n string text line 2
这和 String.raw()的功能相同:
var str = String.raw`Hi\n${2+3}!`;
//"Hi\n5"
str.splite("").join(",");
//"H,i,\,n,5,!"
- tagged template literals and escap sequences es6 中的标签模板文字符合以下转移规则: 1、以\u 开始的 Unicode 转义序列,例如:\u00A9 2、以\u 开始的 Unicode point escape,例如:\u{2F804} 3、十六进制,例如:\xA9 4、八进制转义,例如:\251
给定数据A有N个元素(索引从0开始),数组A的一个极点Q满足一下条件:
0<= Q <= N;
如果0<=P<=Q,则A[P]<=A[Q];
如果Q<R<N,则A[Q]<=A[R];
例如:数组A�由以下10个元素组成:
A[0] = 4;A[1] = 2;A[2] = 2;A[3] = 3;A[4] = 1;
A[5] = 4;A[6] = 7;A[7] = 8;A[8] = 6;A[9] = 9;
如前所说,该函数应该返回5或者9.
假设有如下条件:
1、N取值范围是[0,100000];
2、数组的每一个元素都是整数,切且取值范围是[-2147483648,2147483647]
复杂度:
1、期望最差时间复杂度是O(N)
2、期望最差空间复杂度是O(N),超出输入存储(不计算输入参数所需的存储空间)
输入数组的元素是可以修改的(是不是意味着可以重用输入数组,节省�存储空间)
- 关于 setState
Demo在fillorder页面
react对state的更新有两个分支,一个分支合并setState,只有合并过后才会走完生命周期并更新state;一个会一直走完生命周期并更新state。
在生命周期或合成事件中,setState会被合并;在其他地方的setState会直接走完生命周期
-
Single source of truth
-
State is read-only
-
Changes are made with pure functions
-
top level api
-
createStore(reducer, [preloadedState], [enhancer])
-
combineReducers(reducers)
-
applyMiddleWare(...middlewares)
-
bindActionCreators(actionCreators, dispatch)
-
compose(...functions)
-
Store api
-
getState()
-
dispatch(action)
-
subscribe(listener)
-
replaceReducer(nextReducer)
- combineReducers 初始化发送的 action
combinereducers做的是对reducer的校验,并没有使用dispatch发送action,数据没有更新到state上
1、以state=undefined,action={type: INIT}执行每一个reducer,并检测每一个reducer的返回值是否为undefined
如果是undefined,抛异常;否者,进行第2步。(结论1:每一个reducer对INIT的action返回值不能是undefined)
2、以state=undefined,action={type: PROBE_UNKNOWN_ACTION}执行每一个reducer,并检测每一个reducer的返回值
是否为undefined,如果是undefined,抛异常;(结论2:reducer对PROBE_UNKNOWN_ACTION的action返回值不能是undefined)
- createStore 初始化发送的 action
创建store时,会发送一个dispatch({type: Actions.INIT}),初始化state树
- replaceReducer 初始化发送的 action
执行replaceReducer时,会发送一个dispatch({type: Actions.REPLACE}),功能类似Actions.INIT
- 结论
1、每一个reducer中的state给一个默认值{},防止combineReducers校验失败
function home(state = {}, action) {
switch(action.type) {
default:
return state;
}
}
2、定义初始状态,页面数据结构清晰,便于阅读。且INIT发出后,会初始化到state树上作为各个页面初始状态,有利于减少页面各种null和undefined的出现;减少js对象因为访问层级过深造成的异常
const initialState = {
home: {
},
about: {
}
}
createStore(reducers, initialState, middlwares);
# 代码的可读性要求
1、代码能够清晰的表达意图
// bad code,2 代表什么 � 意思呢? Coffe.makeCoffe(2);
// good code enum COFFE_CUP { small, middle, large }; Coffe.makeCoffe(COFF_CUP.large);//语义化的参数,表明是大杯的 coffe
2、用代码沟通:注释应该用来说明代码的功能和约束条件;代码的逻辑则由代码本身来说明。源代码可以被读懂,不是因为注释,而是它本身的优雅清晰。
/**
- @desc 求和
- @num1 {number} 输入参数 1
- @num2 {number} 输入参数 2
- @result {number} 返回和 */ function add(num1, num2){ return num1 + num2; }
`结论:`
用语义化的命名,准备表达意图;
用注释描述代码的意图和约束;
用代码自身的优雅清晰描述自身的逻辑。
# 关于配置css模块化的问题
但模块化css文件时,由于typescript的类型提示编译时会报错,目前暂时去掉模块化(联系下自己对css样式的组织吧),文件中使用import css = reuiqre()语法,ts编译会报错,但是能正常运行
# css的命名规则
[参考资料](http://www.cnblogs.com/xiaohuochai/p/6261697.html)
* BEM(block element modifier):模块和子元素之间用两个下划线标识;元素和修饰符之间用两个中划线标识;命名过长如何处理呢?
```
.blockname__innerelement--active{
display: block;
}
```
* NEC(网易的命名方法):使用后代迭代器方法,首先将元素分5类--->布局(.g-),模块(.m-),元件(unit,.u-),功能(.f-),皮肤(.s-),状态(.z-)
```
.m-list{
margin:0;
padding:0;
}
.m-list .item{
margin: 1px;
}
.m-list .cnt{
margin: 1px;
}
```
* JD(京东):采用标识层级嵌套关系的长命名。当子孙模块超过4级,考虑祖先模块内具有识别辨别性的独立缩写作为新的子孙模块
```
<div class="modulenamne">
<div class="modulename_cover"></div>
<div class="modulename_info">
<div class="modulename_info_user">
<div class="modulename_info_user_img">
<img src="" alt>
<!--miui===modulename_info_user_img-->
<div class="miui_tit"></div>
<div class="miui_txt"></div>
</div>
</div>
</div>
</div>
```
* 常见的命名:
```
about ---关于
account ---账户
arrow ---箭头图标
article ---文章
aside ---边栏
audio ---音频
avatar ---头像
bg,background ---背景
bar ---栏(工具类)
branding ---品牌化
crumb,breadcrumbs---面包屑
btn,button ---按钮
caption ---标题,说明
category ---分类
chart ---图表
clearfix ---清楚浮动
close ---关闭
col,column ---列
comment ---评论
community ---社区
container ---容器
content ---内容
copyright ---版权
current ---当前态(选中态)
default ---默认(缺醒)
description ---描述
details ---详情(细节)
disabled ---不可用
entry ---文章,博文
error ---错误
even ---偶数
fail ---失败
feature ---专题
fewer ---收起
field ---输入区域
figure ---图
filter ---筛选
first ---第一个
footer ---页脚
forum ---论坛
gallery ---画廊
group ---模块
header ---页头
help
```
* 自用的命名规范:
基于BEM命名:Block是指component(module,个人倾向使用component这个词),element是指组成component(module)的element(不用嵌套),modifier是指component的外观或行为,同样的块不同的样式,显示不同的外观(b_e-m:input_text-error,input_text-warning,input_text-success)。
<strong><font style="color:green">与BEM区别的一点,允许element的嵌套,以显示层级关系</font></strong>
使用<font style="color:red">单下划线</font>标识层级关系,当超过4层(出现超过4个下划线),使用类jd的缩写
使用<font style="color:red">单中划线</font>标识状态关系,当超过4层(出现超过4个下划线),使用jd的缩写
```
<div class="monkey">
<div class="monkey_header">
<div class="monkey_header_nav monkey_header_nav-hover">
<div class="monkey_header_nav_item">
<div class="mhni_text mhni_text-active">
</div>
<div class="mhni_img">
</div>
</div>
</div>
</div>
<div class="monkey_content"></div>
<div class="monkey_footer"></div>
</div>
```
# React Optimizing Performance(优化性能)
* use the production build(使用生产版本)
1、使用React Development Tools for Chrome检测react时生产版本(绿色背景)还是开发版本(红色背景),原因:生产版本没有提示信息,体积更小
2、使用Chrome performance tab分析组件的性能(Profiling Components with the Chrome Performance Tab)
在url后面拼接查询字符串:?react_perf
3、avoid reconcolication
shouldComponentUpdate(nextProps, nextState)该函数会控制re-render的触发与否。
但会引起另一个问题,那就是变量的比较问题,js中引用类型比较的复杂性引起的。
example:
```
handleClick() {
this.setState(prevState => ({
words: prevState.words.concat(['marklar'])//不会引起mutate data
}));
}
```
# component and module
[参考资料](http://blog.csdn.net/horkychen/article/details/45083467)
* component:强调代码的重用(web component 或者说组件是达到可复用要求的模块,将本来分离的html,js,css又糅合到一坨了)
* module:强调职责(内聚、分离)
# 字符集和编码方案
* 字符集:所有符号的集合
* 字符编码集:为每一个`字符`分配一个`唯一的ID`(学名为`码位`、`码点`、`Code Point`)
* 码元(code unit):编码方案中最小字节,例如:utf8码元是8bit,utf16是16bit,utf32是32bit
* 编码方案:将`码位(Code Point)`转换成`字节序列`(储存或传输)的规则。
譬如:utf-8,utf-16,utf-32
广泛的来讲,unicode是一个标准,定义了字符集以及一系列的编码规则,即Unicode字符集和UTF-8、UTF-16、UTF-32等等编码方案……
ansi的askii(American Standard Code for Information Interchange)字符集是使用8位表示127个字符;
出现了新的符号,就继续扩展,出现了askii扩展字符集,但8位最多能表示256个字符;
汉字更多,�8位的已经无法标识,于是127之后的所有状态全部用16位来表示,扩展成GB2313,再后来扩展成GBK、GB8030。此时此刻,**地区出现了BIG5字符集……这些统称为DBCS(Double Byte Charecter Set),为了统一起来,让字符集通用,ISO�组织制作了Unicode字符集。
demo:
raw binary: 0000000001000001
askii 0和A
utf-16 A
<table>
<thead>
<tr>
<th></th>
<th>Unicode</th>
<th>ASCII</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td> U+0030</td>
<td>48</td>
</tr>
<tr>
<td>9</td>
<td> U+0039</td>
<td>57</td>
</tr>
<tr>
<td>A</td>
<td> U+0041</td>
<td>65</td>
</tr>
<tr>
<td>Z</td>
<td> U+005A</td>
<td>90</td>
</tr>
<tr>
<td>a</td>
<td> U+0061</td>
<td>97</td>
</tr>
<tr>
<td>z</td>
<td> U+007A</td>
<td>122</td>
</tr>
<tr>
<td>9</td>
<td> U+0041</td>
<td>57</td>
</tr>
</tbody>
</table>
# RPC(Remote Procedure Call),远程过程调用
* 为什么需要RPC?
随着分布式系统的广泛应用,服务部署在不同的设备上,服务之间的调用�成了问题,为了解决这个问题,就产生了RPC。
* RPC的定义
它是一种通过网络从远程计算机上请求服务,而不需要了解底层网络技术的方式。简单点就是:通过一定的协议和方法使得调用远程计算机上的服务,就像调用本地服务(此处可以理解为指同一台电脑上的服务)一样。
* 基于协议的分类
基于HTTP协议的RPC;
基于TCP协议的RPC;
�
基于二进制协议的RPC;
其它;
* webservice(就是rpc的�实现)
webservice就是一台电子设备通过万维网为另一台电子设备提供服务的case。常用的技术有http,xml,json等。---维基百科
webservice就是一套为 设备与设备通过互联网通信交互 提供解决方案的软件系统。---W3C
* 基于soap&xml的webservice 和 基于restful的webservice
soap(Simple Object Access Protocol):基于xml的简单对象访问协议
soap提供的时操作,不是数据。
[参考资料](https://zhuanlan.zhihu.com/p/25329503)
# 腾讯云Web播放器在线直播和点播
[参考资料](https://www.qcloud.com/document/product/267/7479)
协议支持:HLS(HTTP Live Streaming),苹果的标准,兼容性较好,但是延迟大,在20-30秒左右,PC端有flash存在,相对较好。
<table>
<tr>
<td>视频协议</td>
<td>用途</td>
<td>PC浏览器</td>
<td>移动端浏览器</td>
<td>DEMO</td>
</tr>
<tr>
<td>HLS(m3u8)</td>
<td>直播(点播)</td>
<td>支持</td>
<td>支持</td>
<td>http://2157.liveplay.myqcloud.com/2157_35a.m3u8</td>
</tr>
<tr>
<td>FLV</td>
<td>直播(点播)</td>
<td>支持</td>
<td>不支持</td>
<td>http://2157.liveplay.myqcloud.com/2157_35a.flv</td>
</tr>
<tr>
<td>RTMP</td>
<td>直播</td>
<td>支持</td>
<td>不支持</td>
<td>http://2157.liveplay.myqcloud.com/2157_35a</td>
</tr>
<tr>
<td>MP4</td>
<td>点播</td>
<td>支持</td>
<td>支持</td>
<td>http://2157.liveplay.myqcloud.com/2157_35a.MP4</td>
</tr>
</table>
# 对接准备
* 引入初始化脚本
* HTML里放置容器
- chart.js:HTML5 的 Canvas 绘图,支持 6 种图标类型(折线图、条形图、雷达图、饼图、柱状图、极地区域区,独立的包不依赖第三方库)
- ECharts:基于 Canvas,底层基于 ZRender
- D3.js:基于 SVG
- Highcharts:兼容性好,个人用户免费,纯 js 无 bs 接口
- Fusionchart:强交互性
- Flot:基于 jQuery
- Chartist.js:使用 svgxua 渲染图
- n3-charts:基于 D3.js 和 angular
- Ember Charts:基于 D3 和 Ember
- Demo
1、将状态全部抽到state树上,将每个页面的数据都抽象成uiData、apiData两部分
actionTypes:
1、api接口的actionTypes,服务器可能会改变UI状态
2、ui操作的actionTypes,用户操作也会改变UI状态
actions:
1、apiActions
2、businessActions
reducers:
1、apiReducers:处理api请求
2、businessReducers:处理ui用户操作,还有可能处理api涉及UI状态的处理
uiData: 每一项对应一个业务组件UI数据
apiData: 每一项对应一个业务数据
1.1、apiData包括业务数据和api请求状态,可以按照业务组件抽出数据结构,比如商品信息类业务数据,促销类业务数据、发票类业务数据、运费类业务数据
1.2、uiData类似单选框、复选框之类的状态,可以按业务抽出数据结构,比如促销类UI数据、发票类UI数据、运费累UI数据
1.3 分成UIData和apiData,就需要将部分甚至全部的ActionType处理2遍,所以有必要这样分吗?
2、业务数据放在state树上,UI状态放在组件内部
想法:1、state树直接提供UI中业务组件的props属性,拿来即用,不需要额外的逻辑处理
2、container还是要处理逻辑,比如夸平台,用户交互
GitHub Token: 0dda64dce8b7fac3de9f9040cd2469808938ff4c
GitHub Gist(同步密钥): f4402bd9c87c11daceb45b5efea58a25
GitHub Gist Type: Secret
分类 | 安卓 2.1-4.3 | 安卓 4.4 以上 | UC11.4 | QQ1.2 以上 | IOS safari3.2-6.1 | IOS safari7.1-8.4 | IOS safari9.2 以上 |
---|---|---|---|---|---|---|---|
语法版本 | 09 | 标准 | 09 | 标准 | 09 | 标准 | 标准 |
是否前缀 | 是 | 否 | 是 | 否 | 是 | 是 | 否 |
- 09 年版语法:-webkit-box
- 11 年版过渡语法:-webkit-flex
- 标准语法:flex
| 属性 | 标准 | 09 版 | 说明 | | ------- | :-------------: | :----------------------- | -------- | ------ | | display | flex | box | 块元素 | 无差异 | | display | inline-flex | inline-box | 内联元素 | 无差异 | | 容器 | flex-direction | box-orient,box-direction | 无差异 | | 容器 | flex-wrap | box-lines | 有差异 | | 容器 | flex-flow | 无 | 有差异 | | 容器 | justify-content | box-pack | 有差异 | | 容器 | align-items | box-align | 无差异 | | 容器 | align-content | 无 | 有差异 | | 项目 | order | box-ordinal-group | 无差异 | | 项目 | flex | box-flex | 有差异 | | 项目 | flex-grow | 无 | 有差异 | | 项目 | flex-shrink | 无 | 有差异 | | 项目 | flex-basis | 无 | 有差异 | | 项目 | align-self | 无 | 有差异 |
- justify-content:space-between,旧版语法没有
- flex-wrap: wrap,大部分浏览器不支持 box-lines
- Application:
- Manifest:web 应用程序清单,目的是将 web 应用安装到设备的主屏幕,是 pwa 技术的一部分
- ServiceWorkers:
- Storage:(https://www.cnblogs.com/best/p/6084209.html) 3. LocalStorage:大小限制 500 万字符左右,本质是读写文件,不能跨域 4. SessionStorage:不能跨域 5. IndexedDB: 6. WebSQL:支持度不够好 7. Cookies:大小限制是 4k,每次 http 请求都会带上 cookie,cookie 是否可以访问收到 path 和域名的影响,子域名可以访问父域名的 cookie
- Cache: 8. CacheStorage(存储静态资源) 9. ApplicationCache(根据 manifest 来进行缓存)
- 其它: 10. PWA
<!-- Manifest json文件 -->
cookies--->web storage(localstorage和sessionstorage)--->
webpackJsonpCallback函数作用就是加载模块,并触发回调函数
data[0]: chunkIds: Array,chunkId列表
data[1]: moreModules: Object,
data[2]: executedModules:
- (window['webpackJsonp'] = window['webpackJsonp'] || []).push([[0], {}, [[10, 1, 2]]])((备注:chunk))
- DCE(Dead Code Elimination)
DeadCode:
不会被执行的代码
代码执行的结果不会被用到
代码只会影响只写不读的变量
Tools:
1、rollup
2、uglify(目前不会跨文件DCE)
- alpha:内测版,主要是给开发人员和测试人员测试用的,a 第一个希腊字母,表示最早的版本
- beta:公开测试版本,b 是第二个希腊字母,晚于 alpha 版
- rc:Release Cadidate(候选版本),和最终版本保持一致
- stable:稳定版
- react 版本:v0.3.0--->v0.14.8--->v15.0.0--->lastest
- post 请求
https://api.dev.dc.com/m.api
FormData:
_chl=iOS%7C&_mt=phoebe.getConfig&_sm=md5&key=wx.background&_sig=03cddc889d2728302ab1ffa46a3485b6
- get 请求
http://api.test.dc.com/m.api?_chl=iOS%7C&_mt=pegasus.getRecipe&_sm=md5&outBizType=&recipeId=15516952408822238150663230603&_sig=4cb3d2809eb973f362d003fd5e8e2bdd
http://api.test.dc.com/m.api?_chl=iOS%7C&_mt=pegasus.orderCreatePage&_sm=md5&biz=%7B%22outBizNo%22%3A%2215516952408822238150663230603%22%7D&fund=%7B%22healthGoldSelected%22%3A%22%22%2C%22healthLiveSelected%22%3A%22%22%2C%22paymentType%22%3A%22%22%2C%22invoice%22%3A%7B%22selected%22%3A%22%22%7D%7D&lg=%7B%22addressId%22%3A0%2C%22tel%22%3A%22%22%2C%22distributor%22%3A%224%22%7D&outBizType=&seller=%5B%7B%22storeId%22%3A200001800208%2C%22skus%22%3A%5B%7B%22skuId%22%3A911911888700424%2C%22amount%22%3A1%7D%5D%7D%5D&user=%7B%7D&_sig=264d7a6ab56db28b3e0bba6216ff39c2
module.exports = function(source) {
<!-- 对source进行逻辑处理 -->
this.callback(null, handledSource, map);
}
- options 配置项
Entry: entryOption
Plugins: afterPlugins
Resolve: afterResolvers
enviroment
afterEnvironment
beforeRun
run
watchRun
normalModuleFactory
contextModuleFactory
beforeCompile
compile
thisCompilation
compilation
make
afterCompile
shoulEmit
emit
afterEmit
assetEmitted
done
failed
invalid
watchClose
infrastructureLog
log
-
webpack 中的事件 事件名|触发时机|回调参数|Hook 类型 ---|:--:|:--:|:--:|--- entryOption|配置项 entry 被处理后触发|(context, entry) => {}|SyncBailHook afterPlugins|内部插件初始化之后触发|(compiler) => {}|SyncHook afterResolvers|resolver 设置完成之后触发|(compiler) => {}|SyncHook ...|...|...|...
-
Tapable
旧版本:
this._plugins = {
'event_name': ['event_handler']
};
Tapable.prototype.plugin = function plugin(name, fn) {
if(Array.isArray(name)) {
name.forEach(function(name) {
this.plugin(name, fn);
}, this);
return;
}
if(!this._plugins[name]) this._plugins[name] = [fn];
else this._plugins[name].push(fn);
};
Tapable.prototype.apply = function apply() {
for(var i = 0; i < arguments.length; i++) {
arguments[i].apply(this);
}
};
新版本:
将所有的插件全部拆分成几个不同的类型,同步和异步。
在同步和异步的前提下,根据event_handler执行规则又分成若干,
同步:SyncHook, SyncBailHook, SyncLoopHook, SyncWaterfallHook
异步:AsyncParallelHook, AsyncParallelBailHook, AsyncSeriesBailHook, AsyncSeriesHook, AsyncSeriesLoopHook, AsyncSeriesWaterfallHook
每一种Hook自己维护自己的event_handler,格式如下
this.taps = [
{
name: '',
fn: fn,
type: 'sync',
before: '',
stage: 'number',
...还有不知道的参数...
}
];
1、***Hook函数最终返回的是Hook的实例hook,hook.tapAsync,hook.tapPromise函数属性会直接抛异常,hook.compile属性函数创建了对应的factory函数,并执行了factory.create()函数,返回factory.create()的返回值
- 1、入口:webpack 命令行会调用 webpack 库中 webpack.js 中的 webpack 函数
- 2、校验配置文件 options(经测试,options 内容就是配置文件导出的 JSON 对象)
- 3、根据 options 类型调用不同的 compiler
- 3-1、options 是数组时,走 MultiCompiler 流程,再调用 webpack 入口函数
- 3-2、options 是非数组时,使用 WebpackOptionsDefaulter 处理 options,并走 Compiler 流程
OptionsDefaulter(父类)------WebpackOptionsDefaulter(子类)
Tapable(父类)------------------Compiler(子类)
1、WebpackOptionsDefaulter:设置所有的默认配置项,使用process函数,将用户的配置项与默认配置项合并
2、let compiler = new Compiler(options.context);options.context是指cwd
google 的 inspect 线上资源地址: 172.217.160.116 chrome-devtools-frontend.appspot.com Apache-internals: /Users/wangfanghua618/Library/Application Support/Google/Chrome/Default (1)
- gradle 和安卓 gradle 插件是两个东西,版本要对应
- gradle 国内镜像资源