在ScalaJs sbt构建中,使用webjars而不是带有“Provided”的npm或bower是否有任何优势?

12

几个月前我第一次接触webJars时,我非常怀疑它是否是处理客户端依赖关系的可行方式,因为某些构建/构建系统非常复杂,并且由于经常发布js文件。第二个担忧当然是没有根据的,但是我在尝试让大约10个scss/css/less类型的webJars和8个JS webJars共存于一个jsDependencies下而花费了近36小时后感到自己被证明是正确的。

我发现的问题是,当你达到JS依赖项3、4或5时,你开始进入一个荒谬的时间消耗循环:

1. "哦,不!fastOptJS失败了,因为有一些随机文件也被命名为webjar中的某个依赖项!"

[trace] Stack trace suppressed: run last client/compile:resolvedJSDependencies for the full output.
[error] (client/compile:resolvedJSDependencies) org.scalajs.core.tools.jsdep.JSLibResolveException: Some references to JS libraries could not be resolved:
[error] - Ambiguous reference to a JS library: bootstrap.min.js
[error]   Possible paths found on the classpath:
[error]   - META-INF/resources/webjars/bootstrap/3.3.6/js/bootstrap.min.js
[error]   - META-INF/resources/webjars/bootstrap3-dialog/1.34.4/examples/assets/bootstrap/js/bootstrap.min.js
[error]   originating from: client:compile, client:compile, client:compile, client:compile
[error] - Ambiguous reference to a JS library: bootstrap.js
[error]   Possible paths found on the classpath:
[error]   - META-INF/resources/webjars/bootstrap3-dialog/1.34.4/examples/assets/bootstrap/js/bootstrap.js
[error]   - META-INF/resources/webjars/bootstrap/3.3.6/js/bootstrap.js
[error]   originating from: client:compile, client:compile, client:compile, client:compile

2. 我知道该怎么做!我会给定义的js添加一个版本!

lazy val           webjarbs   =   "org.webjars"               %    "bootstrap"                       % version.bootstrap  / s"${version.bootstrap}/bootstrap.js"                      minified s"${version.bootstrap}/bootstrap.min.js"         dependsOn    "jquery.js" commonJSName  "bootstrap"

3. "哦不!fastOptJS失败了!"

[trace] Stack trace suppressed: run last client/compile:resolvedJSDependencies for the full output.
[error] (client/compile:resolvedJSDependencies) org.scalajs.core.tools.jsdep.JSLibResolveException: Some references to JS libraries could not be resolved:
[error] - Missing JS library: 3.3.6/bootstrap.js
[error]   originating from: client:compile, client:compile, client:compile, client:compile
[error] - Missing JS library: 3.3.6/bootstrap.min.js
[error]   originating from: client:compile, client:compile, client:compile, client:compile

GG男孩们。

这件事一遍又一遍、绕来绕去,然后我就不得不开始做。

lazy val         bs_sidebar   = ( "org.webjars"               %    "bootstrap-sidebar"              % version.bs_sidebar intransitive())  / "js/sidebar.js" dependsOn(s"bootstrap.js",  s"bootstrap.min.js")

现在我甚至没有使用 webjar,但它有一个名为 X 的js依赖项,我无法更改它...

问题

嗯?如果我只是像以前一样构建依赖项,将其构建成一个巨大的文件或一组文件,然后将其输入构建中呢?我从网上得到了一个概念验证,并使其工作(我认为是 https://github.com/wav/material-ui-scalajs-react/blob/master/src/main/scala/wav/web/muiwrapper/package.scala ),这几乎起作用,并给了我启发。

我知道npmsbt好得多,而且我仍然可以将其放入我的软件包中...缺点是什么,我是否对sbt有所遗漏

2个回答

12

我同意你的观点。一旦应用程序开始对JavaScript库存在重要依赖,jsDependencies 就不可扩展了。这主要是因为WebJars缺少关键特性(例如传递依赖项),但也因为 jsDependencies 不是设计为可扩展的机制。

随着时间的推移,用户要求更多的 jsDependencies 功能,因为他们想将其用作真正的应用级别(无论意味着什么)依赖机制。结果,我们越来越多地在 jsDependencies 上添加了功能/补丁。结果并不是世界上最美丽的东西,它肯定有缺点。

实际上,我鼓励使用 npm 来解决您的依赖问题,特别是如果您熟悉它并知道如何将其集成到您的工作流程中。


1
最近宣布的scalajs-bundler如何适应这一情况?未来,或者对于非微不足道的应用程序,您应该从jsDependencies迁移到npmDependencies吗? - Grogs
2
预计大多数复杂的构建最终会转移到比jsDependencies更有原则的东西。 npmDependencies绝对是一个选择。 - sjrd

3
使用Web Jars的主要优势在于我认为不需要使用npm。此外,它们通过常规的maven解析/下载过程进行处理,因此虽然它并不完美,但只有一个中断管道而不是两个。
不过,它们也可能会很麻烦。我的Scala.js应用程序中有大约30个依赖项,其中大部分是由Web Jars管理的。总的来说,我发现使用npm Web Jars而不是bower Web Jars可以获得更好的结果,并且尝试依赖于Web Jar传递性依赖是愚蠢的。
我的jsDependencies通常看起来像这样:
("org.webjars" % "morrisjs" % "0.5.1" intransitive ())
        / "morris.js"
        minified "morris.min.js"
        dependsOn "2.1.2/raphael.js",
("org.webjars" % "raphaeljs" % "2.1.2-1" intransitive ())
        / "2.1.2/raphael.js"
        minified "2.1.2/raphael-min.js"

首先,需要注意的是版本号混杂到了基本上所有被依赖的东西中。如果使用频繁,我会将版本提取出来放入变量中。第二个是 intransitive() 注释。虽然我有时可以不用它,但我发现明确表达能使事情正常运行并且让我的头发保持在原位。

我倾向于使用类似于 react 和 angular 这样面向前端的友好包。一些新的 react 库有数十个传递依赖,试图使用它们会很痛苦。我避免使用它们 =p


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接