├── .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 | }; --------------------------------------------------------------------------------