Created
April 9, 2018 14:24
-
-
Save cdeutsch/29d47db9fd91b0eafdc6d5b5392af46a to your computer and use it in GitHub Desktop.
Typescript Webpack, Node Server backend
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Express } from 'express'; | |
import path from 'path'; | |
import webpack from 'webpack'; | |
import webpackDevMiddleware from 'webpack-dev-middleware'; | |
const webpackConfig = require('../../../frontend/webpack/webpack.dev.config'); | |
export function addDevMiddlewares(app: Express) { | |
const compiler = webpack(webpackConfig); | |
const middleware = webpackDevMiddleware(compiler, { | |
//noInfo: true, | |
publicPath: webpackConfig.output.publicPath, | |
//silent: true, | |
//stats: 'errors-only', | |
stats: { colors: true }, | |
}); | |
app.use(middleware); | |
// Since webpackDevMiddleware uses memory-fs internally to store build | |
// artifacts, we use it instead | |
const fs = middleware.fileSystem; | |
app.get('*', (req, res) => { | |
fs.readFile(path.join((compiler as any).outputPath, 'index.html'), {}, (err: Error, file: any) => { | |
if (err) { | |
console.error('Failed to load index.html', err); | |
res.sendStatus(404); | |
} else { | |
res.send(file.toString()); | |
} | |
}); | |
}); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import compression from 'compression'; | |
import express, { Express } from 'express'; | |
import path from 'path'; | |
export interface ProdMiddlewareOptions { | |
outputPath: string; | |
publicPath: string; | |
} | |
export function addProdMiddlewares(app: Express, options: ProdMiddlewareOptions) { | |
const publicPath = options.publicPath || '/'; | |
const outputPath = options.outputPath || path.resolve(process.cwd(), '../../../frontend/dist'); | |
// compression middleware compresses your server responses which makes them | |
// smaller (applies also to assets). You can read more about that technique | |
// and other good practices on official Express.js docs http://mxs.is/googmy | |
app.use(compression()); | |
app.use(publicPath, express.static(outputPath)); | |
app.get('*', (req, res) => { | |
res.sendFile(path.resolve(outputPath, 'index.html')); | |
}); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Express } from 'express'; | |
import { addDevMiddlewares } from './addDevMiddlewares'; | |
import { addProdMiddlewares, ProdMiddlewareOptions } from './addProdMiddlewares'; | |
export function frontendMiddleware(app: Express, options: ProdMiddlewareOptions) { | |
const isProd = process.env.NODE_ENV === 'production'; | |
if (isProd) { | |
addProdMiddlewares(app, options); | |
} else { | |
addDevMiddlewares(app); | |
} | |
return app; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require('dotenv').config(); | |
import express, { NextFunction, Request, Response } from 'express'; | |
import { resolve } from 'path'; | |
import { db } from './api/db'; | |
const nodeCleanup = require('node-cleanup'); | |
// This setups error handling when using async/await in express routes. | |
// Just throw an error like you naturally would. | |
require('express-async-errors'); | |
import { frontendMiddleware } from './frontendMiddleware'; | |
import { argv, logger, port } from './util'; | |
import api from './api'; | |
const app = express(); | |
app.use('/api', api); | |
// In production we need to pass these values in instead of relying on webpack. | |
frontendMiddleware(app, { | |
outputPath: resolve(process.cwd(), '../../frontend/dist'), | |
publicPath: '/', | |
}); | |
// get the intended host and port number, use localhost and port 3000 if not provided | |
const customHost = argv.host || process.env.HOST; | |
const host = customHost || null; // Let http.Server use its default IPv6/4 host | |
const prettyHost = customHost || 'localhost'; | |
// // serve public files | |
// app.use( | |
// express.static(resolve(process.cwd(), 'public'), { | |
// index: 'index.html', | |
// }) | |
// ); | |
// Error handler for our async/await routes | |
app.use((err: any, req: Request, res: Response, next: NextFunction) => { | |
if (err && err.message) { | |
res.status(500); | |
res.json({ error: err.message }); | |
} | |
next(err); | |
}); | |
// Start your app. | |
app.listen(port, host, (err: Error) => { | |
if (err) { | |
logger.error(err.message); | |
return; | |
} | |
logger.appStarted(port, prettyHost); | |
}); | |
nodeCleanup((exitCode: number, signal: string) => { | |
console.debug('CLEANUP', exitCode, signal); | |
db.$pool.end(); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// cSpell:ignore devtool | |
'use strict'; | |
const fs = require('fs'); | |
const path = require('path'); | |
const webpack = require('webpack'); | |
const CleanWebpackPlugin = require('clean-webpack-plugin'); | |
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); | |
const ProgressBarPlugin = require('progress-bar-webpack-plugin'); | |
const WebpackBuildNotifierPlugin = require('webpack-build-notifier'); | |
const srcPath = path.join(__dirname, '../src'); | |
module.exports = (options) => ({ | |
mode: options.mode, | |
devtool: options.devtool, | |
entry: { | |
app: path.join(srcPath, 'index.tsx'), | |
}, | |
output: Object.assign({ // Compile into dist/[name].js | |
path: path.resolve(process.cwd(), 'dist'), | |
publicPath: '/', | |
}, options.output), // Merge with env dependent settings | |
resolve: { | |
extensions: ['.ts', '.tsx', '.js'], | |
alias: { | |
'@root': srcPath, | |
}, | |
}, | |
devServer: { | |
contentBase: path.resolve(process.cwd(), 'dist'), | |
}, | |
module: { | |
rules: [ | |
{ | |
test: /\.tsx?$/, | |
exclude: /node_modules/, | |
use: [ | |
{ | |
loader: 'ts-loader', | |
options: { | |
configFile: 'tsconfig.json', | |
transpileOnly: true, // disable type checker because we will type check using fork-ts-checker-webpack-plugin | |
} | |
}, | |
], | |
}, | |
], | |
}, | |
plugins: options.plugins.concat([ | |
new ProgressBarPlugin(), | |
new CleanWebpackPlugin(['dist'], { | |
root: process.cwd(), | |
}), | |
// Always expose NODE_ENV to webpack, in order to use `process.env.NODE_ENV` | |
// inside your code for any environment checks; UglifyJS will automatically | |
// drop any unreachable code. | |
new webpack.DefinePlugin({ | |
'process.env': { | |
NODE_ENV: JSON.stringify(process.env.NODE_ENV), | |
MOBX_DEV_TOOLS: JSON.stringify(process.env.MOBX_DEV_TOOLS || 'false'), | |
}, | |
}), | |
new ForkTsCheckerWebpackPlugin(), | |
new WebpackBuildNotifierPlugin({ | |
title: "The Inspector", | |
logo: path.resolve("../notifier.png"), | |
suppressSuccess: true | |
}), | |
]), | |
target: 'web', // Make web variables accessible to webpack, e.g. window | |
performance: options.performance || {}, | |
optimization: { | |
minimize: false, | |
runtimeChunk: { | |
name: 'vendor' | |
}, | |
splitChunks: { | |
cacheGroups: { | |
default: false, | |
commons: { | |
test: /node_modules/, | |
name: "vendor", | |
chunks: "initial", | |
minSize: 1 | |
}, | |
styles: { | |
name: 'styles', | |
test: /\.css$/, | |
chunks: 'all', | |
enforce: true | |
} | |
} | |
} | |
} | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* DEVELOPMENT WEBPACK CONFIGURATION | |
*/ | |
const path = require('path'); | |
const webpack = require('webpack'); | |
const HtmlWebpackPlugin = require('html-webpack-plugin'); | |
// const CircularDependencyPlugin = require('circular-dependency-plugin'); | |
module.exports = require('./webpack.base.config')({ | |
mode: 'development', | |
// Don't use hashes in dev mode for better performance | |
output: { | |
filename: '[name].js', | |
chunkFilename: '[name].chunk.js' | |
}, | |
// Add development plugins | |
plugins: [ | |
new HtmlWebpackPlugin({ | |
template: path.resolve(process.cwd(), '../frontend/public/index.html'), | |
title: 'The Inspector', | |
filename: 'index.html', | |
inject: true, | |
}), | |
// new CircularDependencyPlugin({ | |
// exclude: /a\.js|node_modules/, // exclude node_modules | |
// failOnError: false // show a warning when there is a circular dependency | |
// }) | |
], | |
// Emit a source map for easier debugging | |
// See https://webpack.js.org/configuration/devtool/#devtool | |
devtool: 'eval-source-map', | |
performance: { | |
hints: false | |
} | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Important modules this config uses | |
const path = require('path'); | |
// const webpack = require('webpack'); | |
const HtmlWebpackPlugin = require('html-webpack-plugin'); | |
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); | |
module.exports = require('./webpack.base.config')({ | |
mode: 'production', | |
// Utilize long-term caching by adding content hashes (not compilation hashes) to compiled assets | |
output: { | |
filename: '[name].[chunkhash:6].js', | |
chunkFilename: 'chunks/[name].[chunkhash:6].js', | |
}, | |
plugins: [ | |
// Minify and optimize the index.html | |
new HtmlWebpackPlugin({ | |
template: path.resolve(process.cwd(), 'public/index.html'), | |
title: 'The Inspector', | |
filename: 'index.html', | |
inject: true, | |
minify: { | |
removeComments: true, | |
collapseWhitespace: true, | |
removeRedundantAttributes: true, | |
useShortDoctype: true, | |
removeEmptyAttributes: true, | |
removeStyleLinkTypeAttributes: true, | |
keepClosingSlash: true, | |
minifyJS: true, | |
minifyCSS: true, | |
minifyURLs: true, | |
}, | |
}), | |
new OptimizeCSSAssetsPlugin({}), | |
], | |
performance: { | |
assetFilter: (assetFilename) => !(/(\.map$)|(^(main\.|favicon\.))/.test(assetFilename)), | |
}, | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment