Skip to content

Instantly share code, notes, and snippets.

@jslatts
Last active May 17, 2021 05:44
Show Gist options
  • Save jslatts/f9dec699e8fd853590f520f62d5bf21a to your computer and use it in GitHub Desktop.
Save jslatts/f9dec699e8fd853590f520f62d5bf21a to your computer and use it in GitHub Desktop.
webpack config for React.NET with server side bundle
ReactSiteConfiguration.Configuration.AddScriptWithoutTransform("~/wwwroot/ng-server.bundle.js");
ReactSiteConfiguration.Configuration.JsonSerializerSettings = new Newtonsoft.Json.JsonSerializerSettings
{
ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore,
};
// Don't use slower IE engine
ReactSiteConfiguration.Configuration.AllowMsieEngine = false;
// Don't use built in babel
ReactSiteConfiguration.Configuration.LoadBabel = false;
// Don't use built in react
ReactSiteConfiguration.Configuration.LoadReact = false;
// Temporarily disable SSR for dev if needed
//ReactSiteConfiguration.Configuration.DisableServerSideRendering();
// Experimenting with leaving this on. Stores need to be reset for each request.
ReactSiteConfiguration.Configuration.SetReuseJavaScriptEngines(true);
// @flow
// Copyright 2017 Zeroarc Software, LLC
'use strict'
const { join, resolve } = require('path');
const webpack = require('webpack');
// Used for analyzing webpack results, uncomment below to visualize
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const serverConfig = {
entry: {
main: [
'./Scripts/server.jsx',
]
},
output: {
path: resolve(__dirname,'./wwwroot/'),
filename: 'ng-server.bundle.js',
},
plugins: [
new webpack.LoaderOptionsPlugin({
minimize: false,
debug: true
}),
// Uncomment to visualize bundles
//new BundleAnalyzerPlugin()
],
module: {
rules: [
// Required by React.NET
{
test: require.resolve('react-dom'),
use: {
loader: 'expose-loader',
query: 'ReactDOM'
}
},
// Required by React.NET
{
test: require.resolve('react-dom/server'),
use: {
loader: 'expose-loader',
query: 'ReactDOMServer'
}
},
// Required by React.NET
{
test: require.resolve('react'),
use: {
loader: 'expose-loader',
query: 'React'
}
},
// requires window
{
test: require.resolve('bootstrap'),
use: {
loader: 'null-loader',
query: 'bootstrap'
}
},
// Server specific entry point
{
test: require.resolve('./Scripts/server.jsx'),
use: {
loader: 'expose-loader',
query: 'Components'
}
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.json?$/,
loader: 'json-loader'
},
]
},
resolve: {
extensions: ['.js', '.jsx'],
modules: [
'./node_modules',
]
},
resolveLoader: { modules: [
'./node_modules',
]}
}
const clientConfig = {
entry: {
main: [
'react-hot-loader/patch',
'babel-polyfill',
// Leave disabled and use webpack-dev-server --hot --inline instead
//'webpack-dev-server/client?http://localhost:8080',
'./Scripts/styles.js',
'./Scripts/global.js',
'./Scripts/client.jsx',
],
//'pdf.worker': 'pdfjs-dist/build/pdf.worker.entry'
},
output: {
path: resolve(__dirname,'./wwwroot/'),
publicPath: '/wwwroot/',
filename: 'ng-[name].client.bundle.js',
sourceMapFilename: 'ng-[name].client.bundle.js.map'
},
// Switch these and restart dev server if accurate line number source maps
// are needed for debugging
//devtool: 'source-map',
devtool: 'cheap-module-eval-source-map',
plugins: [
// Leave disabled and use webpack-dev-server --hot --inline instead
//new webpack.HotModuleReplacementPlugin(),
new ExtractTextPlugin({
filename: '[name].min.css',
disable: true,
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module) {
return module.context && module.context.indexOf('node_modules') !== -1
}
}),
// Uncomment to visualize bundles
//new BundleAnalyzerPlugin()
// Off because it breaks everything
//new webpack.NamedModulesPlugin(),
],
module: {
rules: [
// Required by React.NET
{
test: require.resolve('react-dom'),
use: {
loader: 'expose-loader',
query: 'ReactDOM'
}
},
// Required by React.NET
{
test: require.resolve('react'),
use: {
loader: 'expose-loader',
query: 'React'
}
},
// Used directly in some places
{
test: require.resolve('jquery'),
use: [
{
loader: 'expose-loader',
query: 'jQuery'
},
{
loader: 'expose-loader',
query: '$'
}]
},
// Used directly in some places
{
test: require.resolve('numeral'),
use: {
loader: 'expose-loader',
query: 'numeral'
}
},
// Summernote requires this to exist, isn't used
{
test: require.resolve('codemirror'),
loader: 'null-loader',
query: 'codemirror'
},
// Main client entry point
{
test: require.resolve('./Scripts/client.jsx'),
use: {
loader: 'expose-loader',
query: 'Components'
}
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.json?$/,
loader: 'json-loader'
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader'
})
},
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [{
loader: 'css-loader', options: {
// Breaks inline images right now
//sourceMap: true
}
}, {
loader: 'less-loader', options: {
sourceMap: true
}
}]
})
},
{
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
loader: 'url-loader',
options: {
limit: 10000
}
}
]
},
resolve: {
// This may cause unexpected behavior since it forces deps to use the top level version of react
// It was added to get rid of the Only ReactOwner can have refs error
// http://stackoverflow.com/a/32444088/190766
alias: {
'react': join(__dirname, 'node_modules', 'react')
},
extensions: ['.js', '.jsx'],
modules: [
'./node_modules',
]
},
resolveLoader: { modules: [
'./node_modules',
]},
devServer: {
contentBase: resolve(__dirname,'./wwwroot/'),
publicPath: '/wwwroot/',
hot: true,
// Change proxy to match local VM IP for developer's environment
proxy: {
'**': {target: 'http://10.100.50.1:8001/', changeOrigin: true}
}
}
}
module.exports = [clientConfig, serverConfig]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment