diff --git a/package.json b/package.json index b3daed3..e07f94a 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "babel-preset-stage-0": "^6.5.0", "babel-register": "^6.7.2", "babel-runtime": "^6.26.0", + "clean-webpack-plugin": "^0.1.19", "compression-webpack-plugin": "^1.1.11", "css-loader": "^0.28.11", "css-modules-require-hook": "^4.0.6", @@ -53,6 +54,7 @@ "webpack": "^4.7.0", "webpack-cli": "^2.1.2", "webpack-dev-middleware": "^3.1.3", - "webpack-hot-middleware": "^2.18.0" + "webpack-hot-middleware": "^2.18.0", + "webpack-manifest-plugin": "^2.0.3" } } diff --git a/src/utils/serverRender.js b/src/utils/serverRender.js index 2a8640b..c7134b5 100644 --- a/src/utils/serverRender.js +++ b/src/utils/serverRender.js @@ -3,6 +3,7 @@ import React from 'react' import { renderToString } from 'react-dom/server' import { StaticRouter as Router } from 'react-router-dom' import { App } from '../components/App' +import manifest from '../../public/static/manifest.json' function serverRender(req, res) { let markup = ''; @@ -15,10 +16,10 @@ function serverRender(req, res) { , ); - return res.status(status).send(renderFullPage(markup)); + return res.status(status).send(renderFullPage(markup, manifest)); } -function renderFullPage(html) { +function renderFullPage(html, manifest) { return ` @@ -30,11 +31,11 @@ function renderFullPage(html) { - + ${process.env.NODE_ENV === 'production' ? `` : ''}
${process.env.NODE_ENV === 'production' ? html : `
${html}
`}
- + ` diff --git a/src/utils/staticFiles.js b/src/utils/staticFiles.js index b825e0e..012ddf6 100644 --- a/src/utils/staticFiles.js +++ b/src/utils/staticFiles.js @@ -1,31 +1,34 @@ const staticFiles = require('express').Router(); const path = require('path'); +import manifest from '../../public/static/manifest.json' -staticFiles.get('/bundle.js', (req, res) => { +staticFiles.get('/*.js', (req, res) => { + const filename = req.url.split("/").pop(); if (req.acceptsEncodings('gzip')) { res.set({ 'Content-Encoding': 'gzip', 'Content-Type': 'text/javascript', - 'Cache-Control': 'max-age=86400' + 'Cache-Control': 'max-age=31536000' }); - res.sendFile(path.join(process.cwd(), '/public/static/bundle.js.gz')); + res.sendFile(path.join(process.cwd(), '/public/', manifest[`${filename}.gz`])); } else { - res.set('Cache-Control', 'max-age=86400'); - res.sendFile(path.join(process.cwd(), '/public/static/bundle.js')); + res.set('Cache-Control', 'max-age=31536000'); + res.sendFile(path.join(process.cwd(), '/public/', manifest['bundle.js'])); } }); -staticFiles.get('/bundle.css', (req, res) => { +staticFiles.get('/*.css', (req, res) => { + const filename = req.url.split("/").pop(); if (req.acceptsEncodings('gzip')) { res.set({ 'Content-Encoding': 'gzip', 'Content-Type': 'text/css', - 'Cache-Control': 'max-age=86400' + 'Cache-Control': 'max-age=31536000' }); - res.sendFile(path.join(process.cwd(), '/public/static/bundle.css.gz')); + res.sendFile(path.join(process.cwd(), '/public/', manifest[`${filename}.gz`])); } else { - res.set('Cache-Control', 'max-age=86400'); - res.sendFile(path.join(process.cwd(), '/public/static/bundle.css')); + res.set('Cache-Control', 'max-age=31536000'); + res.sendFile(path.join(process.cwd(), '/public/', manifest['bundle.css'])); } }); diff --git a/webpack.config.js b/webpack.config.js index ec27df9..f3a1c27 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,12 +1,13 @@ const { resolve, join } = require('path') const webpack = require('webpack') +const ManifestPlugin = require('webpack-manifest-plugin'); const config = { mode: 'development', devtool: 'cheap-eval-source-map', context: resolve(__dirname, 'src'), entry: { - home: [ + bundle: [ 'webpack-hot-middleware/client', './app-client.js' ] @@ -66,7 +67,8 @@ const config = { plugins: [ new webpack.HotModuleReplacementPlugin(), new webpack.NoEmitOnErrorsPlugin(), - new webpack.NamedModulesPlugin() + new webpack.NamedModulesPlugin(), + new ManifestPlugin({'writeToFileEmit': true}) ] } module.exports = config diff --git a/webpack.prod.config.js b/webpack.prod.config.js index cca0c58..2e91441 100644 --- a/webpack.prod.config.js +++ b/webpack.prod.config.js @@ -4,6 +4,8 @@ const UglifyJsPlugin = require("uglifyjs-webpack-plugin") const MiniCssExtractPlugin = require("mini-css-extract-plugin") const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin") const CompressionPlugin = require("compression-webpack-plugin") +const ManifestPlugin = require('webpack-manifest-plugin') +const CleanWebpackPlugin = require('clean-webpack-plugin') const config = { mode: 'production', @@ -15,7 +17,7 @@ const config = { }, output: { path: resolve(__dirname, 'public/static'), - filename: '[name].js', + filename: '[name].[contenthash].js', publicPath: '/static/' }, module: { @@ -68,8 +70,10 @@ const config = { ] }, plugins: [ - new MiniCssExtractPlugin({}), - new CompressionPlugin({}) + new CleanWebpackPlugin(['dist', 'public/static'], {}), + new MiniCssExtractPlugin({filename: '[name].[contenthash].css'}), + new CompressionPlugin({}), + new ManifestPlugin(), ] } diff --git a/yarn.lock b/yarn.lock index 85964e9..b0ee4d0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1434,6 +1434,12 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +clean-webpack-plugin@^0.1.19: + version "0.1.19" + resolved "https://registry.yarnpkg.com/clean-webpack-plugin/-/clean-webpack-plugin-0.1.19.tgz#ceda8bb96b00fe168e9b080272960d20fdcadd6d" + dependencies: + rimraf "^2.6.1" + cli-cursor@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" @@ -2588,6 +2594,16 @@ front-matter@^2.2.0: dependencies: js-yaml "^3.10.0" +fs-extra@^0.30.0: + version "0.30.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + klaw "^1.0.0" + path-is-absolute "^1.0.0" + rimraf "^2.2.8" + fs-minipass@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" @@ -2853,7 +2869,7 @@ got@^8.2.0: url-parse-lax "^3.0.0" url-to-options "^1.0.1" -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6: +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -3639,6 +3655,12 @@ json5@^0.5.0, json5@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" +jsonfile@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + optionalDependencies: + graceful-fs "^4.1.6" + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -3684,6 +3706,12 @@ kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" +klaw@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" + optionalDependencies: + graceful-fs "^4.1.9" + last-call-webpack-plugin@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz#9742df0e10e3cf46e5c0381c2de90d3a7a2d7555" @@ -3826,7 +3854,7 @@ lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@^4.0.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.17.10, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.6.1, lodash@~4.17.4: +"lodash@>=3.5 <5", lodash@^4.0.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.17.10, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.6.1, lodash@~4.17.4: version "4.17.10" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" @@ -6659,6 +6687,14 @@ webpack-log@^1.0.1: loglevelnext "^1.0.1" uuid "^3.1.0" +webpack-manifest-plugin@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/webpack-manifest-plugin/-/webpack-manifest-plugin-2.0.3.tgz#b42c5b08a0319cedb3ec45d9375a9ecee0acf5eb" + dependencies: + fs-extra "^0.30.0" + lodash ">=3.5 <5" + tapable "^1.0.0" + webpack-sources@^1.0.1, webpack-sources@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54"