Reactjs+BootStrap开发自制编程语言Monkey的编译器:创建简易的页面IDE

为了尽快上手React,我们先通过一个实际例子,增加你的感性认识。我们将使用React先构建一个简单的Monkey代码编译器,没有感性认识的知识讲解都是bullshit,就像你没摸过水就跟你讲解游泳理论一样。即使你对Reactjs的运用一无所知,通过亲手把代码敲一遍,并看到实践的效果,你内心也自动会对Reactjs有了较为深刻的认知。

首先你需要自行安装好node.js,React本身并不需要Node.js,但开发中需要的很多工具和模块需要Node.js的支持,特别是我们需要NodeJS的npm 模块安装工具。安装好NodeJS后,先运行以下命令:

npm install --global create-react-app

create-react-app 是通过npm模块发布的一个安装包,通过该工具,我们能快速创建一个reactjs项目。接着执行以下命令:

npm install --save react-bootstrap

上面的命令用来安装试用与react框架的boostrap UI控件库,我们将使用它来开发我们Monkey编程语言的IDE。完成上面的安装后,我们就可以创建第一个Reactjs项目了,运行以下命令:

create-react-app monkey_compiler

这个命令会在本地目录创建一个名为monkey_compiler的目录,它已经是一个可运行的reactjs项目,我们在此基础上通过修改或添加若干文件,就可以完成相应的React应用开发,避免大量繁琐的配置工作。接着我们执行:

cd monkey_compiler
npm start

上述命令执行后,命令会启动一个开发模式的服务器,同时会自动调用浏览器打开一个页面,页面指向本地地址http://localhost:3000, 基本情况如下图:

接下来,我们将进入MonKey语言IDE的开发,我们将利用reactjs组件化开发的特点,通过乐高式搭积木的方式,逐步开发出一个功能丰富的页面IDE出来,我们先为项目增加一个新的react组件。你可以把react组件想象成一块砖头,整个react最终项目想象成一座大楼,我们通过砖头间的排列组合就可以搭建出我们想象中的大楼,更重要的是,这些砖头可以重用,你可以在这里搭建‘央视大裤衩’,也可以用相应的砖头搭建‘悉尼歌剧院’,由此可见react框架通过组件化的方式构建项目的模式是相当灵活且强大的。

在生成的monkey-compiler项目中,有一个目录叫src/,该目录用于存放项目的所有代码文件,在开发过程中,我们只要关注src目录中的内容,打开其中的index.js,可见内容如下:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();

其中的App 就是一个组件,它被加载后,效果就是我们前面看到的那样。我们稍作修改,定义一个新组件,修改后代码如下:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import MonkeyCompilerIDE from './MonkeyCompilerIDE';
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(<MonkeyCompilerIDE />, document.getElementById('root'));
registerServiceWorker();

我们把App换成了MonkeyCompilerIDE,我们先把代码的具体含义放一放,先看看如何增加一个React组件,在src目录下创建一个新的代码文件叫MonkeyCompilerIDE.js,并在里面添加如下代码:

import React , {Component} from 'react'
import * as bootstrap from 'react-bootstrap'

class MonkeyCompilerIDE extends Component {
    constructor(props) {
        super(props)
    }

    render () {
        let textAreaStyle = {
            height: 480
        };
        return (
          <bootstrap.Panel header="Monkey Compiler" bsStyle="success">
            <bootstrap.FormGroup>
              <bootstrap.FormControl componentClass = "textarea" 
               style={textAreaStyle}
               placeholder="Enter your code" />
            </bootstrap.FormGroup>
            <bootstrap.Button bsStyle="danger">
              Lexing
            </bootstrap.Button>
          </bootstrap.Panel>
          );
    }
}

export default MonkeyCompilerIDE

由于我们使用到了boostrap控件库,因此需要从外部引用相关的css样式文件,回到根目录,进入public目录,打开index.html,在其头部添加如下代码:

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css">

代码解析一会再说,完成上面代码后,先通过命令npm start看看运行效果:

这就是我们想要的Monkey编程语言开发所用的IDE,相当于Visual Studio或Eclipse,当然现在看起来它太简陋,我们后续会慢慢增强其功能。在文本框中键入Monkey 代码,点击下面按钮,我们就可以开始编译原理算法中的第一步:词法解析,这是我们后续章节要详细讲解的内容。回过头来,我们先解析一下刚完成的组件代码。

你或许可以感觉到,我们用来开发组件的代码不像是前端开发常用的javascript,组件通过class关键字来定义,而且用constructor函数作为类的初始化函数,这些代码看起来似乎与常用的java语言很相像了。这些代码遵循的标准叫ES6,是最新版的js代码语法格式,实际上当前主流浏览器并不支持这种格式代码的解析和执行,但为何他们仍然能运行在各大浏览器中呢?这是因为在Reactjs框架中内嵌了一个小型编译器叫Babel,它会把上面代码编译成浏览器能够解析并执行的常用E5标准的javascript代码,由此可见,掌握编译原理的重要性可见一般了吧!

在index.js中,我们使用import将新组件导入,以便替代原有的App组件。在MonkeyCompilerIDE.js中,第一行我们从react库中引入React和Component两个组件:

import React , {Component} from 'react'
import * as bootstrap from 'react-bootstrap'

第二行我们把react-bootstrap组件库中所有组件全部加载进来,并给予一个统称叫bootstrap,如果我想使用其中的一个组件例如Button,(上面左下角的红色按钮就是由Button组件创建的),那么我们可以通过bootstrap.Button来引用,这跟我们很类似与从一个类中引用它的公有成员变量。

Component组件是所以组件的基类,如果你熟悉java的话,该组件相当于java所有类的父类Object。因此MonKeyCompilerIDE组件的父组件就是Component。在React出现之处,组件的创建方法是通过调用React.createClass来创建组件,现在网上或一些书籍对React的讲解还是基于这种办法,我们必须意识到,这种办法是过时的办法。这两种方式的差异显示出React框架在开发方法论上的显著进化,我们现在使用的是类似于java那样面向对象的开发方式,而React.createClass这种创建组件的方式其实是类似于C语言那样的,面向过程的开发方式。

在上面的代码中我们导入了Component类有被使用到,但导入的React组件却没有被使用到,你可以尝试把第一行中的React给删除然后再加载页面,你就可以看到错误信息:’React’ must be in scope when using JSX。

这里的JSX是一个比较抽象的概念,React的初学者很容易被这个概念搞得糊里糊涂,就像C语言的初学者总会被‘指针’搞得二和尚摸不在头脑一样。什么是JSX呢,在render()函数中,我们通过return返回了一堆类似HTML代码似的东西:

<bootstrap.Panel header="Monkey Compiler" bsStyle="success">
   <bootstrap.FormGroup>
      <bootstrap.FormControl componentClass = "textarea" 
      style={textAreaStyle}
      placeholder="Enter your code" />
         </bootstrap.FormGroup>
            <bootstrap.Button bsStyle="danger">
              Lexing
            </bootstrap.Button>
</bootstrap.Panel>

是的!上面这坨看似与HTML代码非常类似的代码块就叫JSX.它们格式跟HTML很像,但他们不是HTML, 因为它其中包含了HTML规范没有的标签,例如bootstrap.Panel, 其实<>这对尖括号中包含的东西都叫组件而不是标签,由于JSX的形式与HTML实在太像了,所以初学者对它很容易感觉迷茫和困惑。

所谓JSX,它本质是javascript语法的扩展,也就是javascript extension。JSX中,JS代表javascript, X代表 eXtension. 上面那一坨看似HTML的代码其实是以HTML标签化形式来编写的javascript代码,首先要注意上面那坨代码中,有很多元素是HTML规范中没有的。

在React创建之初,人们对这种把javascript代码以HTML标签似来写的方式非常反感。因为这实在太容易引起认知混乱了。但是经过一段时间后,业界发现这种办法很实用。因为原来前端开发的基本思路是,用HTML来表示内容,用CSS来表示样式,用Javascript来定义交互行为,这是三种不同的语言,三种不同的设计逻辑,并且它们往往分布在不同的文件里,这就使得设计逻辑分成了多个不同的部分和层次,因此会带来项目理解和管理上的很多麻烦。

一个组件实际上是一个逻辑上有高度耦合性的独立性个体。如果按照原有方式,那意味着需要把一个原则上不可分的个体分成了三部分(HTML,CSS,Javascript)。既然是一个像原子一样不可再分的单元,那么设计上就应该把所有逻辑整合在一起。我们看到,在render函数中,我们还定义了一个textAreaStyle的对象,不难看出,它实际上承担了原来CSS的作用,也就是说,在JSX中,我们可以统一用javascript语言来代替原来需要用HTML和CSS来实现的功能,于是这样,原来分开三部分的设计逻辑在这里就统一起来了。

JSX是reactjs前端开发的核心功能所在,对初学者而言,它不好理解,但只要随着我们项目的深入,练习多了后,你慢慢的会掌握和消化它。下一节我们将在本节的基础上,进入代码编译的第一步:词法解析。

原文发布于微信公众号 - Coding迪斯尼(gh_c9f933e7765d)

原文发表时间:2017-11-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏九彩拼盘的叨叨叨

耗时函数被短时间频繁调用时,防浏览器卡死的方法

耗时函数如果在短时间内被频繁调用,如果不做合适的处理,会导致浏览器卡死(无响应),严重影响用户体验。

803
来自专栏司想君

React编程思想

能够按照构建的方式来思考web app的实现,是React众多优点之一。在这篇文章中,我们将引导你进行使用React构建可搜索产品数据表的思考过程。

5165
来自专栏华仔的技术笔记

Xcode 7 自动测试XCTestCase

3977
来自专栏weixuqin 的专栏

利用 pyspider 框架抓取猫途鹰酒店信息

4877
来自专栏贾鹏辉的技术专栏@CrazyCodeBoy

React Native 每日一学(Learn a little every day)

本文出自《React Native学习笔记》系列文章。 每天一个知识点(技巧,经验,填坑日记等),每天学一点,离大神近一点。 汇聚知识,分享精华。 如果你是一...

3899
来自专栏华仔的技术笔记

React Native 初探

3676
来自专栏司想君

React编程思想

在我们团队看来,React是使用JavaScript构建大型、快速的Web apps的首选方式。它已经在Facebook和Instagram项目中,表现出了非常...

4099
来自专栏杂七杂八

实现登录框

今天课程要求实现百度的登录框功能,晚上花费了两个小时终于搞定,直接上代码 <!DOCTYPE html> <html lang="en"> <head> ...

3746
来自专栏互联网杂技

Angular 1 vs. Angular 2 深度比较

AngularJS 2 尽管还在Alpha阶段,但主要功能和文档已经发布。让我我们了解下Angular 1 和 2 的区别,以及新的设计目标将如何实现。 Ang...

34010
来自专栏企鹅号快讯

微信小程序电商实战-首页(上)

上一篇:微信小程序电商实战-入门篇 嗨,大家好!经过近两周的精心准备终于开始微信小程序电商实战之路喽。那么最终会做成什么样呢?好了,不啰嗦了 我们先看首页长什么...

3777

扫码关注云+社区

领取腾讯云代金券