Twitter bootstrap 如何在scalajs bundler中包含引导

Twitter bootstrap 如何在scalajs bundler中包含引导,twitter-bootstrap,scalajs-bundler,Twitter Bootstrap,Scalajs Bundler,我使用的是scalajs bundler插件,因此定义了我的build.sbt: enablePlugins(ScalaJSBundlerPlugin) name := "Reproduce" scalaVersion := "2.12.8" npmDependencies in Compile += "bootstrap" -> "3.4.1" 但是,当我运行“sbt fastOptJS::webpack”时,生成的-fastopt-bundle.js文件中没有对引导的引用 不应该

我使用的是scalajs bundler插件,因此定义了我的build.sbt:

enablePlugins(ScalaJSBundlerPlugin)

name := "Reproduce"
scalaVersion := "2.12.8"

npmDependencies in Compile += "bootstrap" -> "3.4.1"
但是,当我运行“sbt fastOptJS::webpack”时,生成的-fastopt-bundle.js文件中没有对引导的引用


不应该包括引导吗?

您必须实际使用该模块,否则webpack不会将其包括在生成的捆绑包中。
如果您的模块应该从全局名称空间使用,请遵循。

我刚刚遇到了完全相同的问题,在任何搜索中都无法找到解决方案。希望这个(相当长的)答案能帮助其他人避免一些痛苦

我认为要将Bootstrap lib绑定为npm模块(即使用scalajs bundler通过npmDependencies参数对其进行打包),需要解决3个问题

1) 将引导程序库放入捆绑包。
2) 使jQuery符号作为全局变量可用于引导。
3) 在运行时加载引导程序

1)将模块放入捆绑包中

这是你在问题中提到的第一个问题。将
bootstrap
添加到npmDependencies不足以使scalajs bundler将您的模块包括在捆绑包中。除此之外,在scala代码中的某个地方必须有一个JSImport(“library_name”,…)语句。这会告诉scalajs bundler您实际上正在使用该库,并且需要将其包含在捆绑包中。您可以阅读有关JSImport的更多详细信息。我觉得这个描述有点模糊。这是我对@Julien Richard Foy提出的一个问题的回答,我发现这个问题更有用。在我的代码中,JSImport要求得到满足,包含在下面的第3部分中。注意,您还需要为jquery库提供一个JSImport,以确保它也包含在包中,因为引导依赖于它,并且您需要将
jquery
添加到npmDependencies

2)创建javascript全局变量

这是解决方案中最复杂的部分

在我的应用程序中,我会在浏览器控制台中得到一个错误,如
jQuery未定义
。我花了一些时间来确定这是在引导库中引起的。通过假设定义了全局变量jquery,引导库依赖于jquery库。不幸的是,仅仅通过npmDependencies和JSImport将jquery包含在包中是不够的。您必须告诉scalajs bundler创建jQuery全局变量并将其导出到包中的所有模块

@Julien Richard Foy指出的是一般的食谱,但我相信它有一个bug。由于库名和全局变量名是相同的,所以该错误不会在它们的应用程序中引起问题。问题是,
modName
globalModules[modName]
在importRule的返回行上交换

这是我的common.webpack.config.js文件,用于scalajs绑定器,指示它生成一个全局变量
jQuery
,并将其导出。注意,我所做的唯一更改是将
jquery:“jquery”
放在globalModules中,并将
modName
globalModules[modName]
的位置交换到importRule的返回行上。否则,我只是按照这个例子(也需要其他配置文件和对build.sbt的更改)

关于和操作的一些额外资源

3)在运行时加载模块

通常这不是你必须明确做的事情。但是,对于引导(或任何扩展另一个js库的js库),您可能不会通过facade直接调用该库。很可能您将使用该模式。在这种情况下,jQuery对象被强制转换为引导程序对象,而不直接调用引导程序库。通常,这会很好地编译,但在浏览器控制台中会出现运行时错误,类似于
uncaughttypeerror:jq.modal不是函数
。以下是如何定义jquery的引导扩展,以便您能够在错误消息中理解jq和modal:

  @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.load()
。我喜欢这一点,因为不需要记住在任何包装器工厂方法中显式调用它。

尝试按照烹饪书中的说明进行操作,但在运行webpack时出现以下错误:“错误:'output.filename'是必需的,在配置文件中或作为--output filename”我建议您在讨论频道上分享您的用例。
  private object BootstrapLib {
    @js.native
    @JSImport("bootstrap", Namespace)
    object BootstrapModule extends js.Object

    private lazy val dummy = BootstrapModule

    def load() = dummy
  }
  BootstrapLib.load()