Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds
Arrow up icon
GO TO TOP
Angular UI Development with PrimeNG

You're reading from   Angular UI Development with PrimeNG Build rich UI for Angular applications using PrimeNG

Arrow left icon
Product type Paperback
Published in Jul 2017
Publisher Packt
ISBN-13 9781788299572
Length 384 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Authors (2):
Arrow left icon
Oleg Varaksin Oleg Varaksin
Author Profile Icon Oleg Varaksin
Oleg Varaksin
Sudheer Jonna Sudheer Jonna
Author Profile Icon Sudheer Jonna
Sudheer Jonna
Arrow right icon
View More author details
Toc

Table of Contents (18) Chapters Close

Title Page
Credits
Foreword
About the Authors
About the Reviewer
www.PacktPub.com
Customer Feedback
Preface
1. Getting Started with Angular and PrimeNG FREE CHAPTER 2. Theming Concepts and Layouts 3. Enhanced Inputs and Selects 4. Button and Panel Components 5. Data Iteration Components 6. Amazing Overlays and Messages 7. Endless Menu Variations 8. Creating Charts and Maps 9. Miscellaneous Use Cases and Best Practices 10. Creating Robust Applications

Setting up PrimeNG project with Webpack


Webpack (https://webpack.js.org) is a de facto standard bundler for single-page applications. It analyzes dependencies between JavaScript modules, assets (styles, icons, and images) as well as other files in your application and bundles everything together. In Webpack, everything is a module . You can, for example, import a CSS file like a JavaScript file using require('./myfile.css') or import './myfile.css'.

Webpack can figure out the right processing strategy for imported files by means of the file extension and associated loader. It is not always reasonable to build one big bundle file. Webpack has various plugins to split your code and generate multiple bundle files. It can also load parts of your application asynchronously on demand (lazy loading). All these features make it a power tool. In this section, we will give a high-level overview of Webpack 2 core concepts and show essential steps for creating a Webpack-based Angular, PrimeNG application.

Note

The complete seed project with PrimeNG and Webpack is available on GitHub athttps://github.com/ova2/angular-development-with-primeng/tree/master/chapter1/primeng-webpack-setup. The project structure was kept the same as in the SystemJS-based setup.

Entry point and output

JavaScript and other files imported into each other are closely interwoven. Webpack creates a graph of all such dependencies. The starting point of this graph is called entry point. An entry point tells Webpack where to start to resolve all dependencies and creates a bundle. Entry points are created in the Webpack configuration file using the entry property. In the seed project on GitHub, we have two configuration files, one for the development mode (webpack.dev.js) and one for the production (webpack.prod.js) mode, each with two entry points.

In the development mode, we use the main entry point for JIT compilation. The main.jit.ts file contains quite normally bootstrapping code. The second entry point combines files from core-js (Polyfills for modern ECMAScript features) and zone.js (the basis for Angular's change detection):

entry: {
  'main': './main.jit.ts',
  'polyfill': './polyfill.ts'
}

In the production mode, we use the main entry point for AOT compilation. JIT and AOT were mentioned in the Angular modularity and lifecycle hooks section:

entry: {
  'main': './main.aot.ts',
  'polyfill': './polyfill.ts'
}

The output property tells Webpack where to bundle your application. You can use placeholders such as [name] and [chunkhash] to define what the names of output files look like. The [name] placeholder will be replaced by the name defined in the entry property. The [chunkhash] placeholder will be replaced by the hash of the file content at project build time. The chunkFilename option determines the names of on-demand (lazy) loaded chunks--files loaded by System.import(). In the development mode, we don't use [chunkhash] because of performance issues during hash generation:

output: {
  filename: '[name].js',
  chunkFilename: '[name].js'
}

The [chunkhash] placeholder is used in the production mode to achieve so called long term caching--every file gets cached in the browser and will be automatically invalidated and reloaded when the hash changes:

output: {
  filename: '[name].[chunkhash].js',
  chunkFilename: '[name].[chunkhash].js'
}

Note

A hash in the filename changes every compilation when the file content is changed. That means, files with hashes in names can not be included manually in the HTML file (index.html). HtmlWebpackPlugin (https://github.com/jantimon/html-webpack-plugin) helps us to include generated bundles with <script> or <link> tags in the HTML. The seed project makes use of this plugin.

Loaders and plugins

Webpack only understands JavaScript files as modules. Every other file (.css, .scss, .json, .jpg, and many more) can be transformed into a module while importing. Loaders transform these files and add them to the dependency graph. Loader configuration should be done under module.rules. There are two main options in the loader configuration:

  • The test property with a regular expression for testing files the loader should be applied to
  • loader or use property with the concrete loader name
module: {
  rules: [
    {test: /.json$/, loader: 'json-loader'},
    {test: /.html$/, loader: 'raw-loader'},
    ...
  ]
}

Note that loaders should be registered in package.json so that they can be installed under node_modules. Webpack homepage has a good overview of some popular loaders (https://webpack.js.org/loaders). For TypeScript files, it is recommended to use the following sequence of loaders in the development mode:

{test: /.ts$/, loaders: ['awesome-typescript-loader', 'angular2-template-loader']}

Multiple loaders are applied from right to left. The angular2-template-loader searches for templateUrl and styleUrls declarations and inlines HTML and styles inside of the @Component decorator. The awesome-typescript-loader is mostly for speeding up the compilation process. For AOT compilation (production mode), another configuration is required:

{test: /.ts$/, loader: '@ngtools/webpack'}

Webpack has not only loaders, but also plugins which take responsibility for custom tasks beyond loaders. Custom tasks could be the compression of assets, extraction of CSS into a separate file, generation of a source map, definition of constants configured at compile time, and so on. One of the helpful plugins used in the seed project is the CommonsChunkPlugin. It generates chunks of common modules shared between entry points and splits them into separate bundles. This results in page speed optimizations as the browser can quickly serve the shared code from cache. In the seed project, we moved Webpack's runtime code to a separate manifest file in order to support long-term caching. This will avoid hash recreation for vendor files when only application files are changed:

plugins: [
  new CommonsChunkPlugin({
    name: 'manifest',
    minChunks: Infinity
  }),
  ...
]

As you can see, configuration of plugins is done in the plugins option. There are two plugins for production configuration yet to be mentioned here. The AotPlugin enables AOT compilation. It needs to know the path of tsconfig.json and the path with module class used for bootstrapping:

new AotPlugin({
  tsConfigPath: './tsconfig.json',
  entryModule: path.resolve(__dirname, '..') + 
               '/src/app/app.module#AppModule'
})

UglifyJsPlugin is used for code minification:

new UglifyJsPlugin({
  compress: {
    dead_code: true,
    unused: true,
    warnings: false,
    screw_ie8: true
  },
  ...
})

Adding PrimeNG, CSS, and SASS

It's time to finish the setup. First, make sure that you have PrimeNG and FontAwesome dependencies in the package.json file. For example:

"primeng": "~2.0.2",
"font-awesome": "~4.7.0"

Second, bundle all CSS files into one file. This task is accomplished by ExtractTextPlugin, which is needed for loaders and plugin configuration:

{test: /.css$/, loader: ExtractTextPlugin.extract({
    fallback: "style-loader",
    use: "css-loader"
  })
},
{test: /.scss/, loader: ExtractTextPlugin.extract({
    fallback: "style-loader",
    use: ['css-loader', 'sass-loader']
  }),
  exclude: /^_.*.scss/
}
...
plugins: [
  new ExtractTextPlugin({
    filename: "[name].css"  // file name of the bundle
  }),
  ...
]

Note

For production, you should set the filename to "[name].[chunkhash].css". The bundled CSS file gets automatically included into index.html by HtmlWebpackPlugin.

We prefer not to use styleUrls in the components. The seed project imports a CSS und SASS files in one place--inside of main.scss file located under src/assets/css:

// vendor files (imported from node_modules)
@import "~primeng/resources/themes/bootstrap/theme.css";
@import "~primeng/resources/primeng.min.css";
@import "~font-awesome/css/font-awesome.min.css";

// base project stuff (common settings)
@import "global";

// specific styles for components
@import "../../app/app.component";
@import "../../app/section/section.component";

Note that the tilde ~ points to the node_modules. More precisely the Sass preprocessor interprets it as the node_modules folder. Sass is explained in Chapter 2, Theming Concepts and Layouts. The main.scss file should be imported in the entry points main.jit.ts and main.aot.ts:

import './assets/css/main.scss';

Webpack takes care of the rest. There are more goodies from Webpack--a development server with live reloading webpack-dev-server (https://webpack.js.org/configuration/dev-server). It detects changes made to files and recompiles automatically. You can start it with npm start or npm run start:prod. These commands represent npm scripts:

"start": webpack-dev-server --config config/webpack.dev.js --inline --open
"start:prod": webpack-dev-server --config config/webpack.prod.js --inline --open

Note

When running webpack-dev-server, the compiled output is served from memory. This means, the application being served is not located on disk in the dist folder.

That's all. More configuration options for unit and end-to-end testing will be added in Chapter 10, Creating Robust Applications.

You have been reading a chapter from
Angular UI Development with PrimeNG
Published in: Jul 2017
Publisher: Packt
ISBN-13: 9781788299572
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime
Visually different images