Coder Social home page Coder Social logo

react-tetris's Introduction

English introduction

Please view README-EN.md


用React、Redux、Immutable做俄罗斯方块


俄罗斯方块是一直各类程序语言热衷实现的经典游戏,JavaScript的实现版本也有很多,用React 做好俄罗斯方块则成了我一个目标。

戳:https://chvin.github.io/react-tetris/ 玩一玩!


效果预览

效果预览

正常速度的录制,体验流畅。

响应式

响应式

不仅指屏幕的自适应,而是在PC使用键盘、在手机使用手指的响应式操作

手机

数据持久化

数据持久化

玩单机游戏最怕什么?断电。通过订阅 store.subscribe,将state储存在localStorage,精确记录所有状态。网页关了刷新了、程序崩溃了、手机没电了,重新打开连接,都可以继续。

Redux 状态预览(Redux DevTools extension

Redux状态预览

Redux设计管理了所有应存的状态,这是上面持久化的保证。


游戏框架使用的是 React + Redux,其中再加入了 Immutable,用它的实例来做来Redux的state。(有关React和Redux的介绍可以看:React入门实例Redux中文文档

1、什么是 Immutable?

Immutable 是一旦创建,就不能再被更改的数据。对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象。

初识:

让我们看下面一段代码:

function keyLog(touchFn) {
  let data = { key: 'value' };
  f(data);
  console.log(data.key); // 猜猜会打印什么?
}

不查看f,不知道它对 data 做了什么,无法确认会打印什么。但如果 data 是 Immutable,你可以确定打印的是 value

function keyLog(touchFn) {
  let data = Immutable.Map({ key: 'value' });
  f(data);
  console.log(data.get('key'));  // value
}

JavaScript 中的ObjectArray等使用的是引用赋值,新的对象简单的引用了原始对象,改变新也将影响旧的:

foo = {a: 1};  bar = foo;  bar.a = 2;
foo.a // 2

虽然这样做可以节约内存,但当应用复杂后,造成了状态不可控,是很大的隐患,节约的内存优点变得得不偿失。

Immutable则不一样,相应的:

foo = Immutable.Map({ a: 1 });  bar = foo.set('a', 2);
foo.get('a') // 1

简洁:

Redux中,它的最优做法是每个reducer都返回一个新的对象(数组),所以我们常常会看到这样的代码:

// reducer
...
return [
   ...oldArr.slice(0, 3),
   newValue,
   ...oldArr.slice(4)
];

为了返回新的对象(数组),不得不有上面奇怪的样子,而在使用更深的数据结构时会变的更棘手。 让我们看看Immutable的做法:

// reducer
...
return oldArr.set(4, newValue);

是不是很简洁?

关于 “===”:

我们知道对于ObjectArray===比较,是对引用地址的比较而不是“值比较”,如:

{a:1, b:2, c:3} === {a:1, b:2, c:3}; // false
[1, 2, [3, 4]] === [1, 2, [3, 4]]; // false

对于上面只能采用 deepCopydeepCompare来遍历比较,不仅麻烦且好性能。

我们感受来一下Immutable的做法!

map1 = Immutable.Map({a:1, b:2, c:3});
map2 = Immutable.Map({a:1, b:2, c:3});
Immutable.is(map1, map2); // true

// List1 = Immutable.List([1, 2, Immutable.List[3, 4]]);
List1 = Immutable.fromJS([1, 2, [3, 4]]);
List2 = Immutable.fromJS([1, 2, [3, 4]]);
Immutable.is(List1, List2); // true

似乎有阵清风吹过。

React 做性能优化时有一个大招,就是使用 shouldComponentUpdate(),但它默认返回 true,即始终会执行 render() 方法,后面做 Virtual DOM 比较。

在使用原生属性时,为了得出shouldComponentUpdate正确的true or false,不得不用deepCopy、deepCompare来算出答案,消耗的性能很不划算。而在有了Immutable之后,使用上面的方法对深层结构的比较就变的易如反掌。

对于「俄罗斯方块」,试想棋盘是一个二维数组,可以移动的方块则是形状(也是二维数组)+坐标。棋盘与方块的叠加则组成了最后的结果Matrix。游戏中上面的属性都由Immutable构建,通过它的比较方法,可以轻松写好shouldComponentUpdate。源代码:/src/components/matrix/index.js#L35

Immutable学习资料:


2、如何在Redux中使用Immutable

目标:将state -> Immutable化。 关键的库:gajus/redux-immutable 将原来 Redux提供的combineReducers改由上面的库提供:

// rootReducers.js
// import { combineReducers } from 'redux'; // 旧的方法
import { combineReducers } from 'redux-immutable'; // 新的方法

import prop1 from './prop1';
import prop2 from './prop2';
import prop3 from './prop3';

const rootReducer = combineReducers({
  prop1, prop2, prop3,
});


// store.js
// 创建store的方法和常规一样
import { createStore } from 'redux';
import rootReducer from './reducers';

const store = createStore(rootReducer);
export default store;

通过新的combineReducers将把store对象转化成Immutable,在container中使用时也会略有不同(但这正是我们想要的):

const mapStateToProps = (state) => ({
  prop1: state.get('prop1'),
  prop2: state.get('prop2'),
  prop3: state.get('prop3'),
  next: state.get('next'),
});
export default connect(mapStateToProps)(App);

3、Web Audio Api

游戏里有很多不同的音效,而实际上只引用了一个音效文件:/build/music.mp3。借助Web Audio Api能够以毫秒级精确、高频率的播放音效,这是<audio>标签所做不到的。在游戏进行中按住方向键移动方块,便可以听到高频率的音效。

网页音效进阶

WAA 是一套全新的相对独立的接口系统,对音频文件拥有更高的处理权限以及更专业的内置音频效果,是W3C的推荐接口,能专业处理“音速、音量、环境、音色可视化、高频、音向”等需求,下图介绍了WAA的使用流程。

流程

其中Source代表一个音频源,Destination代表最终的输出,多个Source合成出了Destination。 源代码:/src/unit/music.js 实现了ajax加载mp3,并转为WAA,控制播放的过程。

WAA 在各个浏览器的最新2个版本下的支持情况(CanIUse

浏览器兼容

可以看到IE阵营与大部分安卓机不能使用,其他ok。

Web Audio Api 学习资料:


4、游戏在体验上的优化

  • 技术:
    • 按下方向键水平移动和竖直移动的触发频率是不同的,游戏可以定义触发频率,代替原生的事件频率,源代码:/src/unit/event.js
    • 左右移动可以 delay 掉落的速度,但在撞墙移动的时候 delay 的稍小;在速度为6级时 通过delay 会保证在一行内水平完整移动一次;
    • 对按钮同时注册touchstartmousedown事件,以供响应式游戏。当touchstart发生时,不会触发mousedown,而当mousedown发生时,由于鼠标移开事件元素可以不触发mouseup,将同时监听mouseout 模拟 mouseup。源代码:/src/components/keyboard/index.js
    • 监听了 visibilitychange 事件,当页面被隐藏\切换的时候,游戏将不会进行,切换回来将继续,这个focus状态也被写进了Redux中。所以当用手机玩来电话时,游戏进度将保存;PC开着游戏干别的也不会听到gameover,这有点像 ios 应用的切换。
    • 任意时刻刷新网页,(比如消除方块时、游戏结束时)也能还原当前状态;
    • 游戏中唯一用到的图片是image,其他都是CSS;
    • 游戏兼容 Chrome、Firefox、IE9+、Edge等;
  • 玩法:
    • 可以在游戏未开始时制定初始的棋盘(十个级别)和速度(六个级别);
    • 一次消除1行得100分、2行得300分、3行得700分、4行得1500分;
    • 方块掉落速度会随着消除的行数增加(每20行增加一个级别);

5、开发中的经验梳理

  • 为所有的component都编写了shouldComponentUpdate,在手机上的性能相对有显著的提升。中大型应用在遇到性能上的问题的时候,写好shouldComponentUpdate 一定会帮你一把。
  • 无状态组件Stateless Functional Components)是没有生命周期的。而因为上条因素,所有组件都需要生命周期 shouldComponentUpdate,所以未使用无状态组件。
  • webpack.config.js 中的 devServer属性写入host: '0.0.0.0',可以在开发时用ip访问,不局限在localhost;
  • redux中的store并非只能通过connect将方法传递给container,可以跳出组件,在别的文件拿出来做流程控制(dispatch),源代码:/src/control/states.js
  • 用 react+redux 做持久化非常的方便,只要将redux状态储存,在每一个reduers做初始化的时候读取就好。
  • 通过配置 .eslintrc.js 与 webpack.config.js ,项目中集成了 ESLint 检验。使用 ESLint 可以使编码按规范编写,有效地控制代码质量。不符规范的代码在开发时(或build时)都能通过IDE与控制台发现错误。 参考:Airbnb: React使用规范

6、总结

  • 作为一个 React 的练手应用,在实现的过程中发现小小的“方块”还是有很多的细节可以优化和打磨,这时就是考验一名前端工程师的细心和功力的时候。
  • 优化的方向既有 React 的本身,比如哪些状态由 Redux存,哪些状态给组件的state就好;而跳出框架又有产品的很多特点可以玩,为了达到你的需求,这些都将自然的推进技术的发展。
  • 一个项目从零开始,功能一点一滴慢慢累积,就会盖成高楼,不要畏难,有想法就敲起来吧。 ^_^

7、控制流程

控制流程


8、开发

安装

npm install

运行

npm start

浏览自动打开 http://127.0.0.1:8080/

多语言

i18n.json 配置多语言环境,使用"lan"参数匹配语言如:https://chvin.github.io/react-tetris/?lan=en

打包编译

npm run build

在build文件夹下生成结果。

react-tetris's People

Contributors

0xflotus avatar andresilveirah avatar calmbit avatar chvin avatar goudarz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-tetris's Issues

请求上架到AppStore

作者你好,您这个项目太完美了,我想上架到AppStore可以吗?

我有苹果的开发者账号,想写一个简单的App,在App内用浏览器加载 https://chvin.github.io/react-tetris 这个页面。

  1. 会注明作者
  2. 不插入广告
  3. 免费

Reuse

Can I use your game on a website with ads? Not sure I understand the licence.

License

That's a wonderful project, what's the license? I'd like to port it to React Native if I could to follow your design

Uncaught TypeError: Cannot set property '4' of undefined

Hi,

we are receiving this error when we lose Tetris. can anybody suggest solution???
We are receiving tons of this error when we lost game.

index.js:6542 Uncaught TypeError: Cannot set property '4' of undefined
at pieceSetter (index.js:6542)
at Object.getGameBoard (index.js:6964)
at gameBoard (index.js:7240)
at Object.Gameboard._this._onChange (index.js:7291)
at emitNone (index.js:4735)
at Object.emit (index.js:4829)
at Object.emitChange (index.js:5143)
at Object. (index.js:7010)
at emitNone (index.js:4735)
at Object.emit (index.js:4829)
at Object.emitChange (index.js:5143)
at Object.setPiece (index.js:6580)
at _lockInPiece (index.js:6824)
at _moveDown (index.js:6794)
at Object.tick (index.js:6876)
at index.js:6975

iOS12, Safari compatibility issue

iOS12下,Safari里,快速点击某个按钮(比如连按两下“向左”按钮),会触发页面缩放操作。

Under iOS12, using Safari, when click same button rapidly (e.g. Press "Move Left" button twice quickly), will trigger the zoom operation of the browser.

No explicit license.

Hello Chvin,

I can see that the repository doesn't contain any license file.
READMEs also doesn't mention any licenses.

Could this be fixed, so everyone can clearly see how this repo may be used, please?

Kind regards

New feature for GamePad&Joystick control 添加手柄功能

Hello Chvin,

We added GamePad control for this wonderful Tetris game, maybe it isn't good enough but it works well in my Chrome browser:)
Only changed this file: src/control/index.js
https://github.com/chvin/react-tetris/commit/1e31eed7aaa19446f9f5ebd60cd42640d1bb7c8f

我添加了手柄功能来方便大家用手柄玩这个完美的游戏,在我的Chrome 浏览器上运行效果还不错。
可能需要调整按键的顺序来适配不同的手柄,我们自己是用Joyscube测试,它能够自己调整按键顺序,所以不存在这个问题!

Not Working | Not loading

I tried to use it as you can go from my web to yours. But it seems to not load all fies please help!

关于习惯问题

你好,做得很棒,所以闲暇时候也会经常玩玩。
可有个体验感受说下哦,这不是我们童年接机的手势习惯,我们童年的都是 左边方向键,右边圆圈变形键。我上传了一张小时接机图模型,希望作者有空能调整一下哦....谢谢。期待~
image

这个项目是什么协议的

我注意到没有这个项目没有开源协议,就想问一下.感觉蛮好玩的,想拿来搭建到自己的网站下

npm run build时报错

我在npm run build时遇到错误


> [email protected] build
> rm -rf ./docs/* && webpack --config ./webpack.production.config.js --progress && ls ./docs

 10% 0/1 build modulesThe react/require-extension rule is deprecated. Please use the import/extensions rule from eslint-plugin-import instead.
 70% 1/1 build modules(node:40496) Warning: Accessing non-existent property 'cat' of module exports inside circular dependency
(Use `node --trace-warnings ...` to show where the warning was created)
(node:40496) Warning: Accessing non-existent property 'cd' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'chmod' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'cp' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'dirs' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'pushd' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'popd' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'echo' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'tempdir' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'pwd' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'exec' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'ls' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'find' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'grep' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'head' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'ln' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'mkdir' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'rm' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'mv' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'sed' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'set' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'sort' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'tail' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'test' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'to' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'toEnd' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'touch' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'uniq' of module exports inside circular dependency
(node:40496) Warning: Accessing non-existent property 'which' of module exports inside circular dependency
Hash: 297bc94e95c5cbfaebeb  
Version: webpack 1.15.0
Time: 8636ms
            Asset       Size  Chunks             Chunk Names
     app-1.0.1.js    1.15 MB       0  [emitted]  main
    css-1.0.1.css    7.11 kB       0  [emitted]  main
 app-1.0.1.js.map    1.36 MB       0  [emitted]  main
css-1.0.1.css.map   90 bytes       0  [emitted]  main
        music.mp3    54.4 kB          [emitted]  
       loader.css     1.5 kB          [emitted]  
       index.html  991 bytes          [emitted]  
    + 310 hidden modules

ERROR in app-1.0.1.js from UglifyJs
SyntaxError: Unexpected token name «i», expected punc «;» [./~/qrcode/lib/core/qrcode.js:51,0]
Child html-webpack-plugin for "index.html":
        + 3 hidden modules
Child extract-text-webpack-plugin:
        + 2 hidden modules
Child extract-text-webpack-plugin:
        + 2 hidden modules
Child extract-text-webpack-plugin:
        + 2 hidden modules
Child extract-text-webpack-plugin:
        + 2 hidden modules
Child extract-text-webpack-plugin:
        + 2 hidden modules
Child extract-text-webpack-plugin:
        + 2 hidden modules
Child extract-text-webpack-plugin:
        + 2 hidden modules
Child extract-text-webpack-plugin:
        + 2 hidden modules
Child extract-text-webpack-plugin:
        + 2 hidden modules
Child extract-text-webpack-plugin:
        + 2 hidden modules
Child extract-text-webpack-plugin:
        + 2 hidden modules
app-1.0.1.js		css-1.0.1.css.map	music.mp3
app-1.0.1.js.map	index.html
css-1.0.1.css		loader.css
getianyoudeMacBook-Pro:react-tetris-master ge$ 

Change name

Tetris is a copyrighted name. The company owning it defend it very aggressively. You are probably only days away from a "cease and desist" from their legal department.

下载到本地运行没有声音

我把源码下载到了本地运行docs文件夹下的index.html,额没有声音!

这个画面好有童年的味道哦,简单的快乐...

想引入到我们APP内

您好,我们想把您的这个俄罗斯方块引入到我们APP内,该怎样联系到您呢?已给您发过邮件了

npm start 运行报错

执行完npm install之后接着执行npm start会报错,输出如下:

-> % npm start

> [email protected] start /Users/zentorwie/Codes/Frontend/react-tetris
> webpack-dev-server --progress

 70% 1/1 build modules http://0.0.0.0:8080/
webpack result is served from /
content is served from ./server
 32% 3/8 build modulesThe react/require-extension rule is deprecated. Please use the import/extensions rule from eslint-plugin-import instead.
Hash: 98044a932f7444f61380
Version: webpack 1.14.0
Time: 3764ms
     Asset     Size  Chunks             Chunk Names
    app.js   669 kB       0  [emitted]  main
 music.mp3  54.4 kB          [emitted]
loader.css   1.5 kB          [emitted]
chunk    {0} app.js (main) 226 kB [rendered]
    [0] multi main 52 bytes {0} [built] [1 error]
    [1] (webpack)-dev-server/client?http://0.0.0.0:8080 3.97 kB {0} [built]
    [2] ./~/url/url.js 23.3 kB {0} [built]
    [3] ./~/url/~/punycode/punycode.js 14.6 kB {0} [built]
    [4] (webpack)/buildin/module.js 251 bytes {0} [built]
    [5] ./~/url/util.js 314 bytes {0} [built]
    [6] ./~/querystring/index.js 127 bytes {0} [built]
    [7] ./~/querystring/decode.js 2.4 kB {0} [built]
    [8] ./~/querystring/encode.js 2.09 kB {0} [built]
    [9] ./~/strip-ansi/index.js 161 bytes {0} [built]
   [10] ./~/ansi-regex/index.js 135 bytes {0} [built]
   [11] (webpack)-dev-server/client/socket.js 856 bytes {0} [built]
   [12] ./~/sockjs-client/lib/entry.js 244 bytes {0} [built]
   [13] ./~/sockjs-client/lib/transport-list.js 613 bytes {0} [built]
   [14] ./~/sockjs-client/lib/transport/websocket.js 2.71 kB {0} [built]
   [15] ./~/node-libs-browser/~/process/browser.js 5.3 kB {0} [built]
   [16] ./~/sockjs-client/lib/utils/event.js 2 kB {0} [built]
   [17] ./~/sockjs-client/lib/utils/random.js 746 bytes {0} [built]
   [18] ./~/sockjs-client/lib/utils/browser-crypto.js 438 bytes {0} [built]
   [19] ./~/sockjs-client/lib/utils/url.js 975 bytes {0} [built]
   [20] ./~/url-parse/index.js 9.92 kB {0} [built]
   [21] ./~/requires-port/index.js 753 bytes {0} [built]
   [22] ./~/url-parse/lolcation.js 1.58 kB {0} [built]
   [23] ./~/querystringify/index.js 1.3 kB {0} [built]
   [24] ./~/debug/src/browser.js 4.68 kB {0} [built]
   [25] ./~/debug/src/debug.js 4.31 kB {0} [built]
   [26] ./~/ms/index.js 2.72 kB {0} [built]
   [27] ./~/inherits/inherits_browser.js 672 bytes {0} [built]
   [28] ./~/sockjs-client/lib/event/emitter.js 1.27 kB {0} [built]
   [29] ./~/sockjs-client/lib/event/eventtarget.js 1.85 kB {0} [built]
   [30] ./~/sockjs-client/lib/transport/browser/websocket.js 172 bytes {0} [built]
   [31] ./~/sockjs-client/lib/transport/xhr-streaming.js 1.25 kB {0} [built]
   [32] ./~/sockjs-client/lib/transport/lib/ajax-based.js 1.31 kB {0} [built]
   [33] ./~/sockjs-client/lib/transport/lib/sender-receiver.js 1.15 kB {0} [built]
   [34] ./~/sockjs-client/lib/transport/lib/buffered-sender.js 2.3 kB {0} [built]
   [35] ./~/sockjs-client/lib/transport/lib/polling.js 1.32 kB {0} [built]
   [36] ./~/sockjs-client/lib/transport/receiver/xhr.js 1.58 kB {0} [built]
   [37] ./~/sockjs-client/lib/transport/sender/xhr-cors.js 343 bytes {0} [built]
   [38] ./~/sockjs-client/lib/transport/browser/abstract-xhr.js 4.8 kB {0} [built]
   [39] ./~/sockjs-client/lib/transport/sender/xhr-local.js 352 bytes {0} [built]
   [40] ./~/sockjs-client/lib/utils/browser.js 560 bytes {0} [built]
   [41] ./~/sockjs-client/lib/transport/xdr-streaming.js 984 bytes {0} [built]
   [42] ./~/sockjs-client/lib/transport/sender/xdr.js 2.46 kB {0} [built]
   [43] ./~/sockjs-client/lib/transport/eventsource.js 766 bytes {0} [built]
   [44] ./~/sockjs-client/lib/transport/receiver/eventsource.js 1.58 kB {0} [built]
   [45] ./~/sockjs-client/lib/transport/browser/eventsource.js 37 bytes {0} [built]
   [46] ./~/sockjs-client/lib/transport/lib/iframe-wrap.js 981 bytes {0} [built]
   [47] ./~/sockjs-client/lib/transport/iframe.js 3.83 kB {0} [built]
   [48] ./~/json3/lib/json3.js 43.3 kB {0} [built]
   [49] (webpack)/buildin/amd-options.js 43 bytes {0} [built]
   [50] ./~/sockjs-client/lib/version.js 26 bytes {0} [built]
   [51] ./~/sockjs-client/lib/utils/iframe.js 5.06 kB {0} [built]
   [52] ./~/sockjs-client/lib/utils/object.js 532 bytes {0} [built]
   [53] ./~/sockjs-client/lib/transport/htmlfile.js 710 bytes {0} [built]
   [54] ./~/sockjs-client/lib/transport/receiver/htmlfile.js 2.2 kB {0} [built]
   [55] ./~/sockjs-client/lib/transport/xhr-polling.js 894 bytes {0} [built]
   [56] ./~/sockjs-client/lib/transport/xdr-polling.js 712 bytes {0} [built]
   [57] ./~/sockjs-client/lib/transport/jsonp-polling.js 1.02 kB {0} [built]
   [58] ./~/sockjs-client/lib/transport/receiver/jsonp.js 5.57 kB {0} [built]
   [59] ./~/sockjs-client/lib/transport/sender/jsonp.js 2.46 kB {0} [built]
   [60] ./~/sockjs-client/lib/main.js 11.9 kB {0} [built]
   [61] ./~/sockjs-client/lib/shims.js 18.2 kB {0} [built]
   [62] ./~/sockjs-client/lib/utils/escape.js 2.31 kB {0} [built]
   [63] ./~/sockjs-client/lib/utils/transport.js 1.35 kB {0} [built]
   [64] ./~/sockjs-client/lib/utils/log.js 450 bytes {0} [built]
   [65] ./~/sockjs-client/lib/event/event.js 477 bytes {0} [built]
   [66] ./~/sockjs-client/lib/location.js 177 bytes {0} [built]
   [67] ./~/sockjs-client/lib/event/close.js 295 bytes {0} [built]
   [68] ./~/sockjs-client/lib/event/trans-message.js 292 bytes {0} [built]
   [69] ./~/sockjs-client/lib/info-receiver.js 2.22 kB {0} [built]
   [70] ./~/sockjs-client/lib/transport/sender/xhr-fake.js 456 bytes {0} [built]
   [71] ./~/sockjs-client/lib/info-iframe.js 1.52 kB {0} [built]
   [72] ./~/sockjs-client/lib/info-iframe-receiver.js 791 bytes {0} [built]
   [73] ./~/sockjs-client/lib/info-ajax.js 1.03 kB {0} [built]
   [74] ./~/sockjs-client/lib/iframe-bootstrap.js 2.9 kB {0} [built]
   [75] ./~/sockjs-client/lib/facade.js 723 bytes {0} [built]
   [76] (webpack)/hot/dev-server.js 1.85 kB {0} [built]
   [77] (webpack)/hot/log-apply-result.js 813 bytes {0} [built]

ERROR in ./src/index.js
Module build failed: ReferenceError: [BABEL] /Users/zentorwie/Codes/Frontend/react-tetris/src/index.js: Unknown option: /Users/zentorwie/Codes/Frontend/react-tetris/node_modules/react/react.js.Children. Check out http://babeljs.io/docs/usage/options/ for more information about options.

A common cause of this error is the presence of a configuration options object without the corresponding preset name. Example:

Invalid:
  `{ presets: [{option: value}] }`
Valid:
  `{ presets: [['presetName', {option: value}]] }`

For more detailed information on preset configuration, please see http://babeljs.io/docs/plugins/#pluginpresets-options. (While processing preset: "/Users/zentorwie/Codes/Frontend/react-tetris/node_modules/react/react.js")
    at Logger.error (/Users/zentorwie/Codes/Frontend/react-tetris/node_modules/babel-core/lib/transformation/file/logger.js:41:11)
    at OptionManager.mergeOptions (/Users/zentorwie/Codes/Frontend/react-tetris/node_modules/babel-core/lib/transformation/file/options/option-manager.js:221:20)
    at /Users/zentorwie/Codes/Frontend/react-tetris/node_modules/babel-core/lib/transformation/file/options/option-manager.js:260:14
    at /Users/zentorwie/Codes/Frontend/react-tetris/node_modules/babel-core/lib/transformation/file/options/option-manager.js:329:22
    at Array.map (native)
    at OptionManager.resolvePresets (/Users/zentorwie/Codes/Frontend/react-tetris/node_modules/babel-core/lib/transformation/file/options/option-manager.js:270:20)
    at OptionManager.mergePresets (/Users/zentorwie/Codes/Frontend/react-tetris/node_modules/babel-core/lib/transformation/file/options/option-manager.js:259:10)
    at OptionManager.mergeOptions (/Users/zentorwie/Codes/Frontend/react-tetris/node_modules/babel-core/lib/transformation/file/options/option-manager.js:244:14)
    at OptionManager.init (/Users/zentorwie/Codes/Frontend/react-tetris/node_modules/babel-core/lib/transformation/file/options/option-manager.js:374:12)
    at File.initOptions (/Users/zentorwie/Codes/Frontend/react-tetris/node_modules/babel-core/lib/transformation/file/index.js:216:65)
    at new File (/Users/zentorwie/Codes/Frontend/react-tetris/node_modules/babel-core/lib/transformation/file/index.js:139:24)
    at Pipeline.transform (/Users/zentorwie/Codes/Frontend/react-tetris/node_modules/babel-core/lib/transformation/pipeline.js:46:16)
    at transpile (/Users/zentorwie/Codes/Frontend/react-tetris/node_modules/babel-loader/lib/index.js:38:20)
    at Object.module.exports (/Users/zentorwie/Codes/Frontend/react-tetris/node_modules/babel-loader/lib/index.js:133:12)
 @ multi main
webpack: bundle is now VALID.

环境信息:

OS: OS X 10.11
npm version的输出:
{ 'react-tetris': '1.0.0',
  npm: '3.10.9',
  ares: '1.10.1-DEV',
  http_parser: '2.7.0',
  icu: '57.1',
  modules: '48',
  node: '6.9.2',
  openssl: '1.0.2j',
  uv: '1.9.1',
  v8: '5.1.281.88',
  zlib: '1.2.8' }

Customize handheld color!

The idea is simple. building a component on the right side where users can change the color of the handheld.

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.