The primary use for Node.JS is of course as a full server stack, and I've used it in that manner to great success.

However, a number of useful, interesting NPM packages deal with things like transpiling a styling language, adding typing information to typeless JavaScript, running JavaScript unit tests, even having a "piped" build system like Gulp.

Currently, I work on a project that uses Tomcat, and is primarily written in Java. Java and Ant utilities have felt somewhat limiting in terms of interacting with our JavaScript files when building/testing, so I'm looking into the possibility of adding a dependency on NodeJS, and setting up build dependencies.

Why would I do this?

I distinctly want to avoid adding dependencies "because they're cool". I only want to add Node packages for scenarios where it is infeasible, or even deprecated, to solve particular problems using Java-based programs (eg, Ant).

One example: Our JavaScript widget library, Dojo, has stated they will not support doing Dojo builds via Java for much longer, having largely moved to Node builds. Additionally, some CSS compression toolkits run using Java have stopped being maintained in favor of those like LESS. There are also developer tools like JavaScript unit tests, or TypeScript types we'd like to consider to make development more reliable. Using a dependency manager might also help us engineer a solution where we don't have Dojo's entire source code committed to our repository.

The question: Proper project layout and potential pitfalls

What would be some reliable practices to follow if I want to use Node as a build/test/development dependency, but not require it for the final, packaged app (And, pros/cons of different approaches)? In this scenario, does it actually make sense to include a package.json in the root project hierarchy? Should Node-related build tasks be invoked via Ant, or does it make sense to require separate commandline actions to invoke them? Under what scenarios should developers/build machines run "npm install", and should it always be automated?

If based on experience people tend to find that the answer to those questions don't matter, that is also a helpful answer - but I'm asking for experience to hopefully avoid some design pitfalls.

  • 1
  • @Snowman Is my question too subjective? Too broad? I understand the recommendations for questions have lots of rules, but I don't think it's right to call a question bad based on reading its title. Even the responses to the meta question aren't universal. – Katana314 Jan 21 '16 at 18:42
  • It is a bit subjective and certainly too broad, but I think the core of what you are trying to get out of it is alright. It just needs to be rephrased. Specifically, I would make it a bit more focused on what your end goals are: start there and work toward Node, not the other way around. As it is, you are saying "I want to leverage Node, but I have a ton of questions about its impact" instead of "My primary concern is X, I want to use Node, but Y might cause trouble - how do I achieve my goal without breaking anything?" – user22815 Jan 21 '16 at 18:47
  • The other concern is this sounds like it is on the borderline of being a discussion topic, and might be better suited to The Whiteboard. – user22815 Jan 21 '16 at 18:49

Having both share the same root is fine. Apache Freemarker Docgen uses this structure. Invoking the JavaScript build from within the Java build is the standard. Running npm install can be decided programmatically by the Java build. For example, in Maven:

<plugin>
    <groupId>com.github.eirslett</groupId>
    <artifactId>frontend-maven-plugin</artifactId>
    <version>0.0.27</version>

    <executions>

      <execution>
        <id>install node and npm</id>
        <goals>
          <goal>install-node-and-npm</goal>
        </goals>
        <configuration>
          <nodeVersion>v4.2.1</nodeVersion>
          <npmVersion>3.5.3</npmVersion>
        </configuration>
      </execution>

      <execution>
        <id>npm install</id>
        <goals>
          <goal>npm</goal>
        </goals>
        <configuration>
          <arguments>install</arguments>
        </configuration>
      </execution>

      <execution>
        <id>npm run build</id>
        <goals>
          <goal>npm</goal>
        </goals>
        <configuration>
          <arguments>run build</arguments>
        </configuration>
      </execution>

    </executions>
</plugin>

References

I find myself using Node for build-related miscellany quite frequently, including for non-Node projects like C++ and otherwise. It provides the immediacy of shell scripting in a less arcane, more digestible to average programmers, and arguably more cross-platform-compatible package than conventional build scripts. That would be true even without the Grunt/Gulp ecosystem, which provides a declarative way of structuring build or deployment related tasks and is, in my opinion, underused for this purpose (as a build sidekick) given the utility of the system versus the intricacies of shell or most proprietary build systems.

Let me give you a for-example.

In one of my gaming projects, I have to kick up a bunch of C++ and C# code in various configurations. Resources have to be massaged, text files have to be parsed, and all of this in extremely specific ways. Now, I could have chosen to do this with the various proprietary OS- or language-specific toolchains (Visual Studio + Unity/Unreal, for example). Instead, I handle it all with Node. This feels cleaner and more approachable. I know can take those same build assets and run my build on OS X, Linux, or Windows, without worrying about obscure differences in shells, build systems, or IDEs.

That doesn't mean doing everything the hard way. I try to let my normal development ecosystem handle the mainline build tasks in whatever way makes sense for the language and environment. But I'm 100% willing to use Node to spackle in the rest, and I believe you can defend this decision from a technical standpoint quite vigorously.

And anyway, who doesn't like working with Node? Live a little!

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.