react 的类型声明
ts react 难就难在中间件的类型推导, ts 中 react 难度如果为 1,那么 redux 为 5, redux 中间件为 20.
ts 中的类型大部分在库里都已经写好了,但比较难记,这里记录一下。
由于 SPA 应用随着开发层级越来越多,管理不断变化的 state 非常困难,即使是同级组件,也需要经过很多层才能通信。Redux 是在这种情况下出现的,实现原理是 发布订阅模式。它其实并不依赖于 react,但一般与 react 一起使用,内部使用闭包保存 state,向外暴露 getStore、dispatch、reducer 等方法
由于每个组件想要使用 redux,必须引入 store,设置 dispatch,通过 subscribe 在 componentDidMount 时订阅,在 componentWillUnmount 时取消订阅,极其繁琐,即使 redux 里有 bindActionCreators 来解决每次都要写 store.dispatch 的问题,也是效果甚微。因此出现了 react-redux 这个库,它是一个高阶组件,通过 connect 方法把 store 和组件映射起来,通过 Provider 注入到组件的 props,就可以省去上面的步骤,直接使用 props 使用 store 的 state、action 了。
记录一下遇到的可以简写的内容。
1 | if (l.get(-key)) { |
1 | if (l.get(key)) { |
1 | 3.25 << 0 // 3 |
1 | if (str,indexOf('a') > -1) {} |
1 | var a = 100 |
重新整理一下正则知识。
String.match(RegExp)
字符串匹配正则方法 match,如果匹配成功,会返回一个数组,第一项表示整个正则 (regexp)
匹配到的内容,其余表示所有捕获组。匹配不成功返回 null。
match 返回的这个数组上有几个自定义属性:
()
匿名捕获组,如果在 /(这里)/
被匹配到,会返回到 match 得到的数组中,在字符串的 replace 方法中,可以用 $n
来表示第几个捕获组,n 从 1 开始,表示第一个捕获组。
(?:)
非捕获组,如果在 /(?:)/
被匹配到,也不会返回到 match 得到的数组中,但正则仍然需要匹配到它,只是不返回到数组中。
(?<name>)
具名捕获组,replace 中可以用 $<name>
来取得匹配内容替换的字符串。
(?<后顾)X(?前瞻)
,前瞻后顾是相对与 X 来讲的,X 在前面就是前瞻,X在后面就是后顾。
注意:断言不会消耗匹配内容,仅仅起到条件匹配作用。
模式 | 类型 | 匹配 |
---|---|---|
x(?=y) |
前瞻肯定断言 | 匹配 y 前的 x |
x(?!y) |
前瞻否定断言 | 匹配不在 y 前的 x |
(?<=y)x |
后顾肯定断言 | 匹配在 y 后的 x |
(?<!y)x |
后顾否定断言 | 匹配不在 y 后的 x |
例子
1 | 'a123b'.match(/a(?<=a)(?<first>1)(?:(2)3)(?=b)b/) |
npm 是包管理工具
npm config list
可以查看 npm 配置。
比如有一个 registry 属性,标识C盘用户目录下 .npmrc 里有一个 registry 属性,可以用于配置 npm 源
全局安装的意思很简单,就是安装的模块会被安装到全局下。是只能在命令行中使用的包。
npm root -g
可以查看 npm -g 的全局安装目录,比如 npm i http-server -g
,如果已经安装过一次,会报错说本地已存在,需要覆盖的话加上 –force,npm i http-server -g --force
。
为什么 npm -g 的包可以全局使用,举个例子 npm i http-server -g
其实只是在 **/user/local/bin
(C:\User\test1\AppData\Roaming\npm\hs 和C:\User\test1\AppData\Roaming\npm\http-server
)目录下作了个链接到 /usr/local/lib/node_modules/http-server/bin/http-server
(C:\User\test1\AppData\Roaming\npm\node_modules\http-server\bin\http-server
)这个文件,当我们执行 http-server 或 hs 这个命令时,会去找目录下的 .cmd 文件,之后 .cmd 会调用这个链接的文件,而这个文件的开头,会标识出这个文件是用什么来执行的(#!/usr/bin/env node
表示用环境变量里的 node 来执行这个文件,前面是固定的,不管是 mac 还是 windows,如果不标识,将会当作 txt 文件打开。)
如果能直接在命令行里输入 hs 后能够执行命令,可以发现系统或用户的环境变量 PATH 里会有 C:\User\test1\AppData\Roaming\npm
这样的路径,cmd 里直接输入 path,可以查看所有的环境变量。
包的初始化,生成一个 package.json 文件,值得一提的是,”main”: “xxx.js” 字段是 node 会默认调用的文件,webpack 默认会调用 “module” (es6 模块用)
临时指令,在开发时,可以将我们的包临时放到全局下,方便调试。后续可以将包发到 npm 上,通过 -g 下载。仅仅能在命令行中使用,做一些工具。
在我们为 package.json 加入 “bin”: “xxx.js” 的属性后,可以使用 npm link 将当前目录做一个软链到 C:\User\test1\AppData\Roaming\npm
,然后就会在这个目录下新建一个当前 package,json 里 name 属性一样名字(比如 dl)的 .cmd 文件,指向 C:\User\test1\AppData\Roaming\npm\node_modules\dl\xxx.js
,而这个 C:\User\test1\AppData\Roaming\npm\node_modules\dl
是当前项目目录的一份拷贝(C:\User\test1\AppData\Roaming\npm\node_modules\dl
会指向当前目录),每次修改了当前目录的文件之后,如果想要更新全局指令,需要重新 npm link,当然这时候会出现重复,需要 –force。
最后结果是 C:\User\test1\AppData\Roaming\npm\dl
(这是一个文件) 指向 C:\User\test1\AppData\Roaming\npm\node_modules\dl\xxx.js
,接着 C:\User\test1\AppData\Roaming\npm\node_modules\dl
指向当前项目目录。
bin 属性如果想写多个,可以写成对象形式
1 | { |
devDependencies 开发依赖
dependencies 项目依赖
peerDepencies 同版本依赖,
optionsalDependencies(很少用,表示可选包,下不下都行。。好像没啥用)
bundleDependencies(npm pack 压缩成 .tgz 时用的,会把这里的包一起打包进去)
npm i xxx -D 开发依赖,仅在开发时使用,比如 gulp(打包 css),安装到”devDependencies”。
npm i xxx -S 项目依赖,开发上线都需要,比如 react、vue,安装到 “dependencies”。
npm 特点是会将包拍平,当我们安装了 a 和 b 两个包,a 中依赖了 c 包,b 中也依赖了 c 包,此时由于 npm 已经把包拍平,所以会共用同一个 c 包,只安装一次。但是,如果 a 包和 b 包中的 c 包版本不同,就不会拍平了,就都会安装各自模块目录里去。
比如,当前项目下使用 -S 安装了 jquery,又在 package.json 的 “peerDependencies” 中有 “bootstrap”: “^3.0.0” 属性。
由于 jq 也依赖 bootstrap,在 npm i 的时候,很有可能会出现警告
1 | npm WRAN [email protected] requires a peer of bootstrap@^3.0.0 but none is installed. You must install peer dependencies youerself. |
就表示需要一个 3.0.0 的依赖,但是没装,可能会出现问题。
会用当前目录打出一个 .tgz 的包,可以上传到服务器上