- Notifications
You must be signed in to change notification settings - Fork29
Command for building Dojo applications
License
dojo/cli-build-app
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
The official CLI command for building optimized Dojo applications.
To use@dojo/cli-build-app in a single project, install the package:
npm install @dojo/cli-build-app
@dojo/cli-build-app is a command for the@dojo/cli.
There are four modes available to build a Dojo application,dist,dev,unit, andfunctional. The mode required can be passed using the--mode flag:
dojo build app --mode dist
The built application files are written to theoutput/{dist/dev} directory. The built test files are written to theoutput/test/{unit|functionl} directory.
Note:dist is the default mode and so can be run without any arguments,dojo build app.
Thedist mode creates a production-ready build.
When building your application indist mode, the build process will generate a webpack bundle analyzer that can be used to inspect the content of your application's bundles. The webpack bundle analyzer is outputted to theoutput/info/analyzer directory of your project. To view the analyzer, open theindex.html file contained in this directory.
Thedev mode creates an application build that has been optimized for debugging and development.
Theunit mode creates bundles that can be used to run the unit tests of the application.
Thefunctional mode creates bundles that can be used to run the functional tests of the application.
The build command conditionally loads polyfills from@dojo/framework/shim based on your application's usage and the user's browser capabilities.
By default, the build will support the last two versions of the latest browsers. To support IE 11, run the build with the--legacy (-l) flag.
While most assets will beimported by modules in thesrc/ directory and therefore handled by the main build pipeline, it is often necessary to serve static assets or include assets in the HTML file itself (e.g., the favicon).
Static assets can be added to anassets/ directory at the project root. At build time, these assets are copied as-is without file hashing tooutput/{mode}/assets, and can be accessed using the absolute/assets/ path. For example, if users need access to a static terms of service document namedterms.pdf, that file would added toassets/terms.pdf and accessed via the URL/assets/terms.pdf.
The build also parsessrc/index.html for CSS, JavaScript, and image assets, hashing them and including them in theoutput/{mode}/ directory. For example, it is common for applications to display a favicon in the URL bar. If the favicon is namedfavicon.ico, it can be added to thesrc/ directory and included insrc/index.html with<link rel="icon" href="favicon.ico">. The build will then hash the file and copy it tooutput/{mode}/favicon.[hash].ico.
The build command will automatically code split your application based on its dojo routing configuration.
To enable the code automatic splitting by route:
- The dojo routing configuration needs to be the default export from a
routes.tsmodule in thesrcdirectory. - Widgets must by the default export of their module.
- When defining the
Outlet, therendererfunction must be defined inline.
// routes.tsexportdefault[{path:'foo',outlet:'foo',children:[{path:'bar',outlet:'bar'}]},{path:'bar',outlet:'bar'}];
// widgetimportWidgetBasefrom'@dojo/framework/widget-core/WidgetBase';import{v,w}from'@dojo/framework/widget-core/d';importOutletfrom'@dojo/framework/routing/Outlet';importFooWidgetfrom'./FooWidget';importBarWidgetfrom'./BarWidget';exportdefaultclassAppextendsWidgetBase{protectedrender(){returnv('div',[w(Outlet,{id:'foo',renderer:()=>w(FooWidget,{})}),w(Outlet,{id:'bar',renderer:()=>w(BarWidget,{})})]);}}
The output will result in a separate bundle for each of the application's top level routes. In this example, there will be a main application bundle and two further bundles forsrc/FooWidget andsrc/BarWidget.
Note: The configuration can be further refined using the bundle configuration in the.dojorc, see bundles configuration.
A web server can be started with the--serve flag while running indev ordist modes. By default, the application is served on port 9999, but this can be changed with the--port (-p) flag:
# build once and then serve the app on port 3000dojo build -s -p 3000By default, the files will be served via HTTP. HTTPS can be enabled by placingserver.crt andserver.key files in a.cert directory in the root of your project:
|-- my-project |-- .cert |-- .server.crt |-- .server.keyWhen these files are detected,dojo build -s will automatically serve files via HTTPS.
The development server can be configured to act as a simple proxy. Add aproxy section to your.dojorc containing the paths you want to proxy. The key of the object is the path you want to proxy and the value of the object is the proxy configuration.
{"build-app": {"proxy": {"/api": {"target":"http://example.com","changeOrigin":true,"pathRewrite": {"^/api":"/api/v1" } },"/simple":"http://example.com" } }}Proxy configuration can take the following options:
| Property | Description |
|---|---|
target | The source URL to proxy from |
changeOrigin | true to rewrite the origin header (required for named based virtual hosts) |
ws | true to proxy WebSockets |
pathRewrite | key/value pairs of paths that will get rewritten during the proxy. The key is a regular expression to be matched, the value is the replacement. |
Note: Setting the proxy configuration as a string is equivelant to{ target: "string" }.
Building with the--watch option observes the file system for changes and when with the development server (--serve) will automatically reload you browser.
# start a build with watchdojo build --mode=dev --watch# start a build using the development server and live reloaddojo build --mode=dev --serve --watch
Ejecting@dojo/cli-build-app will produce the following files under theconfig/build-app directory:
build-options.json: the build-specific config options removed from the.dojorcejected.config.js: the root webpack config that passes the build options to the appropriate mode-specific config based on the--env.modeflag's value.base.config.js: a common configuration used by the mode-specific configs.base.test.config.js: a common configuration used by the unit and functional modes.dev.config.js: the configuration used during development.dist.config.js: the production configuration.unit.config.js: the configuration used when running unit tests.functional.config.js: the configuration used when running functional tests.
As already noted, the dojorc'sbuild-app options are moved toconfig/build-app/build-options.json after ejecting. Further, the modes are specified using webpack'senv flag (e.g.,--env.mode=dev), defaulting todist. You can run a build using webpack with:
node_modules/.bin/webpack --config=config/build-app/ejected.config.js --env.mode={dev|dist|unit|functional}Applications use a.dojorc file at the project root to control various aspects of development such as testing and building. This file, if provided, MUST be valid JSON, and the following options can be used beneath the"build-app" key:
Useful for breaking an application into smaller bundles, thebundles option is a map of webpack bundle names to arrays of modules that should be bundled together. For example, with the following configuration, bothsrc/Foo andsrc/Bar will be grouped in thefoo.[hash].js bundle.
Widget modules defined used withw() will be automatically converted to a lazily imported, local registry item in the parent widget. This provides a mechanism for declarative code splitting in your application.
{"build-app": {"bundles": {"foo": ["src/Foo","src/Bar"]}}}The bundles configuration supports globs for matching against modules, this can be useful for scenarios such as grouping all nls internationalization modules by locale:
{"build-app": {"bundles": {"fr": ["src/**/nls/fr/**"],"de": ["src/**/nls/de/**"]}}}Note: The precedence for bundle configuration is 1) An exact match wins against a glob match 2) Order based with the last config winning.
An array of paths toCLDR JSON files. Used in conjunction with thelocale andsupportedLocales options (see below). If a path contains the string{locale}, that file will be loaded for each locale listed in thelocale andsupportedLocales properties. For example, with the following configuration thenumbers.json file will be loaded for the "en", "es", and "fr" locales:
{"build-app": {"locale":"en","supportedLocales": ["es","fr" ]"cldrPaths": ["cldr-data/main/{locale}/numbers.json"]}}Options for compression when running indist mode. Each array value represents a different algorithm, allowing both gzip and brotli builds to be output side-by-side. When used in conjunction with the--serve flag (indist modewithout memory watch), the compressed files will be served, with brotli preferred over gzip when available.
If this is set totrue, image optimization will be performed when running indist mode using default settings. This uses several different libraries dependingon the type of image being optimized.imageOptimization can be an object with individual configuration for these libraries in nested objects. They can also be individually disabled by passing{ enabled: false }.Webp optimization is disabledby default and can be enabled by passingwebp: { enabled true }. The options available for each library can be found at the links below:
Non-modular libraries or standalone applications that cannot be bundled normally can be included in a Dojo application by providing an implementation ofrequire ordefine when needed, and some configuration in the project's.dojorc file.
Configuration for external dependencies can be provided under theexternals property of thebuild-app config.externals is an object with two allowed properties:
outputPath: An optional property specifying an output path to which files should be copied.dependencies: A required array that defines which modules should be loaded via the external loader, and what files should be included in the build. Each entry can be one of two types:- A string that indicates that this path, and any children of this path, should be loaded via the external loader.
- An object that provides additional configuration for dependencies that need to be copied into the built application. This object has the following properties:
| Property | Type | optional | Description |
|---|---|---|---|
from | string | false | A path relative to the root of the project specifying the location of the files or folders to copy into the build application. |
to | string | true | A path that replacesfrom as the location to copy this dependency to. By default, dependencies will be copied to${externalsOutputPath}/${to} or${externalsOutputPath}/${from} ifto is not specified. If there are any. characters in the path and it is a directory, it needs to end with a forward slash. |
name | string | true | Either the module id or the name of the global variable referenced in the application source. |
inject | string, string[], or boolean | true | This property indicates that this dependency defines, or includes, scripts or stylesheets that should be loaded on the page. Ifinject is set totrue, then the file at the location specified byto orfrom will be loaded on the page. If this dependency is a folder, theninject can be set to a string or array of strings to define one or more files to inject. Each path ininject should be relative to${externalsOutputPath}/${to} or${externalsOutputPath}/${from} depending on whetherto was provided. |
type | 'root' or 'umd' or 'amd' or 'commonjs' or 'commonjs2' | true | Force this module to a specific method of resolution. For AMD style require useumd oramd. For node style require usecommonjs, and to access the object as a global useroot |
As an example the following configuration will injectsrc/legacy/layer.js into the application page, inject the file that defines theMyGlobal global variable, declare that modulesa andb are external and should be delegated to the external layer, and then copy the foldernode_modules/legacy-dep, from which several files are injected. All of these files will be copied into theexternals folder, which could be overridden by specifying theoutputPath property in theexternals configuration.
"externals": {"dependencies": ["a","b",{"from":"node_modules/GlobalLibrary.js","to":"GlobalLibrary.js","name":"MyGlobal","inject":true },{"from":"src/legacy/layer.js","to":"legacy/layer.js","inject":true },{"from":"node_modules/legacy-dep","to":"legacy-dep/","inject": ["moduleA/layer.js","moduleA/layer.css","moduleB/layer.js" ]}]}
Types for any dependencies included inexternals can be installed innode_modules/@types, like any other dependency.
Because these files are external to the main build, no versioning or hashing will be performed on files in a production build, with the exceptionof the links to anyinjected assets. Theto property can be used to specify a versioned directory to copy dependencies to in order to avoid differentversions of files being cached.
A map ofhas features to boolean flags that can be used when building indist mode to remove unneeded imports or conditional branches. See thestatic-build-loader documentation for more information.
The default locale for the application. When the application loads, the root locale is set to the user's locale if it supported (see below), or to the defaultlocale as a fallback.
A parent map that houses settings specific to creating progressive web applications.
Specifies information for aweb app manifest. If provided, the following<meta> tags are injected into the application'sindex.html:
mobile-web-app-capable="yes": indicates to Chrome on Android that the application can be added to the user's homescreen.apple-mobile-web-app-capable="yes": indicates to iOS devices that the application can be added to the user's homescreen.apple-mobile-web-app-status-bar-style="default": indicates to iOS devices that the status bar should use the default appearance.apple-touch-icon="{{icon}}": the equivalent of the manifests'iconssince iOS does not currently read icons from the manifest. A separate meta tag is injected for each entry in theiconsarray.
For example:
{"build-app": {"pwa": {"manifest": {"name":"Todo MVC","description":"A simple to-do application created with Dojo","icons": [{"src":"./favicon-16x16.png","sizes":"16x16","type":"image/png" },{"src":"./favicon-32x32.png","sizes":"32x32","type":"image/png" },{"src":"./favicon-48x48.png","sizes":"48x48","type":"image/png" },{"src":"./favicon-256x256.png","sizes":"256x256","type":"image/png" }]}}}}Generates a fully-functional service worker that is activated on startup, complete with precaching and custom route handling. Alternatively, you can create your own service worker file and@dojo/cli-build-app will ensure it is copied to the correct output directory. Under the hood, theServicerWorkerPlugin from@dojo/webpack-contrib is used to generate the service worker, andall of its options are validpwa.serviceWorker properties. Note that ifpwa.serviceWorker.cachePrefix is not included, it defaults to thename property from the application'spackage.json.
{"build-app":{"pwa":{"serviceWorker":{"cachePrefix":"my-app",// exclude the "admin" bundle from caching"excludeBundles":["admin"],"routes":[// Use the cache-first strategy for loading images, adding them to the "my-app-images" cache.// Only the first ten images should be cached, and for one week.{"urlPattern":".*\\.(png|jpg|gif|svg)","strategy":"cacheFirst","cacheName":"my-app-images","expiration":{"maxEntries":10,"maxAgeSeconds":604800}},// Use the cache-first strategy to cache up to 25 articles that expire after one day.{"urlPattern":"http://my-app-url.com/api/articles","strategy":"cacheFirst","expiration":{"maxEntries":25,"maxAgeSeconds":86400}}]}}}}
Renders the application to HTML during the build and in-lines the critical CSS. This allows the application to effectively render static HTML pages and provide some advantages of SSR (server side rendering) such as performance, SEO etc without the complexities of running a server to support full SSR.
- root (required) : The
idof the root DOM node that applicationmergeonto. - paths (optional): An array of routes for rendering the application during the build; for more complex routes an object can be provided with a basic "matcher" (regular expression) that gets used to match against the application's route on page load.
Build time rendering supports applications that use either the@dojo/framework/routing/history/HashHistory or@dojo/framework/routing/history/StateHistory history managers. If your application uses theHashHistory, ensure that allpaths are prefixed with a# character.
{"build-app": {"build-time-render": {"root":"app","paths": ["#home",{"path":"#comments/9999","match": ["#comments\/.*" ]}]}}}BTR generates a screenshot for each of the paths rendered during the build in theoutput/info/screenshots directory of your project.
Build time rendering exposes ahas flagbuild-time-render that can be used to skip functionality that cannot be executed at build time, for example fetching external data.
if(!has('build-time-render')){fetch(/* ... */);}
Note: Theindex.html of your application needs to contain a DOM node with theid specified as theroot in the configuration. This DOM node needs to be used when mounting therenderer for application:
constr=renderer(()=>w(YourAppWidget,{}));r.mount({domNode:document.getElementById('app')!});
An array of supported locales beyond the default. When the application loads, the user's locale is checked against the list of supported locales. If the user's locale is compatible with the supported locales, then the user's locale is used throughout the application. Otherwise, the defaultlocale is used. For example, with the following configuration, the application locale will be set to Pashto or Arabic if either is listed as the user's locale, with Farsi used as the default.
Example:
{"build-app": {"locale":"fa","supportedLocales": ["ps","ar" ],"compression":"gzip","bundles": {"widgets": ["src/widgets/Header","src/widgets/Footer"]}}}We appreciate your interest! Please see theDojo Meta Repository for the Contributing Guidelines. This repository usesprettier for code style and is configured with a pre-commit hook to automatically fix formatting issues on staged.ts files before performing the commit. If you are changing the.dojorc configuration behaviour forbuild-app, please make sure to update theschema.json (aJSON Schema description which is used to validate thebuild-app configuration) to match the changes.
To start working with this package, clone the repository and run:
npm installIn order to build the project, you can run all the build steps via:
npm run buildWill run a watcher process which looks for changes in the source code TypeScript files and runs the build scripts to update the contents of the built files in dist with latest changes made.
Runs the clean up script which removes any built files like output, dist, coverage which get created on build and testing steps.
Runs thets-lint andprettier on all.ts files in thesrc andtests directories. ts-lint will ensure that all linting rules have been abided by and prettier will fix any detected code style violations in the code.
Test cases MUST be written usingIntern using the BDD test interface and Assert assertion interface.
90% branch coverage MUST be provided for all code submitted to this repository, as reported by istanbul’s combined coverage results for all supported platforms.
The command is tested by running via the Dojo CLI and asserting the build output against known fixtures. To do this, a test artifact needs to be built and installed into thetest-app:
npm test© 2018JS Foundation.New BSD license.
About
Command for building Dojo applications
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors15
Uh oh!
There was an error while loading.Please reload this page.
