潮州网页设计:用同构应用程序对未来做出反应

2019.08.12 mf_web

185

软件工程中的事情经常发生。特别是网络开始于向客户端提供内容的服务器。最近,随着AngularJS和Ember等现代Web框架的创建,我们已经看到了在客户端上进行渲染并仅使用服务器进行API的推动。我们现在看到可能的回归,或者更确切地说,两种架构的结合。潮州网页设计

什么是反应?

React是一个用于构建用户界面的JavaScript库。

据官方网站报道。这是一种创建可重用前端组件的方法。简单明了,这就是React的目标。

是什么让它与众不同?

React很快就在JavaScript社区中大受欢迎。它的成功有很多原因。一个是Facebook创建并使用它。这意味着Facebook的许多开发人员都在使用它,修复错误,建议功能等等。

用同构应用程序对未来做出反应

其迅速普及的另一个原因是它与众不同。它与AngularJS,Backbone.js,Ember,Knockout以及过去几年JavaScript革命期间出现的其他任何流行的MV * JavaScript框架不同。这些其他框架中的大多数都基于对DOM的双向绑定以及基于事件更新它的想法。它们都需要DOM存在 ; 因此,当您使用其中一个框架并且希望在服务器上呈现任何标记时,您必须使用PhantomJS之类的东西

虚拟DOM

React通常被描述为MVC应用程序中的“V”。但它与其他MV *框架完全不同。它与Handlebars,Underscore模板和AngularJS模板不同。React运行在“虚拟DOM”的概念上。它在内存中维护这个虚拟DOM,每当对DOM进行更改时,React都会对更改进行快速区分,将它们全部批量更新为一个更新并点击实际DOM同时出现。

这有很大的影响。首先,在性能方面,您不会像许多其他JavaScript框架那样经常进行DOM更新。DOM是前端性能的巨大瓶颈。第二个分支是React可以像在客户端上一样轻松地在服务器上呈现。

React公开了一个名为的方法React.renderToString()。此方法使您可以传入一个组件,该组件将呈现它及其使用的任何子组件,并简单地返回一个字符串。然后,您可以获取该HTML字符串,然后将其发送到客户端。

这些组件使用名为JSX的语法构建。起初,JSX看起来像一个奇怪的HTML-JavaScript混合:

var HelloWorld = React.createClass({
  displayName: "HelloWorld",
  render() {
    return (
      <h1>Hello {this.props.message}</h1>
    );
  }});React.render(<HelloWorld message="world" />, document.body);
复制

你这个做什么.jsx格式之通过(或“transpile”) ,webpack,grunt,gulp选择或您的“渲染”,然后吐出的JavaScript看起来像这样:

var HelloWorld = React.createClass({
  displayName: "HelloWorld",
  render: function() {
    return (
      React.createElement("h1", null, "Hello ", this.props.message)
    );
  }});React.render(React.createElement(HelloWorld, {message: "world"}), document.body);
复制

这就是我们的HelloWorld.jsx组件所传达的 - 只不过是简单的JavaScript。有些人认为这是通过将JavaScript与HTML混合而违反关注点的分离。起初,这似乎正是我们正在做的事情。但是,在使用React一段时间之后,您意识到组件标记与JavaScript的紧密接近使您可以更快地开发并更长时间地维护它,因为您不会在HTML和JavaScript文件之间来回跳转。给定组件的所有代码都存在于一个地方。

React.render将您的<HelloWorld>组件附加到body。当然,那可能是那里的任何元素。这会导致组件的render方法触发,并将结果添加到<body>标记内的DOM中。

使用React组件,无论您将哪些内容作为属性传递 - 比如说<HelloWorld message=“world” />- 您都可以访问组件中的内容this.props。所以,在<HelloWorld>组件中,this.props.message是world。另外,请仔细查看代码的JSX部分:

return (
  <h1>Hello {this.props.message}</h1>);
复制

您首先要注意到必须将HTML包装在括号中。其次,this.props.message用括号括起来。大括号使您可以访问组件this。

每个组件还可以访问其“状态”。有了反应,每一个组件管理它的状态,几个简单的API方法,getState并且setState,以及getInitialState对于当组件首次加载。每当状态改变时,该render方法只是重新渲染组件。例如:

var Search = React.createClass({
  getInitialState() {
    return {
      search: ""
    };
  },
  render() {
    return (
      <div className="search-component">
        <input type="text" onChange={this.changeSearch} />
        <span>You are searching for: {this.state.search}</span>
      </div>
    );
  },
  changeSearch(event) {
    var text = event.target.value;
    this.setState({
      search: text    });
  }});React.render(<Search />, document.body);
复制

在此示例中,getInitialState函数只返回包含组件初始状态的对象文字。

该render函数为我们的元素返回JSX - 所以,a input和a span都包含在一个div。请记住,JSX中只能返回一个元素作为父元素。换句话说,你不能回来<div></div><div></div>; 你只能返回一个有多个孩子的元素。

请注意onChange={this.changeSearch}。这告诉组件changeSearch在更改事件触发输入时触发该函数。

该changeSearch函数接收event来自DOM事件的触发器,并可以获取输入的当前文本。然后,我们调用setState并传入文本。这导致render再次发射,并且{this.state.search}将反映新的变化。

React中的许多其他API都可以使用,但从高层次来看,我们上面所做的就像创建一个简单的React组件一样简单。

同构JavaScript

使用React,我们可以构建“同构”应用程序。

我·所以·mor·phic:“在形式和关系上相应或相似”

这已经成为2015年的流行语。基本上,它只是意味着我们可以在客户端和服务器上使用相同的代码。

这种方法有很多好处。

消除FOUC

使用AngularJS,Ember(现在)和SPA类型架构,当用户首次点击页面时,所有资产都必须下载。对于SPA应用程序,这可能需要一秒钟,而且现在大多数用户希望加载时间少于两秒。在加载内容时,页面将被取消。这被称为“无格式内容的闪光”(FOUC)。构建应用程序的同构方法的一个好处是,您可以获得在服务器上呈现的速度优势,并且您仍然可以在客户端上加载页面后呈现组件。

同构应用程序的工作不是取代传统的服务器API,而只是为了帮助消除FOUC并为用户提供他们越来越习惯的更好,更快的体验。

共享代码

一个很大的好处是能够在客户端和服务器上使用相同的代码。只需创建您的组件,它们就可以在两个地方工作。在大多数系统中,例如Rails,ASP.NET MVC,您通常会在服务器上拥有erb或cshtml视图进行渲染。然后,您必须拥有客户端模板,例如Handlebars或Hogan.js,它们通常会复制逻辑。使用React,相同的组件在两个地方都可以工作。

渐进式增强

服务器呈现允许您发送客户端显示网站所需的准系统HTML。然后,您可以增强体验或在客户端中呈现更多组件。

在非洲的翻盖手机上为用户提供良好的体验,以及使用带有Retina显示屏的15英寸MacBook Pro的用户增强体验,连接到新的4K显示器,通常是一项相当繁琐的工作。

React超越了共享组件。当您在服务器上呈现React组件并将HTML发送到客户端时,客户端上的React会注意到HTML已经存在。它只是将事件处理程序附加到现有元素上,您就可以开始了。

这意味着您只能下载呈现页面所需的HTML; 然后,可以根据需要将任何其他内容拉入并在客户端上呈现。通过服务器呈现可以获得快速页面加载的好处,并且可以重用组件。

创建同构Express应用程序

Express是最受欢迎的Node.js Web服务器之一。启动并运行React with Express非常简单。

将React渲染添加到Express应用程序只需几个步骤。首先,添加node-jsx和react将项目与此:

npm install node-jsx --savenpm install react --save
复制

让我们app.jsx在public/javascripts/components目录中创建一个基本文件,这需要我们之前的Search组件:

var React = require("react"),
  Search = require("./search");var App = React.createClass({
  render() {
    return (
      <Search />
    );
  }});module.exports = App;
复制

在这里,我们要求react和我们的Search.jsx组件。在Apprender方法中,我们可以简单地使用组件<Search />。

然后,将以下内容添加到您计划使用React进行渲染的路由器中:

require("node-jsx").install({
  harmony: true,
  extension: ".jsx"});
复制

所有这一切都是允许我们实际使用require来抓取.jsx文件。否则,Node.js将不知道如何解析它们。该harmony选项允许使用ECMAScript 6样式的组件。

接下来,在组件中要求并将其传递给React.createFactory,这将返回一个可以调用以调用组件的函数:

var React = require("react"),
  App = React.createFactory(require("../public/javascripts/components/app")),
  express = require("express"),
  router = express.Router();
复制

然后,在路线中,只需调用React.renderToString并传递您的组件:

router.get("/", function(req, res) {
  var markup = React.renderToString(
    App()
  );
  res.render("index", {
    markup: markup  });});
复制

最后,在您的视图中,只需输出标记:

<body>
  <div id="content">
    {{{markup}}}
  </div></body>

这就是服务器代码。让我们来看看客户端需要什么。

的WebPack

Webpack是一个JavaScript捆绑器。它将您的所有静态资产(包括JavaScript,图像,CSS等)捆绑到一个文件中。它还使您能够通过不同类型的加载器处理文件。您可以使用CommonJS或AMD模块语法编写JavaScript。

对于React .jsx文件,您只需webpack.config稍微配置一下文件即可编译所有jsx组件。

Webpack入门很简单:

npm install webpack -g # Install webpack globallynpm install jsx-loader --save # Install the jsx loader for webpack

接下来,创建一个webpack.config.js文件。

var path = require("path");module.exports = [{
  context: path.join(__dirname, "public", "javascripts"),
  entry: "app",
  output: {
    path: path.join(__dirname, "public", "javascripts"),
    filename: "bundle.js"
  },
  module: {
    loaders: [
      { test: /\.jsx$/, loader: "jsx-loader?harmony"}
    ]
  },
  resolve: {
    // You can now require('file') instead of require('file.coffee')
    extensions: ["", ".js", ".jsx"],
    root: [path.join(__dirname, "public", "javascripts")],
    modulesDirectories: ["node_modules"]
  }}];
复制

让我们打破这个:

  • context 这是JavaScript文件的根目录。

  • entry这是require默认情况下将使用CommonJS 语法加载其他文件的主文件。

  • output这告诉Webpack输出一个包中的代码,路径为public/javascripts/bundle.js。

该module对象是您设置“加载器” 的对象。加载器只是让您测试文件扩展名,然后通过加载器传递该文件。许多加载器存在于CSS,Sass,HTML,CoffeeScript和JSX之类的东西中。在这里,我们只有一个,jsx-loader?harmony。您可以将选项作为“查询字符串”附加到加载程序的名称。在这里,?harmony我们可以在模块中使用ECMAScript 6语法。该test通知的WebPack通过任何文件,.jsx在年底jsx-loader。

在resolve我们看到一些其他选项。首先,extensions告诉Webpack在我们require提交文件时省略某些文件类型的扩展名。这让我们只做require(“./file”),而不是require(“./file.js”)。我们还要设置一个root,这只是我们需要文件的根源。最后,我们将允许Webpack node_modules使用该modulesDirectories选项从目录中提取模块。这使我们能够安装喜欢的事把手与npm install handlebars和简单require(“handlebars”),就像在一个Node.js的应用程序。

客户端代码

在public/javascripts/app.js,我们将需要App在Express中需要的相同组件:

var React = require("react"),
  App = React.createFactory(require("components/app"));if (typeof window !== "undefined") {
  window.onload = function() {
    React.render(App(), document.getElementById("content"));
  };}
复制

我们将检查我们是否在浏览器中typeof window !== “undefined”。然后,我们将附加到onload窗口的事件,我们将调用React.render并传入我们的App()。我们需要的第二个参数是要挂载的DOM元素。这需要与我们在服务器上呈现React标记的元素相同 - 在本例中为#content元素。

Search上面示例中的组件在服务器上呈现并传送到客户端。客户端React查看呈现的标记并仅附加事件处理程序!这意味着我们将在JavaScript加载时看到初始页面。

上面的所有代码都可以在GitHub上找到。

结论

Web架构肯定会经历周期。我们开始在服务器上渲染所有内容并将其发送到客户端。然后,JavaScript出现了,我们开始使用它进行简单的页面交互。在某些时候,JavaScript长大了,我们意识到它可以用来构建大型应用程序,这些应用程序在客户端上呈现所有内容,并使用服务器通过API检索数据。

在2015年,我们开始意识到我们拥有这些功能强大的服务器,拥有大量的内存和CPU,并且他们在为我们渲染内容方面做得非常好。Ť 他的同构的方法来构建应用程序可能只是给我们两全其美:利用两地的JavaScript,并通过发送下来的东西,他们可以快速查看,然后建立在与客户端JavaScript提供给用户良好的体验。

React是第一个确保能够实现此类行为的框架之一。Ember的开发人员也在研究同构风格的应用程序。看看这一切是如何运作的肯定会很有趣!

潮州网页设计

最新案例

寒枫总监

来电咨询

400-6065-301

微信咨询

寒枫总监

TOP