Guidelines on how to handle advanced frontend topics when sharing a Light Module.
Using npm to share Magnolia light modules provides great opportunities to take advantage of the npm dependency resolution, and to incorporate frontend build processes.
Our goal is to provide guidelines to the magnolia community to ensure that packages are easy to understand and use, and yet ensure that the developers of packages have complete flexibility in how their package is built and interacts with the rest of the npm and the frontend ecosystem.
All of the topics on this page are derived from these core rules.
- npm package is a ready-to-use light module.
- The source control project contains all information about the project. But it is not necessarily a functional light module.
- Running "npm run build" creates a functional light module.
- Each module is responsible for own build.
Frontend build processes (LESS, SASS, ES6 etc)
Each module contains its own build pipeline which is run when the 'npm run build' command is executed. This build pipeline will process the source files provided in the _dev directory and will typically generate files in the webresources directory.
The reason is the huge diversity of frontend tools and rapid speed of change, it would be limiting to have a single build pipeline at the project level that all modules would have to stick to. With module-level build, each module has complete freedom to select its own build pipeline, and is sure that it will build properly, no matter the project "environment".
Magnolia provides examples of how to do this - but again, does not recommend any specific build for a module.
prepublish script should run
npm run build so that the build pipeline will be run whenever the package is published. This ensures that all packages on npm are always 'built' and ready to use as light modules.
_dev directory with all its source files, and the build config files like
.babelrc should be excluded from the built npm package. This is accomplished by listing them in the standard
As a best practice, consider including any built files in a
.gitignore file. This ensures that devs using the project will get a build based on the latest versions, eliminates redundancy, and serves to document what is being generated.
- https://github.com/magnolia-cms/calculator-magnolia Illustrates building an ES5 JS file from several ES6 files. It also demonstrates building css from Less files. It includes the prepublish hook and the .npmignore file.
NPM Library dependencies
Based on the same "module-level build" introduced above, a module should declare those projects as npm
dependencies in its
package.json. The build pipeline must include a step to either generate new resources (js, css, etc) based on those dependencies, or simply copy resources from those dependencies - and place them in the
- https://github.com/magnolia-cms/chartjs-magnolia Illustrates a very simple build pipeline, it just copies the js file that it depends on from the chartjs package.
Big popular libraries like jquery and angular should usually not be brought in via npm dependencies. Since many components are likely to depend on them, and they are available via CDN, a project developer will usually prefer to manage those libraries "by hand".
Note that it is the modules job to generate/copy the proper resources in the webresources directory, but not to handle how they get into the web page. This is left to the project developer so that they can use the web resources strategy that makes the most sense for their project (resfn, theme, include, etc).
To test magnolia rendering, integration tests can easily be provided to test a demo page for the presence of expected DOM. These tests can be written with the cheerio library which leverages jQuery for easily selecting the contents of the html DOM. For example, a demo page could contain the same component, but configured via the dialog in 4 different ways. A test could check each rendered version for expected HTML elements. You could use more sophisticated approaches than simple DOM tests, such as selenium to test user interactions with your components.
Tests are especially valuable for open source projects. They make it easier for people to contribute to your project, because they (and you) will see if they have broken anything.
- https://github.com/magnolia-cms/calculator-magnolia Illustrates unit and integration tests which are automatically run on the https://travis-ci.org/ service whenever a
git pushis made on the repository. Travis build status for this project: https://travis-ci.org/magnolia-cms/calculator-magnolia
Steps to create a test of magnolia rendering (illustrated in the above project):
- Create a demo page with one or more instances of your component configured in various ways via the dialog.
- Export the page as an xml bootstrap file to the
- Supply a test script in
_dev/test/integrationwhich loads the demo webpage and checks the rendered DOM for expected contents. (For example with the
- Add an integration and test script to the
- Supply a
.travis.ymlconfiguration, and connect your git repo to the free travis-ci continuous integration service.
Additional details: Testing Light Modules for Frontend Developers
Light Project: Frontend build on the entire project
A light project consists of a package.json which declares all of the light modules in the project as npm dependencies, and any required build pipeline. A light project is an optional concept.
For each shared light module we recommend a module-level build (as described above), but on the project level, you may want to further process the contents of all modules in your project. The most common use case is that you want to concatonate or minify the webresources from all the modules into a fewer number of resources. Projects often have only app.js and styles.css files.
For a light project setup we suggest the following directory structure:
- The light-project files at the root of the directory.
- A src directory where the project can put the dependencies. A dist directory where the project will place the processed light modules.
- The dist directory functions as your magnoila.resources.dir directory.
- https://github.com/magnolia-cms/light-project-example-gulp A light project builder based on Gulp
- https://github.com/magnolia-cms/light-project-example-webpack A light project builder based on Webpack
If some of the modules that your project depends on are on your harddrive instead of npm, you can reference the files directly. npm will then build the project (if a prepublish hook is defined) and takes the .npmignore of the module into account.