我有2个js
类,我需要同时在后端和前端上运行。为此,我写了这张支票(在module.exports
之前有一张类似的支票):
// in foo.js
class foo {
constructor(){...}
fooMethod(){...}
}
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined')
module.exports = foo;
else
window.foo = foo
// in bar.js
if (typeof require !== 'undefined' ){
var foo = require('./foo.js');
var baz = require('baz_module')
// note, baz is loaded from a cdn on the front-end.
// I wrote some extension functions here
}
// error still happens if I don't do anything here
baz.prototype.myFunction = function(){ ... }
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined')
module.exports = baz;
else
window.baz = baz
在index.html
<script src="http://cdn.com/baz"></script>
<script src="./path/to/foo.js"></script>
<script src="./path/to/bar.js"></script>
问题是当将此文件加载到前端时,出现错误:
Identifier 'foo' has already been declared
。这是有道理的,因为文件foo.js
已经运行。
我尝试交换浏览器加载文件的顺序(bar
之前的foo
),但是遇到相同的错误。 console.log(foo)
在undefined
中返回bar
,而不是预期的ReferenceError: foo is not defined
我的困惑是为什么var foo ...
行即使在if
语句为false的情况下也行?我的期望是var
声明应与脚本的其余部分内联运行
答案 0 :(得分:0)
var
声明被提升到if
块作用域之外。您在class foo
声明中遇到错误,抱怨foo
已被全局声明。
一种解决方案是仅对全局变量(即var
)使用function
(和var foo = class foo {…};
)。但是,imo真正的问题是,您根本使用的是全局变量,而不是某些模块系统。您应该将模块放在IIFE中,并让模块系统检查代码将IIFE返回值作为导出处理。或者更好的是,不要自己编写该校验代码,而是使用ES6模块语法并将其模块(例如,使用Rollup进行转换)到UMD format中,这正是为您完成的。