-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
Changes from all commits
a0fffc7
5fd1bc3
d6c3d90
2551b1f
30b4db3
53fc2bd
b7725b7
98b2b30
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -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 />} /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this needed? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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} | ||
|
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; | ||
}; |
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'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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' | ||
}) | ||
]; | ||
}); |
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' | ||
]) | ||
] | ||
}); |
There was a problem hiding this comment.
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?