好的,我正在使用 ES6 和 ReactJS,import React from "react";
为了让它们工作,你应该做一些包,但其他包,那么,我应该<script src="/semantic/dist/semantic.min.js"></script>
在index.html
什么情况下应用一个或另一个?
如何知道何时导入包或将其粘贴到 index.html
一般来说,有两种类型的module。ES6 和非 ES6。如果你想在 ES6 中使用非 ES6 module,你可以尝试以下方法之一:
- 使用 CommonJS 编译(例如通过 npm 使用 jQuery 作为 CommonJS)
- 使用 SystemJS 加载以允许 ES6 与 CommonJS、AMD 和全局变量一起使用
如果你不想这样做,你可以尝试在 HTML 中导入非 ES6 脚本。在这种情况下,你不会做类似的事情
import $ from 'jquery';
所以简而言之,如果你想使用非 ES6 module而不用 CommonJS 编译或者如果它不能通过 npm 使用,你可以使用 HTML 导入而不是 ES6 导入
我在以下情况下遇到了这个问题:我想在我为本地index.html
文件编写的脚本中使用 react 和 react-dom api 。我可以<script src="react-cdn-url"></script>
在<head>
of 中放置一个标签index.html
,但我更喜欢在我的本地系统上使用 api。所以我wget react-cdn-url
看看我是否可以导入它。我在控制台上遇到一些错误,所以我查看了react.js
我现在拥有的文件并看到以下几行:
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.React = factory());
}(this, (function () { 'use strict';
...
})));
一旦我破译了这一点,我应该能够使我的react api“可导入”。所以让我们一点一点地把它拆开。第一个构造:
(function (global,factory){}(this,(function() {...})));
起初这有点令人困惑,所以首先看一下表达式:(function (params){}(args));
this 的目的是创建一个未命名的函数,该函数采用 paramaters params
,然后立即使用 arguments 调用它arg
。将此与;function (params){}(args);
. 这不是有效的 javascript,如果你在 node 中尝试它会破坏解析器,如果你在 firefox 控制台中这样做你会得到错误:SyntaxError: function statement requires a name。原因是这是一个不完整的句法结构。Javascript 语法允许您编写没有绑定名称的函数定义,但这仅在表达式中有意义. 将函数定义括在括号中会导致对其进行评估。将所有这些放在一起,我们有一个未命名的函数被调用参数this
和(function(){})
(另一个未命名的函数)。 this
将是任何本地上下文,并且未命名的函数对应factory
于“顶级”匿名函数中的参数。考虑以下三行:
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.React = factory());
这些检查是否正在从节点导入此module,如果是,则导出factory
函数的结果。如果它是由 require.js 导入的,它会“定义”factory
函数,如果这两者都没有,则结果factory
在全局对象中被命名为“React”。最后一种情况适用于通过<script>
标签“导入”库时。
但是,如果您尝试,这些情况都不是真正适用的es6 import
。为了使import
工作如愿,我们将只导出工厂函数,然后在导入脚本中调用它。为什么不直接调用工厂函数并将其分配给导出的名称?因为您需要将这个工厂的结果传递给react-dom的工厂。一般来说,沿着这条路还有很多问题在继续,最终最好是解决某种依赖管理器,但现在我们继续玩。
let ReactFactory;
export default ReactFactory = function () { 'use strict';
...
}
我对 react-dom 文件做同样的事情,改变这些行:
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react')) :
typeof define === 'function' && define.amd ? define(['react'], factory) :
(global.ReactDOM = factory(global.React));
}(this, (function (React) { 'use strict';
...
})));
进入:
let ReactDOMFactory;
export default ReactDOMFactory = function (React) { 'use strict';
...
}
注意,这次工厂函数有参数React
。我看到了几行:
if (!React) {
{
throw Error("ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM.");
}
}
从这里我得到提示,我需要React
从我的第一个工厂创建我的对象并将它传递到ReactDOMFactory
. 总而言之,我将以下几行放在我的script.js
文件中:
import ReactFactory from '/path-to-modified/react.js';
import ReactDOMFactory from '/path-to-modified/react-dom.js';
let React = ReactFactory();
let ReactDOM = ReactDOMFactory(React);
当然,哪里path-to-modified
是修改后的 api 文件的路径,瞧!现在它工作得很好。