├── .babelrc
├── .gitignore
├── README.md
├── config
└── webpack.config.js
├── index.html
├── package.json
├── server.js
├── src
├── containers
│ └── App.tsx
└── index.tsx
├── tsconfig.json
└── type-declarations
└── require.d.ts
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react", "stage-0"],
3 | "plugins": ["react-hot-loader/babel"]
4 | }
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | ts-build
3 | dist
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Typescript and React project template
2 |
3 | This repository contains a basic Typescript and React project template. For more information, see http://blog.tomduncalf.com/posts/setting-up-typescript-and-react/
4 |
5 | If using a newer Typescript version that Visual Studio Code doesn't (yet) understand, a setting is required.
6 | i.e. enter the content below into *File/Preferences/Workspace Settings* settings.json file. This will instruct Visual Studio Code to use proper TypeScript version that project uses.
7 |
8 | `{
9 | "typescript.tsdk": "node_modules/typescript/lib"
10 | }`
--------------------------------------------------------------------------------
/config/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 | var path = require('path');
3 | var WebpackNotifierPlugin = require('webpack-notifier');
4 |
5 | module.exports = {
6 | devtool: 'eval',
7 | entry: [
8 | // Add the react hot loader entry point - in reality, you might only want this in your dev config
9 | 'react-hot-loader/patch',
10 | 'webpack-dev-server/client?http://localhost:3000',
11 | 'webpack/hot/only-dev-server',
12 | 'index.tsx'
13 | ],
14 | output: {
15 | filename: 'app.js',
16 | publicPath: '/dist',
17 | path: path.resolve('dist')
18 | },
19 | resolve: {
20 | extensions: ['', '.ts', '.tsx', '.js', '.jsx'],
21 | modulesDirectories: ['src', 'node_modules'],
22 | },
23 | module: {
24 | loaders: [
25 | { test: /\.tsx?$/, loaders: ['babel', 'ts-loader'] }
26 | ]
27 | },
28 | plugins: [
29 | // Add the HMR plugin
30 | new webpack.HotModuleReplacementPlugin(),
31 | new WebpackNotifierPlugin({ alwaysNotify: true }),
32 | ]
33 | };
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | My Typescript App
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "typescript-react-template",
3 | "version": "1.0.0",
4 | "description": "A simple template for Typescript + React + Webpack + Babel",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "webpack --config config/webpack.config.js",
8 | "start": "node server.js"
9 | },
10 | "author": "Tom Duncalf",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "@types/node": "4.0.22-alpha",
14 | "@types/react": "0.14.21-alpha",
15 | "@types/react-dom": "0.14.8-alpha",
16 | "@types/requirejs": "2.1.20-alpha",
17 | "babel-core": "6.9.1",
18 | "babel-loader": "6.2.4",
19 | "babel-preset-es2015": "6.9.0",
20 | "babel-preset-react": "6.5.0",
21 | "babel-preset-stage-0": "6.5.0",
22 | "react-hot-loader": "3.0.0-beta.2",
23 | "ts-loader": "0.8.2",
24 | "typescript": "1.9.0-dev.20160620-1.0",
25 | "webpack": "1.13.1",
26 | "webpack-dev-server": "1.14.1",
27 | "webpack-notifier": "1.3.0"
28 | },
29 | "dependencies": {
30 | "react": "15.1.0",
31 | "react-dom": "15.1.0"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 | var WebpackDevServer = require('webpack-dev-server');
3 | var config = require('./config/webpack.config');
4 |
5 | new WebpackDevServer(webpack(config), {
6 | publicPath: config.output.publicPath,
7 | hot: true,
8 | historyApiFallback: true
9 | }).listen(3000, 'localhost', function (err, result) {
10 | if (err) {
11 | return console.log(err);
12 | }
13 |
14 | console.log('Listening at http://localhost:3000/');
15 | });
--------------------------------------------------------------------------------
/src/containers/App.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 |
3 | export default () => Hello world
4 |
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | // Import React and React DOM
2 | import * as React from 'react';
3 | import { render } from 'react-dom';
4 | // Import the Hot Module Reloading App Container – more on why we use 'require' below
5 | const { AppContainer } = require('react-hot-loader');
6 |
7 | // Import our App container (which we will create in a second)
8 | import App from 'containers/App';
9 |
10 | // Tell Typescript that there is a global variable called module - see below
11 | declare var module: { hot: any };
12 |
13 | // Get our root element
14 | const rootEl = document.getElementById('app');
15 |
16 | // And render our App into it, inside the HMR App Container which handles the reloading
17 | render(
18 |
19 |
20 | ,
21 | rootEl
22 | )
23 |
24 | // Handle hot reloading actions from Webpack
25 | if (module.hot) {
26 | module.hot.accept('./containers/App', () => {
27 | // If we receive a HMR action for our App container, then reload it
28 | // using require (we can't do this dynamically with import)
29 | const NextApp = require('./containers/App').default;
30 |
31 | // And render it into our root element again
32 | render(
33 |
34 |
35 | ,
36 | rootEl
37 | )
38 | })
39 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "es6",
4 | "target": "es6",
5 | "moduleResolution": "node",
6 | "baseUrl": "src",
7 | "allowSyntheticDefaultImports": true,
8 | "noImplicitAny": false,
9 | "sourceMap": true,
10 | "outDir": "ts-build",
11 | "jsx": "preserve"
12 | },
13 | "exclude": [
14 | "node_modules"
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/type-declarations/require.d.ts:
--------------------------------------------------------------------------------
1 | declare var require: {
2 | (path: string): any;
3 | (path: string): T;
4 | (paths: string[], callback: (...modules: any[]) => void): void;
5 | ensure: (paths: string[], callback: (require: (path: string) => T) => void) => void;
6 | };
--------------------------------------------------------------------------------