Skip to content

feat(pwa) use offline-plugin for service worker setup and offline sup… #3000

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
May 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"fetch:supporters": "node src/utilities/fetch-supporters.js",
"fetch:starter-kits": "node src/utilities/fetch-starter-kits.js",
"prebuild": "npm run clean",
"build": "run-s fetch content && cross-env NODE_ENV=production webpack --config webpack.prod.js",
"build": "run-s fetch content && cross-env NODE_ENV=production webpack --config webpack.ssg.js && cross-env NODE_ENV=production webpack --config webpack.prod.js",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This run-s doesn't work if you append the ENV variable at the beginning?

"postbuild": "npm run sitemap",
"test": "npm run lint",
"lint": "run-s lint:*",
Expand Down Expand Up @@ -109,6 +109,7 @@
"modularscale-sass": "^3.0.3",
"node-sass": "^4.5.3",
"npm-run-all": "^4.1.1",
"offline-plugin": "^5.0.7",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"postcss-loader": "^2.1.3",
"redirect-webpack-plugin": "^0.1.1",
Expand Down
6 changes: 6 additions & 0 deletions src/components/Site/Site.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ import './Site.scss';
// Load Content Tree
import Content from '../../_content.json';

// call offline plugin so it can build
if (isClient) {
require('offline-plugin/runtime').install();
}

class Site extends React.Component {
state = {
mobileSidebarOpen: false
Expand Down Expand Up @@ -77,6 +82,7 @@ class Site extends React.Component {
<Route path="/vote" component={Vote} />
<Route path="/organization" component={Organization} />
<Route path="/starter-kits" component={StarterKits} />
<Route path="/app-shell" component={() => <React.Fragment />} />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is "empty" state of the page for service worker to serve when offline, our bundle can then render content onto it on clientside. We have two different page templates: home and content pages. Homepage is always saved in SW and this one is used as fall back for the rest to not download all of them to disk when installing service worker, as client doesnt really need SSR version of the page.

{pages.map(page => (
<Route
key={page.url}
Expand Down
9 changes: 9 additions & 0 deletions src/utilities/find-files-in-dist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// grab .css files from ssg run
const fs = require('fs');

module.exports = function (endsWith = false) {
const filesInDist = fs.readdirSync('./dist');
return endsWith
? filesInDist.filter((item) => item.endsWith(endsWith))
: filesInDist;
};
3 changes: 2 additions & 1 deletion webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ module.exports = (env = {}) => ({
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/',
filename: '[name].bundle.js'
filename: '[name].bundle.js',
chunkFilename: '[name].[chunkhash].chunk.js'
}
});
114 changes: 21 additions & 93 deletions webpack.prod.js
Original file line number Diff line number Diff line change
@@ -1,111 +1,39 @@
// Import External Dependencies
const merge = require('webpack-merge');
const SSGPlugin = require('static-site-generator-webpack-plugin');
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved out due to race between webpack runs [ssg, prod]

const RedirectWebpackPlugin = require('redirect-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const flattenContentTree = require('./src/utilities/flatten-content-tree');
const contentTree = require('./src/_content.json');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const OfflinePlugin = require('offline-plugin');

// Load Common Configuration
const common = require('./webpack.common.js');

// content tree to path array
const paths = [
...flattenContentTree(contentTree),
'/vote',
'/organization',
'/starter-kits'
];
// find css files for sw
const cssFiles = require('./src/utilities/find-files-in-dist')('.css');
// find favicons
const favicons = require('./src/utilities/find-files-in-dist')('.ico');

// Prod only config
const prod = {
// fall back all urls to app shell

module.exports = env => merge(common(env), {
mode: 'production',
target: 'web',
optimization: {
minimizer: [
new TerserJSPlugin({}),
new OptimizeCSSAssetsPlugin({})
]
},
plugins: [
new CopyWebpackPlugin([
{
from: './assets/PWA',
to: './'
},
{
from: './assets/icon-square-small-slack.png',
to: './assets/'
},
{
from: './assets/icon-square-big.svg',
to: './assets/'
},
'CNAME'
])
new OfflinePlugin({
autoUpdate: true,
publicPath: '/',
appShell: '/app-shell/',
// make sure to cache homepage and app shell as app shell for the rest of the pages.
externals: ['/app-shell/', '/', '/manifest.json', ...cssFiles, ...favicons],
excludes: [],
AppCache: {
publicPath: '/'
}
})
]
};

// Export both SSG and SPA configurations
module.exports = env => [
merge(common(env), prod, {
target: 'node',
entry: {
index: './server.jsx'
},
plugins: [
new SSGPlugin({
globals: {
window: {}
},
paths,
locals: {
content: contentTree
}
}),
new RedirectWebpackPlugin({
redirects: {
'support': '/contribute/',
'writers-guide': '/contribute/writers-guide/',
'get-started': '/guides/getting-started/',
'get-started/install-webpack': '/guides/installation/',
'get-started/why-webpack': '/guides/why-webpack/',
'pluginsapi': '/api/plugins/',
'pluginsapi/compiler': '/api/compiler-hooks/',
'pluginsapi/template': '/api/template/',
'api/passing-a-config': '/configuration/configuration-types/',
'api/plugins/compiler': '/api/compiler-hooks/',
'api/plugins/compilation': '/api/compilation/',
'api/plugins/module-factories': '/api/module-methods/',
'api/plugins/parser': '/api/parser/',
'api/plugins/tapable': '/api/tapable/',
'api/plugins/template': '/api/template/',
'api/plugins/resolver': '/api/resolver/',
'development': '/contribute/',
'development/plugin-patterns': '/contribute/plugin-patterns/',
'development/release-process': '/contribute/release-process/',
'development/how-to-write-a-loader': '/contribute/writing-a-loader/',
'development/how-to-write-a-plugin': '/contribute/writing-a-plugin/',
'guides/code-splitting-import': '/guides/code-splitting/',
'guides/code-splitting-require': '/guides/code-splitting/',
'guides/code-splitting-async': '/guides/code-splitting/',
'guides/code-splitting-css': '/guides/code-splitting/',
'guides/code-splitting-libraries': '/guides/code-splitting/',
'guides/why-webpack': '/comparison/',
'guides/production-build': '/guides/production/',
'migrating': '/migrate/3/',
'plugins/no-emit-on-errors-plugin': '/configuration/optimization/#optimization-noemitonerrors',
'concepts/mode': '/configuration/mode'
}
})
],
output: {
filename: 'server.[name].js',
libraryTarget: 'umd'
}
}),
merge(common(env), prod, {
target: 'web'
})
];
});
95 changes: 95 additions & 0 deletions webpack.ssg.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Import External Dependencies
const merge = require('webpack-merge');
const SSGPlugin = require('static-site-generator-webpack-plugin');
const RedirectWebpackPlugin = require('redirect-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const flattenContentTree = require('./src/utilities/flatten-content-tree');
const contentTree = require('./src/_content.json');

// Load Common Configuration
const common = require('./webpack.common.js');

// content tree to path array
const paths = [
...flattenContentTree(contentTree),
'/vote',
'/organization',
'/starter-kits',
'/app-shell'
];

module.exports = env => merge(common(env), {
mode: 'production',
target: 'node',
entry: {
index: './server.jsx'
},
output: {
filename: 'server.[name].js',
libraryTarget: 'umd'
},
optimization: {
splitChunks: false
},
plugins: [
new SSGPlugin({
globals: {
window: {}
},
paths,
locals: {
content: contentTree
}
}),
new RedirectWebpackPlugin({
redirects: {
'support': '/contribute/',
'writers-guide': '/contribute/writers-guide/',
'get-started': '/guides/getting-started/',
'get-started/install-webpack': '/guides/installation/',
'get-started/why-webpack': '/guides/why-webpack/',
'pluginsapi': '/api/plugins/',
'pluginsapi/compiler': '/api/compiler-hooks/',
'pluginsapi/template': '/api/template/',
'api/passing-a-config': '/configuration/configuration-types/',
'api/plugins/compiler': '/api/compiler-hooks/',
'api/plugins/compilation': '/api/compilation/',
'api/plugins/module-factories': '/api/module-methods/',
'api/plugins/parser': '/api/parser/',
'api/plugins/tapable': '/api/tapable/',
'api/plugins/template': '/api/template/',
'api/plugins/resolver': '/api/resolver/',
'development': '/contribute/',
'development/plugin-patterns': '/contribute/plugin-patterns/',
'development/release-process': '/contribute/release-process/',
'development/how-to-write-a-loader': '/contribute/writing-a-loader/',
'development/how-to-write-a-plugin': '/contribute/writing-a-plugin/',
'guides/code-splitting-import': '/guides/code-splitting/',
'guides/code-splitting-require': '/guides/code-splitting/',
'guides/code-splitting-async': '/guides/code-splitting/',
'guides/code-splitting-css': '/guides/code-splitting/',
'guides/code-splitting-libraries': '/guides/code-splitting/',
'guides/why-webpack': '/comparison/',
'guides/production-build': '/guides/production/',
'migrating': '/migrate/3/',
'plugins/no-emit-on-errors-plugin': '/configuration/optimization/#optimization-noemitonerrors',
'concepts/mode': '/configuration/mode'
}
}),
new CopyWebpackPlugin([
{
from: './assets/PWA',
to: './'
},
{
from: './assets/icon-square-small-slack.png',
to: './assets/'
},
{
from: './assets/icon-square-big.svg',
to: './assets/'
},
'CNAME'
])
]
});
30 changes: 23 additions & 7 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3057,16 +3057,16 @@ deep-equal@^1.0.0, deep-equal@^1.0.1:
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=

deep-extend@^0.5.1, deep-extend@~0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.5.1.tgz#b894a9dd90d3023fbf1c55a394fb858eb2066f1f"
integrity sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==

deep-extend@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==

deep-extend@~0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.5.1.tgz#b894a9dd90d3023fbf1c55a394fb858eb2066f1f"
integrity sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==

deep-is@~0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
Expand Down Expand Up @@ -3434,6 +3434,11 @@ ee-first@1.1.1:
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=

ejs@^2.3.4:
version "2.6.1"
resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0"
integrity sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==

electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.124, electron-to-chromium@^1.3.30, electron-to-chromium@^1.3.47:
version "1.3.125"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.125.tgz#dbde0e95e64ebe322db0eca764d951f885a5aff2"
Expand Down Expand Up @@ -6374,7 +6379,7 @@ loader-runner@^2.3.0:
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357"
integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==

loader-utils@^0.2.10, loader-utils@^0.2.16:
loader-utils@0.2.x, loader-utils@^0.2.10, loader-utils@^0.2.16:
version "0.2.17"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348"
integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=
Expand Down Expand Up @@ -7071,7 +7076,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1:
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=

"minimatch@2 || 3", minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.2, minimatch@~3.0.4:
"minimatch@2 || 3", minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2, minimatch@~3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
Expand Down Expand Up @@ -7666,6 +7671,17 @@ obuf@^1.0.0, obuf@^1.1.2:
resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e"
integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==

offline-plugin@^5.0.7:
version "5.0.7"
resolved "https://registry.yarnpkg.com/offline-plugin/-/offline-plugin-5.0.7.tgz#26936ad1a7699f4d67e0a095a258972a4ccf1788"
integrity sha512-ArMFt4QFjK0wg8B5+R/6tt65u6Dk+Pkx4PAcW5O7mgIF3ywMepaQqFOQgfZD4ybanuGwuJihxUwMRgkzd+YGYw==
dependencies:
deep-extend "^0.5.1"
ejs "^2.3.4"
loader-utils "0.2.x"
minimatch "^3.0.3"
slash "^1.0.0"

on-finished@~2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
Expand Down