首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将引导程序包含在scalajs-bundler中

如何将引导程序包含在scalajs-bundler中
EN

Stack Overflow用户
提问于 2019-04-25 10:45:18
回答 2查看 378关注 0票数 1

我正在使用scalajs插件,并定义了我的build.sbt,因此:

代码语言:javascript
复制
enablePlugins(ScalaJSBundlerPlugin)

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

npmDependencies in Compile += "bootstrap" -> "3.4.1"

但是,当我运行"sbt::webpack“时,在生成的-fastOptJS bundle.js文件中没有引用。

难道不应该包括引导吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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不会在它们的示例中造成问题。问题是modNameglobalModules[modName]是在importRule的返回线上交换的。

下面是我的scalajs的common.webpack.config.js文件,指示它生成一个全局变量jQuery并导出它。注意,我所做的唯一更改是将jquery: "jQuery"放在globalModules中,并在importRule的返回线上交换modNameglobalModules[modName]的位置。否则,我只是以身作则。还需要其他配置文件和对build.sbt的更改)。

代码语言:javascript
复制
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和模态:

代码语言:javascript
复制
  @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进行一些显式引用。

我就是这么做的。

代码语言:javascript
复制
  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()。我喜欢这样,因为没有必要记住在任何包装工厂方法中显式地调用它。

票数 3
EN

Stack Overflow用户

发布于 2019-04-26 10:00:19

您必须实际使用该模块,否则webpack将不会将其包含在结果包中。如果您的模块应该从全局命名空间中使用,请遵循这个食谱

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55847489

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档