记录遇到的一些问题和解决方法,和一些技巧。
Sublime
快速执行任务
按住 Shift+Command+P
可以弹出一个输入框,可以输入关键字快捷执行一些操作。
例如美化 HTML 格式插件的功能,输入 HTML
,会智能匹配结果,选中 HTMLPrettify
即可实现该插件的操作。
输入 package control
快速进入安装 plugin 界面。
Webpack
遇到的坑
babel 的 resolve.alias 问题
因为看到通过配置 alias 可以加快 webpack 的执行速度,所以尝试了一下使用,但没想到遇到了挺多问题,最后也没解决,这里记录一下。
首先在 webpace.config.js 新添加的配置:
1 |
|
基本跟照着官网的文档来的。
第一个问题是 alias 配置问题,pathToReact 打印出来的路径是 /Users/yang/Desktop/Web/公司/cmw/reactUI/node_modules/react/dist/react.min.js
,在使用 require(‘react’) 成功指向了 react/dist/react.min.js
。
但使用 react-addons-css-transition-group
时 (通过 npm 安装,0.14 版 react 将这个包分出来),包里面的 index.js
内容是
module.exports = require('react/lib/ReactCSSTransitionGroup');
编译时 react/
却被替换成了 react/dist/react.min.js
。
即 module.exports = require('react/dist/react.min.js/lib/ReactCSSTransitionGroup');
。
第二个问题,还是 alias 的问题,多番尝试后将 'react': pathToReact
改成 'react$': pathToReact
,多了一个 $
编译就通过了,但是测试网站时报一些 Invariant Violation: addComponentAsRefTo ...
之类的错误,查了一下原因可能是重复引用了 react 吧,具体是什么原因没查到。
所以还是弄不懂 alias 的规则,所以暂时使用了。而且在 babel-loader 添加一段 cacheDirectory: true,
,出了第一次慢点,以后编译都挺快的。
import 和 require 冲突的问题
如果一个 module 使用 export default [ModuleName];
导出 module,而导入时却使用 require([ModuleName])
,则会报错:
1 |
|
解决方式是使用对应的语法:
import from 'ModuleName'
对应 export default 'ModuleName';
require ('ModuleName')
对应 module.exports = 'Modulename';
。
这个问题出现在使用 webpack build 时,使用了 babel 6 进行语法转换,下面是 babel-loader 的配置:
1 |
|
使用项目自带的 gulp 配置没出现这个问题。
查了下资料,gulp 使用的是 babel 5,我在 webpack 使用的是 babel 6,而 babel 6 将所有东西都以 plugin 的形式分离出去了,默认是没功能的。
而仅仅 es5 就有 20多个 plugin,所以提供了 presets 让我们简化操作。
5. babel-loader 的问题
在使用 ES 6 的 JS 代码中,用到了 Object.assgin
方法合并两个对象。使用 babel-loader 可以成功 build,但是项目运行时报找不到该对象的错。
这个问题可能是在 loader 配置 exclude
,排除了 node_modules 文件夹,没有仔细去认证。
解决方式是需要另外安装 babel-loader 的 plugin。安装时也遇到了坑,回复说需要安装的是 babel-plugin-object-assign
,但安装完成后进行 build 时报错。又找了一下资料,尝试安装 babel-plugin-transform-object-assign
,然后 build 成功了,估计是 babel 5 和 babel 6 之间版本的问题吧。
下面是操作过程,首先安装 plugin:
1 |
|
然后应用到 webpack.config.js
中:
1 |
|
4.less 加载的问题
加载 less 遇到了路径解析解析错误的问题。
最开始的 loader 是跟官网一样:
1 |
|
这样解析路径时会出错,改为 loader: 'style!raw!less'
就没问题了,不过这样会把 css 打包到 JavaScript 中,我想让 css 文件单独分离出来,所以找到了这样的解决方式:
先安装插件
1 |
|
然后引用
1 |
|
修改配置文件
1 |
|
注意 less 的 loader 的 extract 使用了 raw-loader
,这样可以解析路径时出错的问题,需要另外安装 raw-loader
:
npm i raw-loader --save-dev
3.babel-loader 加载 JavaScript 版本问题
接第二个问题,实验项目成功后,开始在实际项目使用,结果又报错,无法识别这样的语法:
1 |
|
理所当然的认为是无法识别 ...
的语法。于是在其它项目试验了一下 <Accordion {...props}></Accordion >
这样的语法,是可以的,并且自己项目中也支持这样的语法。在仔细看了,原来是不支持这样的语法:
1 |
|
原来这种语法是 ES7 的语法,还需要装一个 Babel 插件:
1 |
|
1 |
|
2.loader 问题
使用 babel 加载 jsx 时遇到无法识别 import 的问题
1 |
|
开始自己配置时就出现这个问题,一摸一样的 webpack 配置其他人的项目缺没这个问题。
后来在 bable-loader 的主页看到需要传递一些参数:
1 |
|
这样就问题了,估计版本跟其它项目不一致。
1.webpack-dev-server build 问题
webpack-dev-server 在运行时 build 的文件会生成到内存中,在 finder 中看不到文件的变化。
找了很久都找不到 build 的文件在哪,但是效果又是可以看到的。
Git
一次问题记录
可以使用 revert 回滚之前的 commit,回滚之后工作区的内容已经变了,无法像提交之前可以在暂存区取消单个文件的修改。
可以点击 undo,取消上一次提交。上一次提交就是刚才回滚的提交。
JavaScript
=>
简化 function
1 |
|
Lexical this
出了 arrow function,每个新 function 都定义了它自己的 this 值 (例子中构造的新对象,在 strict mode 中未定义的 function 调用,context 对象中如果 function 作为 “object method” 调用等)。这是恼人的面向对象的编程风格。
1 |
|
在 ECMAScript 3/5,这个问题的修复方式是通过分配 this 值给变量。
1 |
|
此外,可以使用 bound function (.bind()
方式) 创建 function 使 this 值正确传递到 growUp() function。
而 Arrow function 可以捕获 enclosing context 的 this 值,因此下面的代码可以预期工作:
1 |
|
现在这个方法浏览器支持得不多,了解一下就行,还有几种用法。
bind 和 apply 和 call
bind 用来明确指定方法 (或对象) 内的 this 值。
在方法后面使用 bind 会返回一个新方法,这个方法的参数会被 bind 绑定,返回后的新方法即便重新传入参数也无效。
这里有一个原始方法:
1 |
|
使用 bind
创建一个方法:
1 |
|
现在调用 multiby2(b)
就与调用 multiplication(2,b)
的值相同,参数 a 已经被 bind 绑定。
通过 bind
创建的方法类型是 function b()
,原始的方法会被隐藏。
而 call 和 apply:
1 |
|
会立即执行方法,apply 可以以数组方法传递参数。
React
好的做法
通过对组件设置一个属性 ref
,即可通过 this.refs.componentsName
访问该组件的内置方法。例如使轮播组件暂停滚动(取消定时器)。
遇过的坑
调用四个相同的组件,把父组件不同 state 传递给四个组件的 visible 值,更改父组件其中一个 state,发现四个组件都触发了 render。
return 的换行 bug
1 |
|
componentWillUnmount
只有在整个组件都删除时才会触发,即父组件中完全不渲染子组件。假如子组件的 render 是根据父组件的属性判断是返回内容或 null,即使子组件的返回 null,也不会触发子组件的 componentWillUnmount
。
对 React 组件化理解不够深,写了两个组件,都用到了一个覆盖整个页面的遮罩层,而这个遮罩层可以分离成一个组件,这是对组件化理解不够深时遇到的坑。
December 16, 2015 09:23 补充:
不会在将来移除。因为之前使用时没有提供 transitionEnterTimeout
和transitionLeaveTimeout
属性,所以报错会造成不可靠的动画效果,并且不被未来版本支持。这是是说不提供这两个参数那么在未来版本无法运行动画效果。
ReactCSSTransitionGroup 使用太过麻烦,并且可能在将来的版本移除。React 版本 0.14.3。
state 命名要以大写开头,不知道是 React 强制规定还是其它规则组件所要求。React 版本 0.14.3。
… 运算符
December 14, 2015 14:24
常用于将父组件的 props 完整传递给子组件。
暂时未知它的作用,可能跟遍历数组相关,下面是一个使用情境。
在组件的 render 中:
1 |
|
调用组件的代码:
1 |
|
生成的 HTML:
1 |
|
一旦将 ...
去掉,则出现语法错误。
ref
有时需要绕过 React 的虚拟 DOM,明确的使用原生 DOM API,例如使用 jQuery 插件时的操作,React为你提供了安全仓口来直接使用底层API。
为了与浏览器互动,你需要一个指向 DOM node
的引用。React有一个函数ReactDOM.findDOMNode(component)
,你能调用以得到一个指向指向组件的DOM node的引用。
findDOMNode() 只作用于已挂载的组件(即,已经放置于DOM中的组件)。如果你尝试在还没有被挂载的组件上调用此函数(比如在render() 里有待被创建的组件上调用
findDOMNode()
将会抛出一个异常)
findDOMNode 已经在 React 0.14 移除,直接使用 this.myTextInput
即可。
用法:
1 |
|
Node.js
模块机制
http://www.infoq.com/cn/articles/nodejs-module-mechanism
#NPM
Package.json
scripts
安装本地模块
有的模块在其它项目中已经 install 过,其它项目也用上的话,可以使用安装本地模块的方式,省去重复安装下载,节省磁盘空间。
第一种方式
是使用 npm link
,测试过
首先进入已安装的模块目录,在终端执行 npm link
,可能需要使用 sudo
。
执行完成后进入需要安装该模块的目录,执行 npm link package-name
。
这种方式不会将模块复制到新安装目录中,而会创建一个链接目录。
第二种方式
是使用 npm install /path
,这个方式没实际使用过,好像会将模块复制到新安装目录。
第三种方式
在 NPM 2.0,可以直接把本地路径写入 package.json 的 dependencies
中,也没实际使用:
1 |
|