Skip to content

Commit

Permalink
initial import
Browse files Browse the repository at this point in the history
  • Loading branch information
krausest committed Jun 20, 2016
1 parent c03eb08 commit c160bf3
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": ["es2015"]
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ build/Release
# Dependency directories
node_modules
jspm_packages
typings

# Optional npm cache directory
.npm
Expand Down
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,28 @@
# ts-webpack-hmr
Example for typescript and webpack with hot module replacement

Hot module replacement (HMR) from webpack-dev-server can make developing pure fun.
It wasn't that easy to make it work with typescript, so I created a very basic example
to show how to use it.

## How to run it:

`npm install`
`npm run build-dev-server`
Open http://localhost:8080/index.html, open the browser console to see what's happening, make an update to a.ts, save the file and start smiling.
There's no reloading necessary to update the contents of the red div. It shows the results of the updated iAmReloadable function from a.ts.
The module a.ts is reloaded, main.ts is notified about the update. The handler then calls iAmReloadable to update the div.

## Here are the important steps to make HMR with typescript work:

* Use import and require statements correctly.
The module must be imported, but not used as an expression.
`import * as mod_a from "./a";`
Then we're actually loading the module via:
`let a: typeof mod_a = <any>require("./a.ts");`
This allows to replace the module in the callback to module.hot.accept().
See "Optional Module Loading and Other Advanced Loading Scenarios" from http://www.typescriptlang.org/docs/handbook/modules.html for details
* Babel compilation to ES 5 (while using HMR)
If you prefer ES6 output just remove "presets": ["es2015"] from .babelrc and restart webpack
* awesome-typescript-loader supports HMR whereas ts-loader does not
* Use a typescript definition file for webpack via typings
16 changes: 16 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!doctype html>
<html class="no-js">
<head>
<meta charset="utf-8">
<title>Typescript, Webpack and Hot Module Replacement</title>
</head>
<body>
<h1>Typescript, Webpack and Hot Module Replacement</h1>
<p>This is a very basic example to demonstrate hot module reloading with webpack and typescript.</p>
<p>The following div contains the result of a function from a.ts. Change a.ts, save it and and hot
module replacement will update the module. We're notified and can update the div contents with the new value.
No page reload is neccessary to use the new function.</p>
<div id="a_contents" style="background-color:#f99">
</div><script src="dist/main.js"></script>
</body>
</html>
33 changes: 33 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "ts-webpack-hmr",
"version": "1.0.0",
"description": "Example for typescript and webpack with hot module replacement",
"scripts": {
"build-dev-server": "webpack-dev-server -w --hot --inline --config webpack.config.js --host 0.0.0.0",
"postinstall": "typings install --save --global dt~webpack-env"
},
"repository": {
"type": "git",
"url": "https://github.com/krausest/ts-webpack-hmr"
},
"keywords": [
"webpack",
"hot module replacement",
"hmr",
"typescript",
""
],
"license": "Apache-2.0",
"dependencies": {
},
"devDependencies": {
"awesome-typescript-loader": "^0.17.0",
"babel-core": "^6.9.1",
"babel-loader": "^6.2.4",
"babel-preset-es2015": "^6.9.0",
"typescript": "^1.8.10",
"typings": "^1.0.4",
"webpack": "^1.13.1",
"webpack-dev-server": "^1.14.1"
}
}
3 changes: 3 additions & 0 deletions src/a.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// ES6 style to show ES 5 babelification
// Change the return value to see the module replacement in action
export let iAmReloadable = () => "First version";
19 changes: 19 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as mod_a from "./a";

let a: typeof mod_a = <any>require("./a.ts");

if (module.hot) {
console.log("module is hot");
module.hot.accept(["./a.ts"], function () {
console.log("module: accept a");
a = <any>require("./a.ts");
updateDivContents();
});
} else {
console.log("module is not hot. Can't reload the module");
}

let updateDivContents = function() {
document.getElementById("a_contents").innerText = a.iAmReloadable();
}
document.addEventListener("DOMContentLoaded", () => { updateDivContents(); });
23 changes: 23 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"compilerOptions": {
"outDir": "./dist/",
"sourceMap": true,
"noImplicitAny": true,
"module": "commonjs",
"moduleResolution": "node",
"target": "es6",
"noLib": false,
"allowJs": false
},
"files": [
"typings/index.d.ts",
"./src/main.ts"
],
"exclude": [
"node_modules",
"stars",
"vipermkii",
"vipermkvii",
"craider"
]
}
5 changes: 5 additions & 0 deletions typings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"globalDependencies": {
"webpack-env": "registry:dt/webpack-env#1.12.2+20160316155526"
}
}
25 changes: 25 additions & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
var path = require('path');

module.exports = {
entry: "./src/main.ts",
module: {
loaders: [
{ test: /\.ts$/,
exclude:path.resolve(__dirname, "node_modules"),
loader: "babel-loader!awesome-typescript-loader" }
],
},
resolve: {
root: path.resolve(__dirname),
extensions: ['', '.ts', '.js'],
},
output: {
path: __dirname + '/dist/',
filename: '[name].js',
publicPath : 'dist'
},
devServer:{
contentBase: __dirname
},
devtool: "source-map"
};

0 comments on commit c160bf3

Please sign in to comment.