diff --git a/scripts/start.js b/scripts/start.js
index 1e83592..bdad71e 100644
--- a/scripts/start.js
+++ b/scripts/start.js
@@ -65,21 +65,21 @@ async function start() {
// Configure client-side hot module replacement
const clientConfig = webpackConfig.find((config) => config.name === "client");
- clientConfig.entry.client = ["./scripts/lib/webpackHotDevClient"].concat(
- clientConfig.entry.client
- );
- clientConfig.output.filename = clientConfig.output.filename.replace(
- "contenthash",
- "fullhash"
- );
- clientConfig.output.chunkFilename = clientConfig.output.chunkFilename.replace(
- "chunkhash",
- "fullhash"
- );
- clientConfig.module.rules = clientConfig.module.rules.filter(
- (x) => x.loader !== "null-loader"
- );
- clientConfig.plugins.push(new webpack.HotModuleReplacementPlugin());
+ if (clientConfig) {
+ clientConfig.entry.client = ["./scripts/lib/webpackHotDevClient"].concat(
+ clientConfig.entry.client
+ );
+ clientConfig.output.filename = clientConfig.output.filename.replace(
+ "contenthash",
+ "fullhash"
+ );
+ clientConfig.output.chunkFilename =
+ clientConfig.output.chunkFilename.replace("chunkhash", "fullhash");
+ clientConfig.module.rules = clientConfig.module.rules.filter(
+ (x) => x.loader !== "null-loader"
+ );
+ clientConfig.plugins.push(new webpack.HotModuleReplacementPlugin());
+ }
// Configure server-side hot module replacement
const serverConfig = webpackConfig.find((config) => config.name === "server");
@@ -102,11 +102,19 @@ async function start() {
const serverCompiler = multiCompiler.compilers.find(
(compiler) => compiler.name === "server"
);
- const clientPromise = createCompilationPromise(
- "client",
- clientCompiler,
- clientConfig
- );
+
+ let clientPromise;
+
+ if (clientConfig) {
+ clientPromise = createCompilationPromise(
+ "client",
+ clientCompiler,
+ clientConfig
+ );
+ } else {
+ clientPromise = Promise.resolve();
+ }
+
const serverPromise = createCompilationPromise(
"server",
serverCompiler,
@@ -114,15 +122,17 @@ async function start() {
);
// https://github.com/webpack/webpack-dev-middleware
- server.use(
- webpackDevMiddleware(clientCompiler, {
- publicPath: clientConfig.output.publicPath,
- writeToDisk: (filePath) => /stats.json$/.test(filePath),
- })
- );
+ if (clientConfig) {
+ server.use(
+ webpackDevMiddleware(clientCompiler, {
+ publicPath: clientConfig.output.publicPath,
+ writeToDisk: (filePath) => /stats.json$/.test(filePath),
+ })
+ );
+ server.use(webpackHotMiddleware(clientCompiler, { log: false }));
+ }
// https://github.com/glenjamin/webpack-hot-middleware
- server.use(webpackHotMiddleware(clientCompiler, { log: false }));
let appPromise;
let appPromiseResolve;
diff --git a/scripts/webpack.config.js b/scripts/webpack.config.js
index 5f79a7d..16d4159 100644
--- a/scripts/webpack.config.js
+++ b/scripts/webpack.config.js
@@ -17,6 +17,9 @@ const pkg = require("../package.json");
const isDevelopment = !process.argv.includes("--release");
+// set to true to enable CSR
+const IS_SPA = false;
+
const isAnalyze =
process.argv.includes("--analyze") || process.argv.includes("--analyse");
@@ -88,7 +91,8 @@ const configureStyleLoaders = () => ({
test: /\.(sa|sc|c)ss$/,
rules: [
{
- loader: isDevelopment ? "style-loader" : MiniCssExtractPlugin.loader,
+ loader:
+ isDevelopment && IS_SPA ? "style-loader" : MiniCssExtractPlugin.loader,
},
{
exclude: SRC_DIR,
@@ -304,8 +308,9 @@ const baseConfig = {
plugins: [
new webpack.EnvironmentPlugin({
IS_DEVELOPMENT: isDevelopment,
- NAME: JSON.stringify(pkg.name),
- DESCRIPTION: JSON.stringify(pkg.description),
+ IS_SPA,
+ NAME: pkg.name,
+ DESCRIPTION: pkg.description,
VERSION: JSON.stringify(pkg.version),
}),
new webpack.DefinePlugin({
@@ -474,7 +479,7 @@ const serverConfig = {
{
test: /\.(sa|sc|c)ss$/,
rules: [
- ...(isDevelopment
+ ...(isDevelopment && IS_SPA
? []
: [
{
@@ -490,7 +495,7 @@ const serverConfig = {
localIdentName: isDevelopment
? "[name]-[local]-[hash:base64:5]"
: "[hash:base64:5]",
- exportOnlyLocals: isDevelopment,
+ exportOnlyLocals: IS_SPA && isDevelopment,
},
importLoaders: 1,
},
@@ -592,8 +597,8 @@ const serverConfig = {
{
type: "asset/resource",
generator: {
- filename: staticAssetName,
- emit: false,
+ filename: IS_SPA ? staticAssetName : `public/${staticAssetName}`,
+ emit: !IS_SPA,
},
},
],
@@ -603,7 +608,7 @@ const serverConfig = {
type: "asset/resource",
generator: {
filename: "fonts/[name][ext]",
- emit: false,
+ emit: !IS_SPA,
},
},
],
@@ -614,7 +619,7 @@ const serverConfig = {
new LoadablePlugin({
filename: "server-stats.json",
}),
- ...(isDevelopment
+ ...(isDevelopment && IS_SPA
? []
: [
new MiniCssExtractPlugin({
@@ -632,4 +637,7 @@ const serverConfig = {
},
};
-module.exports = [clientConfig, serverConfig, legacyClientConfig];
+module.exports = [
+ serverConfig,
+ ...(IS_SPA ? [clientConfig, legacyClientConfig] : []),
+];
diff --git a/src/client.js b/src/client.js
index fbd9b10..9892add 100644
--- a/src/client.js
+++ b/src/client.js
@@ -8,24 +8,26 @@ import Main from "./js/components/Main";
import initialReducers from "./js/reducers";
import configureDynamicStore from "./js/store";
-// grab the state from a global variable injected into the server-generated HTML
-const store = configureDynamicStore(
- // eslint-disable-next-line no-underscore-dangle
- window.__PRELOADED_STATE__,
- false,
- initialReducers,
- process.env.NODE_ENV !== "production"
-);
-
-loadableReady(() => {
- const routes = selectRoutes(store.getState());
- ReactDOM.hydrate(
-