import React from 'react'
const App = () => {
return (
<div>
<h1>Hello TS</h1>
</div>
)
}
export default App
{
"name": "unique-starter",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"dev": "cross-env NODE_ENV=development nodemon ./src/server/index.ts",
"build": "cross-env NODE_ENV=production webpack --config ./webpack/webpack.prod.conf.js",
"server": "cross-env NODE_ENV=production ts-node ./src/server",
"start": "yarn build && yarn server"
},
"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.0",
"@babel/preset-react": "^7.9.4",
"@types/express": "^4.17.4",
"@types/node": "^13.11.0",
"@types/react": "^16.9.32",
"@types/react-dom": "^16.9.6",
"@types/socket.io": "^2.1.4",
"autoprefixer": "^9.7.6",
"babel-loader": "^8.1.0",
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^5.1.1",
"css-loader": "^3.5.1",
"css-mqpacker": "^7.0.0",
"cssnano": "^4.1.10",
"dotenv": "^8.2.0",
"dotenv-webpack": "^1.7.0",
"file-loader": "^6.0.0",
"html-loader": "^1.1.0",
"html-webpack-plugin": "^4.0.4",
"image-webpack-loader": "^6.0.0",
"mini-css-extract-plugin": "^0.9.0",
"node-sass": "^4.13.1",
"nodemon": "^2.0.2",
"postcss-loader": "^3.0.0",
"sass-loader": "^8.0.2",
"style-loader": "^1.1.3",
"ts-node": "^8.8.2",
"typescript": "^3.8.3",
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11",
"webpack-dev-middleware": "^3.7.2",
"webpack-hot-middleware": "^2.25.0",
"webpack-merge": "^4.2.2",
"webpackbar": "^4.0.0"
},
"dependencies": {
"body-parser": "^1.19.0",
"consola": "^2.11.3",
"cross-env": "^7.0.2",
"express": "^4.17.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"socket.io": "^2.3.0"
}
}
const fs = require('fs')
const path = require('path')
const webpack = require('webpack')
const Dotenv = require('dotenv-webpack')
const WebpackBar = require('webpackbar')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const PATHS = {
src: path.join(__dirname, '../src/client'),
dist: path.join(__dirname, '../dist'),
assets: 'assets/'
}
const baseWebpackConfig = {
externals: {
paths: PATHS
},
output: {
path: PATHS.dist,
publicPath: '/'
},
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
name: 'vendors',
test: /node_modules/,
chunks: 'all',
enforce: true
}
}
}
},
resolve: {
extensions: ['.tsx', '.ts', '.js', '.jsx']
},
module: {
rules: [
{
test: /\.html$/,
use: ['html-loader']
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: '/node_modules/',
},
{
test: /\.ts$/,
loader: 'babel-loader',
exclude: '/node_modules/',
},
{
test: /\.tsx$/,
loader: 'babel-loader',
exclude: '/node_modules/',
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: `${PATHS.assets}fonts`,
}
},
{
test: /\.css$/,
use: [
'style-loader',
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: { sourceMap: true }
}, {
loader: 'postcss-loader',
options: { sourceMap: true, config: { path: `./postcss.config.js` } }
}
]
}
]
},
plugins: [
new WebpackBar({
name: 'client',
color: 'green',
}),
new Dotenv(),
new CleanWebpackPlugin(),
new CopyWebpackPlugin([
{ from: `${PATHS.src}/public`, to: '' },
]),
new HtmlWebpackPlugin({
template: `${PATHS.src}/public/index.html`,
filename: `./index.html`
})
]
}
module.exports = baseWebpackConfig
const webpack = require('webpack')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const devWebpackConfig = merge(baseWebpackConfig, {
mode: 'development',
devtool: 'cheap-module-eval-source-map',
// watch: true,
stats: 'errors-warnings',
entry: {
app: [
'webpack-hot-middleware/client?path=/__webpack_hmr&reload=true',
`${baseWebpackConfig.externals.paths.src}/index.tsx`,
],
},
output: {
filename: `${baseWebpackConfig.externals.paths.assets}js/[name].[hash].bundle.js`,
},
module: {
rules: [
{
test: /\.(png|jp(e)?g|gif|svg)$/,
use: {
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: `${baseWebpackConfig.externals.paths.assets}img`,
useRelativePath: true
}
},
},
]
},
plugins: [
new webpack.SourceMapDevToolPlugin({
filename: '[file].map'
}),
new MiniCssExtractPlugin({
filename: `${baseWebpackConfig.externals.paths.assets}css/[name].[hash].css`,
}),
new webpack.HotModuleReplacementPlugin(),
]
})
module.exports = devWebpackConfig
// webpack.config
module.exports = {
module: {
rules: [
{
oneOf: [
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
options: {
cacheDirectory: true,
},
},
{
use: 'file-loader',
exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
},
// ** STOP ** Are you adding a new loader?
// Make sure to add the new loader(s) before the "file" loader.
],
},
],
},
plugins: [
new ForkTsCheckerWebpackPlugin({
async: true,
useTypescriptIncrementalApi: true,
checkSyntacticErrors: true,
eslint: true,
}),
],
};
// babelrc
{
"presets": [
"@babel/preset-env",
"@babel/preset-typescript"
],
}