我正在使用scalajs插件,并定义了我的build.sbt,因此:
enablePlugins(ScalaJSBundlerPlugin)
name := "Reproduce"
scalaVersion := "2.12.8"
npmDependencies in Compile += "bootstrap" -> "3.4.1"但是,当我运行"sbt::webpack“时,在生成的-fastOptJS bundle.js文件中没有引用。
难道不应该包括引导吗?
发布于 2019-07-02 18:21:00
我只是遇到了同样的问题,在任何搜索中都找不到解决办法。希望这个(相当长的)答案能帮助别人避免一些痛苦。
我认为有三个问题要解决,以使用作为npm模块捆绑的引导库(即。使用scalajs通过npmDependencies参数将其打包)。
1)将引导程序库放入包中。
2)将jQuery符号作为全局变量提供给Bootstrap。
3)在运行时加载引导带。
1)将模块放入包
这是你在问题中提到的第一个问题。将bootstrap添加到npmDependencies并不足以使scalajs将您的模块包含在包中。除此之外,在scala代码的某个地方,您必须有一个JSImport("library_name",.)语句。这告诉,您实际上正在使用库,它需要包含在包中。您可以阅读更多关于JSImport 这里的详细信息。我觉得这个描述有点模糊。这里回答了我在@Julien的一个问题,我发现这个问题更有帮助。在我的代码中,JSImport需求包括在下面的第3部分中。注意,您还需要为jquery提供一个JSImport,以确保它也包含在包中,因为Bootstrap依赖于它,并且需要将jquery添加到npmDependencies中。
2)创建javascript全局变量
这是解决方案中最复杂的部分。
在我的应用程序中,我会在浏览器控制台中得到一个错误,比如jQuery is not defined。我花了一段时间才确定这是在Bootstrap库内部造成的。通过定义全局变量jquery,引导库依赖于jQuery。不幸的是,仅仅通过npmDependencies和JSImport在包中包含jquery是不够的。您必须告诉创建jQuery全局变量,并将其导出到包中的所有模块。
解决方案 @Julien指的是要遵循的一般配方,但我相信它有一个缺陷。由于库名和全局变量名是相同的,因此bug不会在它们的示例中造成问题。问题是modName和globalModules[modName]是在importRule的返回线上交换的。
下面是我的scalajs的common.webpack.config.js文件,指示它生成一个全局变量jQuery并导出它。注意,我所做的唯一更改是将jquery: "jQuery"放在globalModules中,并在importRule的返回线上交换modName和globalModules[modName]的位置。否则,我只是以身作则。还需要其他配置文件和对build.sbt的更改)。
var globalModules = {
jquery: "jQuery"
};
const importRule = {
// Force require global modules
test: /.*-(fast|full)opt\.js$/,
loader:
"imports-loader?" +
Object.keys(globalModules)
.map(function(modName) {
return globalModules[modName] + "=" + modName;
})
.join(",")
};
const exposeRules = Object.keys(globalModules).map(function(modName) {
// Expose global modules
return {
test: require.resolve(modName),
loader: "expose-loader?" + globalModules[modName]
};
});
const allRules = exposeRules.concat(importRule);
module.exports = {
performance: { hints: false },
module: {
rules: allRules
}
};3)在运行时加载模块
通常情况下,这不是你必须明确做的事情。但是,在Bootstrap (或任何扩展另一个js库的js库)的情况下,您可能不会直接通过facade调用库。很可能您将使用猴补模式。在本例中,jQuery对象被强制转换为Bootstrap对象,而不直接调用Bootstrap。通常,这将编译得很好,但在浏览器控制台中会出现运行时错误,类似于Uncaught TypeError: jq.modal is not a function。下面是如何定义jquery的引导扩展,以便在错误消息中理解jq和模态:
@js.native
trait BootstrapJQuery extends JQuery {
def modal(action: String): BootstrapJQuery = js.native
def modal(options: js.Any): BootstrapJQuery = js.native
}
implicit def jq2bootstrap(jq: JQuery): BootstrapJQuery = jq.asInstanceOf[BootstrapJQuery]解决方案是在调用隐式之前的某个时候对lib进行一些显式引用。
我就是这么做的。
private object BootstrapLib {
@js.native
@JSImport("bootstrap", Namespace)
object BootstrapModule extends js.Object
private lazy val dummy = BootstrapModule
def load() = dummy
}
BootstrapLib.load()它包含在一个对象中,该对象包含Bootstrap组件的所有包装器定义。这保证了在使用任何引导包装之前调用Bootstrap.load()。我喜欢这样,因为没有必要记住在任何包装工厂方法中显式地调用它。
发布于 2019-04-26 10:00:19
您必须实际使用该模块,否则webpack将不会将其包含在结果包中。如果您的模块应该从全局命名空间中使用,请遵循这个食谱。
https://stackoverflow.com/questions/55847489
复制相似问题