关于浏览器直接使用 ES6 的一些简单介绍

@LoeiFy 2018-05-12 05:45:36发表于 LoeiFy/Recordum JavascriptReactwebpack

在浏览器端直接运行 ES6 代码通常可以这样做

首先引入 babel-standalone

<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>

然后就可以直接写 ES6 代码了

<script type="text/babel">
class A {
  constructor() {
    this.a = 0
  }
  log() {
    console.log(this.a)
  }
}
</script>

当然也可以直接写 React JSX 相关

<!-- 需要引入 React 相关 -->
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

<script type="text/babel">
ReactDOM.render(
  <div>
    <h1>JSX</h1>
  </div>
, document.body)
</script>

还可以文件引入方式来写 ES6 代码

<script type="text/babel" src="/main.js"></script>

通常要写一些更高级的 js 特性,还需要添加 babel-standalone 一些插件,例如需要支持 class properties 这时候需要这样做

<script type="text/babel" data-plugins="transform-class-properties">
class Bork {
  instanceProperty = "bork";
  boundFunction = () => {
    return this.instanceProperty;
  }
}
</script>

如果需要 import 其他模块,还需要引入 es2015-modules-umd 插件。插件列表可以参考这里:https://babeljs.io/docs/plugins/

<script type="text/babel" data-plugins="transform-class-properties transform-es2015-modules-umd">
import { Breadcrumb } from 'antd';

ReactDOM.render(
  <Breadcrumb>
    <Breadcrumb.Item>Home</Breadcrumb.Item>
    <Breadcrumb.Item><a href="">Application Center</a></Breadcrumb.Item>
    <Breadcrumb.Item><a href="">Application List</a></Breadcrumb.Item>
    <Breadcrumb.Item>An Application</Breadcrumb.Item>
  </Breadcrumb>
, mountNode);
</script>

接下来写一些稍微 正式 的代码

<!-- 同样引入 React 相关 -->
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

<script type="text/babel" data-plugins="transform-class-properties transform-es2015-modules-umd">
import React, { Component } from 'react'
import ReactDOM from 'react-dom'

class Editor extends Component {
// ...
}

class Main extends Component {
  // ...
  render() {
    return (
      <div>
        <Editor {...this.props} />
      </div>
    )
  }
}
</script>

不出意外,console 会得到一些类似错误提示

Uncaught TypeError: Cannot read property 'Component' of undefined

通过测试试验,出现这样提示是因为引入的模块 umd 打包出来不符合标准,根据 umd 标准,react 的 libraryName 应该为 react,而不是 React。同样 react-dom 的 libraryName 应该为 reactDom 而不是 ReactDOM

所以解决办法也很简单,加上对应 libraryName 的定义即可

<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

<script>
window['react'] = window.React
window['reactDom'] = window.ReactDOM
</script>

<script type="text/babel" data-plugins="transform-class-properties transform-es2015-modules-umd">
// ...
</script>

同样,当我们需要引入 react-router 时候,同样也需要做对应处理

window['reactRouterDom'] = window.ReactRouterDOM
window['reactRouter'] = window.ReactRouter

最后,总结一下浏览器写 ES6 + React 模板

<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-router-dom@4.2.2/umd/react-router-dom.min.js"></script>

<script>
window['react'] = window.React
window['reactDom'] = window.ReactDOM
window['reactRouterDom'] = window.ReactRouterDOM
</script>

<script type="text/babel" data-plugins="transform-class-properties transform-es2015-modules-umd">
// ...
</script>

可能会有疑问:为什么要在浏览器做这样事情,为什么不直接用 webpack 之类的。这里说明一下,正常情况下我们的 webapp 是不应该这样子做,应该预先打包后发布。所以这种浏览器处理方式的使用场景是在展示,测试一些小 demo 时候使用的