Skip to content

Latest commit

 

History

History
188 lines (135 loc) · 9.18 KB

README.md

File metadata and controls

188 lines (135 loc) · 9.18 KB

Web Assets

This project contains a monolithic build of all of OpenNMS's JavaScript and CSS web assets. It also contains a Java service to look up resources by name. (Automatically resolving .min.js extensions and such.)

Repository Layout

.
+-- pom.xml                   - Maven POM
+-- webpack.config.js         - webpack configuration
+-- project.json              - JavaScript project info (including possible build commands)
+-- src/
    +-- assembly/
    |   +-- dist.xml          - pack up the compiled assets into a convenient jar
    +-- main/
    |   +-- assets/           - all assets (fonts, images, styles, and javascript)
    |       +-- fonts/        - font files -- NOT copied unless referenced from CSS
    |       +-- images/       - image files -- NOT copied unless referenced from CSS
    |       +-- js/           - JavaScript resources that use CommonJS (require) for loading modules
    |       |   +-- apps/     - JavaScript applications (see the "Applications" section below)
    |       |   +-- lib/      - dumping ground for things that don't fit elsewhere
    |       |   +-- vendor/   - "roll-up" JavaScript files that make it easier to manage dependencies
    |       |   +-- vaadin/   - JavaScript resources that are used as Vaadin components
    |       +-- modules/      - JavaScript resources that use modern module loading (import/export)
    |       |   +-- apps/     - JavaScript applications (see the "Applications" section below)
    |       |   +-- lib/      - dumping ground for things that don't fit elsewhere
    |       |   +-- vendor/   - "roll-up" JavaScript files that make it easier to manage dependencies
    |       |   +-- vaadin/   - JavaScript resources that are used as Vaadin components
    |       +-- static/       - static files that are copied directly into the asset bundle
    |       +-- style/        - CSS and SASS (.scss) stylesheets
    |   +-- java/             - Java asset service
    |   +-- resources/        - Spring component context
    +-- test/
        +-- java/             - Java unit tests
        +-- javascript/       - JavaScript unit tests
        +-- resources/        - Java unit test resources

Development

To build the project, you can just use Maven as normal, eg:

$ ../../compile.pl clean install

Building by "Hand"

While developing new assets, it can be useful to run the node toolchain directly to build. To do so, make sure you have Node.js installed. Note that your Node version (and associated binary plugins built in node_modules/) may not match the version auto-downloaded by the Maven build, so it is best to do a ../../compile.pl clean before hand-building.

Once Node is installed, download the dependencies:

$ npm install

Then, there are a number of commands you can run while developing:

  • npm run build: build all assets in "development" mode -- .min.js assets will not be generated (more on this below)
  • npm run release: build all assets in "production" mode -- this generates both normal .js assets and prod .min.js assets
  • npm run watch: build "development" assets continually, whenever files change
  • npm run watch-release: build "production" assets continually, whenever files change
  • npm run lint: check for errors or warnings in your JavaScript code
  • npm run test: run unit tests

Adding a New Dependency

Bower is no longer used for JS runtime management. Instead, this is a normal npm project, and you can add dependencies as you would any other similar project.

Development Dependencies

If you are modifying webpack.config.js to do something new and you need a dependency added for that, should run:

$ npm install --save-dev <my-new-build-dependency>

Runtime Dependencies

If you need a new dependency to be included into your JavaScript project, you skip the -D (development) flag:

$ npm install --save-prod <my-new-runtime-dependency>

Adding New Tests

Tests are run using Jest. To add a new test, just put a file with the extension .spec.js or .spec.ts in the src/test/javascript/ directory.

Referencing Assets from JSPs

While you can link to the assets directly in the /opennms/assets/ path in the webapp, it is recommended that you use JSP includes instead. This allows for auto-handling of extensions (.min.js vs. .js) and automatically adds versioned hashes to resource URLs for browser cache purposes.

To include a resource in a JSP file, use the following syntax:

<jsp:include page="/assets/load-assets.jsp" flush="false">
  <!-- required: the entry point's name -->
  <jsp:param name="asset" value="manifest" />

  <!-- optional type; if excluded, all resources generated from the specified asset will be included -->
  <jsp:param name="asset-type" value="js" />

  <!-- optional media attribute for css types -->
  <jsp:param name="asset-media" value="screen" />

  <!-- optional async attribute, defaults to false; sets async on the <script> tag -->
  <jsp:param name="asset-async" value="true" />

  <!-- optional defer attribute, defaults to false; sets defer on the <script> tag -->
  <jsp:param name="asset-defer" value="true" />
</jsp:include>

Configuring OpenNMS for Development

While developing JSPs that load assets, it can be convenient to not have to keep copying resources into the assets/ directory. To do so, just delete the $OPENNMS_HOME/jetty-webapps/opennms/assets/ directory and then symlink it to the target/dist/assets directory in this project.

You can also configure the JSP AssetLocator class to use minified or un-minified versions of the assets. To do so, create an asset property file in $OPENNMS_HOME/etc/opennms.properties.d/ and set the following property:

# true or false: whether to serve minified assets from JSPs
org.opennms.web.assets.minified=false

About JavaScript Assets

All JavaScript assets are compiled to a .js file using a UMD loader with webpack. The webpack bundler compiles assets based on "entry points", which are individual files that should be compiled and rolled up into resources. This webpack configuration has a convention that will automatically create entry points based on filesystem layout.

The source tree for JavaScript files is split into 2 sections: js and modules. js is for old-style (or node-style) require() calls to load dependencies. modules is for ES6-style import calls.

The idea is to eventually refactor code out of the js directory into cleaner modules, importing only what is needed. This lets webpack eventually automatically remove dead code from compiled JavaScript.

Applications

In this build system, an "application" is any directory containing an index.js or index.ts file. This is designed for builds like AngularJS apps with templates, or code-splitting into multiple files but with one "entry point". The compiled entry point file will be named after the directory that the index.js file is in. For example, if you create a directory in apps called foo with an index.js file in it, the entry point will be named "foo" and the final asset will be the file foo.js.

Vendor Files

The vendor/ directory is for the equivalent of the dependencies/ directory in the OpenNMS Java build. Files in vendor/ should be a single JavaScript file that includes other dependencies (and maybe a little glue code) to make it easier to get common dependencies rolled up into one include. The compiled entry point file will be named after the file in the vendor/ directory. For example, if your vendor file is called foo.js, the entry point will be named "foo" and the final asset will be the file foo.js.

Vaadin Components

The vaadin/ directory exists for files that will be included in @JavaScript tags in a Vaadin application. Because of the version of Vaadin we use, it is very picky about initialization order. Anything under the vaadin/ subdirectory will be compiled as a single monolithic (minified) script including dependencies with a .vaadin.js extension.

Libraries

The lib/ directory exists for things that don't fit under apps/, vendor/, or vaadin/. It should contain common code and utilities. It also can contain 3rd-party code that you wish to include into other assets. Note that any directory named 3rdparty will automatically be ignored by the webpack entry-point compilation code. The naming convention is the same as for applications.

About Stylesheet Assets

CSS files will be included directly into the finished bundle as-is. SCSS files will be compiled to CSS before being included.

@import tags will be resolved at compile-time. If you need to import CSS or SCSS that comes from the node_modules/ directory, you can include it with a ~ and the module name as prefix. For example, to include the _bootstrap.scss file from node_modules/bootstrap-sass/assets/stylesheets/, you would use: @import "~bootstrap-sass/assets/stylesheets/_bootstrap.scss";

About Static Assets

The static/ directory is the last resort for things that don't fit elsewhere. If you need to put an asset (image, JavaScript, etc.) directly into the asset bundle without compilation or reference from other code, this is the place to put it.