TypeScript - Building with Webpack 2
We walk through the main steps required when using ag-Grid, TypeScript and Webpack below, but for more
information about
either TypeScript or Webpack please refer to those sites for more in depth information around these tools.
Initialise Project
mkdir ag-grid-ts-webpack
cd ag-grid-ts-webpack
npm init --yes
Install Dependencies
npm i --save @ag-grid-community/all-modules
# or, if using Enterprise features
# npm i --save @ag-grid-enterprise/all-modules
npm i --save-dev typescript ts-loader webpack webpack-dev-server extract-text-webpack-plugin
npm i --save-dev css-loader style-loader html-loader html-webpack-plugin
Create Application
Our application will be a very simple one, consisting of a single class that will render a simple grid:
// src/SimpleGrid.ts
import {Grid, GridOptions} from "@ag-grid-community/all-modules";
import "@ag-grid-community/all-modules/dist/styles/ag-grid.css";
import "@ag-grid-community/all-modules/dist/styles/ag-theme-balham.css";
// or, if using Enterprise features
// import {Grid, GridOptions} from "@ag-grid-enterprise/all-modules";
// import "@ag-grid-enterprise/all-modules/dist/styles/ag-grid.css";
// import "@ag-grid-enterprise/all-modules/dist/styles/ag-theme-balham.css";
class SimpleGrid {
private gridOptions: GridOptions = <GridOptions>{};
constructor() {
this.gridOptions = {
columnDefs: this.createColumnDefs(),
rowData: this.createRowData()
};
let eGridDiv:HTMLElement = <HTMLElement>document.querySelector('#myGrid');
new Grid(eGridDiv, this.gridOptions);
}
// specify the columns
private createColumnDefs() {
return [
{headerName: "Make", field: "make"},
{headerName: "Model", field: "model"},
{headerName: "Price", field: "price"}
];
}
// specify the data
private createRowData() {
return [
{make: "Toyota", model: "Celica", price: 35000},
{make: "Ford", model: "Mondeo", price: 32000},
{make: "Porsche", model: "Boxter", price: 72000}
];
}
}
new SimpleGrid();
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="myGrid" style="height: 150px;width: 600px" class="ag-theme-balham"></div>
</body>
</html>
TypeScript Configuration
Our tsconfig.json
is very simple in this example:
// tsconfig.json
{
"compilerOptions": {
"sourceMap": true
}
}
Webpack Configuration
We have 2 Webpack Configurations in the example project - a dev configuration and a production configuration. In
both
of these configurations we make use of an html file where our generated bundle(s) will be inserted and will
serve as our application
starting point, as well as a helper file for within use of the webpack configurations:
Webpack Development Configuration
// config/webpack.dev.js
var webpack = require('webpack');
var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devtool: 'cheap-module-eval-source-map',
entry: './src/SimpleGrid.ts',
output: {
path: path.resolve('dist'),
publicPath: 'http://localhost:8080/',
filename: 'bundle.js'
},
resolve: {
extensions: ['.ts', '.js']
},
module: {
loaders: [
{
test: /\.ts$/,
loader: 'ts-loader'
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader?sourceMap'})
}
]
},
plugins: [
new ExtractTextPlugin({filename: '[name].css'}),
new HtmlWebpackPlugin({
template: 'config/index.html'
})
]
};
entry
This serves as our entry point for our application.
resolve
As our imports done specify what file extension to use, we need to specify what file types we want to match on -
in this case
we're looking at TypeScript and JavaScript files, but you could also add CSS & HTML files too.
module.loaders
Loaders tell Webpack how & what to do with certain types of file - we have specified a few here to deal with
Typescript, HTML, CSS and Images:
- ts-loader: transpile Typescript to ES5
- html
- css: extract and bundle imported CSS into chunked files
plugins
- ExtractTextPlugin: processes and extracts the imported CSS
- HtmlWebpackPlugin: takes our supplied template index.html and inserts the generates JS & CSS files for us
The dev configuration doesn't generate any files - it keeps all bundles in memory, so you won't find any
artifacts in the dist directory (from this configuration).
Webpack Production Configuration
// config/webpack.prod.js
var webpack = require('webpack');
var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devtool: 'source-map',
entry: './src/SimpleGrid.ts',
output: {
path: path.resolve('dist'),
filename: '[name].[hash].js',
chunkFilename: '[id].[hash].chunk.js'
},
resolve: {
extensions: ['.ts', '.js']
},
module: {
loaders: [
{
test: /\.ts$/,
loader: 'ts-loader'
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader?sourceMap'})
}
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin({}),
new ExtractTextPlugin({filename: '[name].css'}),
new webpack.optimize.CommonsChunkPlugin({
name: 'app'
}),
new HtmlWebpackPlugin({
template: 'config/index.html'
})
]
};
We don't use a development server with this configuration - we generate the final artifacts in the dist/ folder
and expect this to be deploy to a server.
We use the plugins to remove duplicates and minify and extract the CSS into cache busting hash named files.
With all this in place, we can now add the following npm scripts to our package.json:
"scripts": {
"start": "webpack-dev-server --config config/webpack.dev.js --inline --progress --port 8080",
"build": "webpack --config config/webpack.prod.js --progress --profile --bail"
},
Now we can either run npm start
to run the development setup, or npm run build
for the
production build.
In the case of the production build the generated files will be under the dist/
folder.
If we now run our application with the above code we will see this: