【问题标题】:How to include bootstrap with scalajs-bundler如何在 scalajs-bundler 中包含引导程序
【发布时间】:2019-07-03 02:21:00
【问题描述】:

我正在使用 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 文件中没有对引导程序的引用。

不应该包含引导程序吗?

【问题讨论】:

    标签: twitter-bootstrap scalajs-bundler


    【解决方案1】:

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

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

    1) 将引导库放入捆绑包中。
    2) 将 jQuery 符号作为全局变量提供给 Bootstrap。
    3) 在运行时加载 Bootstrap。

    1) 将模块放入包中

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

    2) 创建 javascript 全局变量

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

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

    solution@Julien Richard-Foy 指出的是要遵循的一般方法,但我相信它有一个错误。该错误不会在他们的example 中引起问题,因为库名称和全局变量名称是相同的。问题是 modNameglobalModules[modName] 在 importRule 的返回行上交换了。

    这是我用于 scalajs-bundler 的 common.webpack.config.js 文件,指示它生成一个全局变量 jQuery 并导出它。请注意,我所做的唯一更改是将 jquery: "jQuery" 放在 globalModules 中,并在 importRule 的返回行上交换 modNameglobalModules[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
      }
    };
    

    关于imports-loaderexpose-loader 操作的一些额外资源。

    3) 在运行时加载模块

    通常这不是您必须明确执行的操作。但是,在 Bootstrap(或任何扩展另一个 js 库的 js 库)的情况下,您可能不会直接通过外观调用该库。您很可能会使用Monkey Patching 模式。在这种情况下,一个 jQuery 对象被强制转换为一个 Bootstrap 对象,而不直接调用 Bootstrap 库。通常这会编译得很好,但是你会在浏览器控制台中得到一个运行时错误,比如Uncaught TypeError: jq.modal is not a function。以下是 jquery 的 Bootstrap 扩展的定义方式,因此您可以在错误消息中对 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]
    

    解决方案是在调用隐式之前的某个时间对库进行一些显式引用。

    我是这样做的。

      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() 在使用任何 Bootstrap 包装器之前被调用。我喜欢这样,因为不需要记住在任何包装器工厂方法中显式调用它。

    【讨论】:

      【解决方案2】:

      你必须实际使用该模块,否则 webpack 不会将它包含在生成的包中。 如果您的模块应该从全局命名空间中使用,请关注this recipe

      【讨论】:

      • 尝试按照说明书中的说明进行操作,但在运行 webpack 时出现以下错误:“错误:在配置文件或 --output-filename 中需要'output.filename'”
      • 我建议您在gitter 讨论频道上分享您的用例。
      猜你喜欢
      • 1970-01-01
      • 2014-04-15
      • 1970-01-01
      • 1970-01-01
      • 2016-10-12
      • 2021-02-01
      • 1970-01-01
      • 2017-02-23
      • 1970-01-01
      相关资源
      最近更新 更多