Comments (10)
Hm. So if I understand correctly you want to have a multi project typescript build?
It's a feature that I need in my current project as well. But I haven't built that yet for sbt-typescript.
I see two challenges:
- the typescript compiler is a bit challenging to support as soon as there are more than one rootdir. Because it will not move the output files to the correct directory anymore. So I need to guess what it has emitted and move the files to the correct place. I've made a beginning of supporting that for compiling both source files and test files. But it's error prone logic. So I'll have to work myself up to get this really well working for both multi project files and compiling tests.
- it would be efficient from a compilation point of view to have one tsc call compile all subprojects. I don't see how to map that on how sbt deals with subprojects. There are two options: either all subprojects will entail their own tsc call. Or tsc compilation is only performed on the level of the top project. And sbt will not manage the subproject structure. The second option is probably wisest....
In my professional project I wanted to spread the typescript code over subprojects. But I haven't yet because of the above reasons.
I'd like to support multiproject builds but it's a thing that I'll have to find some unfragmented attention for in my spare time....
from sbt-typescript.
Regarding the first challenge:
If you determined the common root between the current project and any projects it depends on, I think you can safely use this for the rootDir. I reckon that if you then found the relative path from rootDir to the asset Dir/test Dir, you could safely use those to find the TypeScript output for the current project.
The sbt code below is a bit verbose and probably wrong in parts (I'm pretty sure this will crash on Linux due to mishandling getRoot), but it demonstrates a way of determining the root folder of a top project and its sub projects. From there, you could then use relativeTo
to find the path to look for in the TypeScript output.
val showProjects = TaskKey[Unit]("show-projects", "shows projects")
showProjects := Def.taskDyn {
Def.task {
var commonRoot: Option[File] = None
def findCommon(a: File, b: File): Option[File] = {
var finalFile: Option[File] = None
val aIter = a.toPath.iterator()
val bIter = b.toPath.iterator()
var aPart: String = a.toPath.getRoot.toString
var bPart: String = b.toPath.getRoot.toString
while (aPart == bPart) {
finalFile = finalFile match {
case Some(file) => Some(file / aPart)
case None => Some(file(aPart))
}
if (!aIter.hasNext || !bIter.hasNext()) {
return finalFile
}
aPart = aIter.next().toString
bPart = bIter.next().toString
}
finalFile
}
Def.task { thisProject.value }
.all(ScopeFilter(inAnyProject)).value
.foreach { project: ResolvedProject =>
commonRoot = commonRoot match {
case Some(file) => {
findCommon(file, project.base)
}
case None => {
Some(project.base)
}
}
println(s"Current CommonRoot: ${commonRoot.getOrElse("None")}")
println(s"${name.value}: ${project.id} => ${project.base}")
}
}
}.value
Regarding the second challenge:
It would indeed be more efficient for tsc to be called once. However, I don't think it's compatible with how sbt-web handles things. Due to the aggregation of tasks from projects to sub projects (that is, sub projects have their tasks called first), you'd struggle to have the top project compile TypeScript files for the sub projects in a way that makes sense.
You might as well just do the compilation for each project - I don't see that hurting, really. Sure, you do some extra processing for the top projects, but I've used other sbt-web plugins that do too much work as well, and everything seems fine.
As long as you're not including the sub project files in the top project asset output, I'm pretty sure everything works out.
from sbt-typescript.
Tx for your suggestion. I hope I can soon make some time for making sbt-typescript support multi project builds.
I'll let you know.
from sbt-typescript.
I've implemented multi-project builds for the most part.
What I did was have each subproject be its own typescript compiler run. The compilation results from the dependee subproject are added to the js dependencies of the depender subproject.
The problem I'm hitting right now is that JsTask seems to include the source files when publishing the dependee subproject. And then the typescript compiler thinks it has to compile those files again and doesn't understand the source directory structure anymore.
Any idea how I can prevent the ts source files from being published along with the compilation results? I think it is somewhere in sbt-web that this is being done. And I'm not aware of a config that allows for not including the sources.
from sbt-typescript.
I'm not sure if you can prevent sbt-web from including the source files with a source task. I keep my .ts files out of my asset jars using sbt-filter, but doing something like that would be too late for sbt-typescript.
At the same time, I'm not sure if you actually do want to exclude submodule source files from compilation in the top level module. I think it's a legitimate scenario to have a TypeScript source file living in a top level module referring to a TypeScript source file in a submodule, in which case you will have to include the submodule source file in the compilation of the top level module. Excluding it would mean TypeScript would fail compilation because it could not find the referenced source file from the submodule.
from sbt-typescript.
Maybe I didn't explain too well.
What I meant is that if there is a subproject B depending on subproject A. I got that working: the js + d.ts type defs build results of A are added as a dependency to the webmodules of B. That would work perfectly. But unfortunately the sources are also copied to B. And that confuses the typescript compiler. Unfortunately the tsc first looks for ts files before looking for the d.ts files. Grr.
You can try it out for yourself in the test
subproject of the multi-project
branch.
Options I can think of are:
- finding out which component does the copying of the sources. (probably sbt-web) And create a pullrequest that makes it configurable whether to copy the sources. But that might be quite complicated.
- seeing if I can make the ts compiler find the d.ts files first. But I haven't find any configuration option that enables this.
- creating a separate delete task that runs after
sbt-typescript
runs on project A but before it runs on project B. And deletes the .ts files. I'm not quite sure yet how easy that is.
....
from sbt-typescript.
After delving around the code for a while, I think I've figured something out which may help. This probably isn't the best solution, but it's something.
When sbt-web does its compilation, all exported assets for the project in question end up under target/web/classes/main/META-INF/resources/webjars/<projectname>/<version>/
In the case of web depending on common, web was importing all files from modules/common/target/web/classes/main/META-INF/resources/webjars/common/<version>/
, which included the component.a.ts
file causing problems
I figured there must be some way of excluding assets from this directory, and I think I stumbled across it:
excludeFilter in Assets := (excludeFilter in Assets).value || "*.ts"
This prevents the component.a.ts
file from appearing in the folder. I suspect that this exclusion occurs after sbt-typescript compiles the TypeScript files but before the output of sbt-typescript is copied to this location, since component.a.d.ts
was still put into the folder (like we'd want it to).
I guess the best solution would to be to have sbt-typescript do something similar in a configurable way, but I dunno if you can reliably set excludeFilter in Assets
like this without the chance someone might set a different value in their build.sbt
.
from sbt-typescript.
Cool! I didn't think of that.
Wow. I'm glad we have a way of dealing with multi-project builds now.
I'll have to release this as a beta version and write some unittests to make sure everything still works. Since it uses webModules now instead of nodeModules to resolve dependencies.
Tx.
from sbt-typescript.
I created version 0.4.0-alfa.1
for this a while back. Any news on that?
from sbt-typescript.
I tried using 0.4.0-alfa.1
against the example I referenced in the OP, objectmastery/rootdir-error-example. It still has the same issue when I did a sbt dist
:
[error] tsconfig.json:0: TS6059 File 'C:/github/objectmastery/rootdir-error-example/sub/app/assets/javascripts/sub.ts' is not under 'rootDir' 'C:/github/objectmastery/rootdir-error-example/main/app/assets'. 'rootDir' is expected to contain all source files.
[error] one error found
[error] (main/web-assets:typescript) com.typesafe.sbt.web.CompileProblemsException
I can ignore the error using the tsCodesToIgnore
key, but the javascript files do not appear in the assets JAR once the distribution finishes.
from sbt-typescript.
Related Issues (18)
- Compilation fails the first time, succeeds the second HOT 5
- source maps not working in example project? HOT 5
- Bower support (for angular + polymer)? HOT 1
- Plugin tries to compile dependencies HOT 3
- sbt/TrackLevel HOT 5
- Keep paths specified in tsconfig.json HOT 6
- Enable to import Lodash In my project HOT 1
- TypeScript compilation fails in Trireme JS engine HOT 1
- Object has no method 'convertCompilerOptionsFromJson' HOT 3
- TypeScript not being compiled. HOT 1
- Is there any plan to upgrade to sbt 1.0? HOT 10
- Intellij does not resolve angular2 (or other) webjar libs HOT 4
- rootDir not including sources under app/assets when compiling tests HOT 12
- Line reporting in compile errors is off by one
- java version < 8 not supported? HOT 2
- Failed compilation with dependencies containing typescript files HOT 1
- Wrong unpacked folder name of webjars (rxjs) HOT 10
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sbt-typescript.