Skip to content
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

Split some of the hacky webpack parts into separate files #942

Merged
merged 2 commits into from
May 24, 2018
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
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@
"webpack-bundle-analyzer": "^2.11.2",
"webpack-dev-middleware": "^3.1.3",
"webpack-hot-middleware": "^2.22.1",
"webpack-merge": "^4.1.2",
"webpack-pwa-manifest": "^3.6.2",
"webpack-subresource-integrity": "^1.1.0-rc.4",
"yaml-loader": "^0.5.0"
Expand Down
13 changes: 13 additions & 0 deletions tasks/utils/htmlMinifierOptions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Minification options for html-minifier.
module.exports = {
removeComments: true,
collapseWhitespace: true,
collapseBooleanAttributes: true,
removeTagWhitespace: true,
removeAttributeQuotes: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
removeOptionalTags: true,
minifyCSS: true,
};
17 changes: 17 additions & 0 deletions tasks/webpack/analyze.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';

export default function analyze(mode) {
const openOptions = {
analyzerMode: 'server',
};
const staticOptions = {
analyzerMode: 'static',
openAnalyzer: false,
};

return {
plugins: [
new BundleAnalyzerPlugin(mode === 'open' ? openOptions : staticOptions),
],
};
}
36 changes: 36 additions & 0 deletions tasks/webpack/compileDependencies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// List of dependency paths that need to be compiled.
const es2015Deps = [
/format-duration/,
/object-values/,
/@material-ui\/core\/es/,
/@material-ui\/icons\/es/,
];

export default function compileDependencies() {
const babelConfig = {
loader: 'babel-loader',
query: {
babelrc: false,
presets: [
['@babel/preset-env', {
modules: false,
// Don't assume dependencies are OK with being run in loose mode
loose: false,
forceAllTransforms: true,
}],
],
},
};

return {
module: {
rules: [
{
test: /\.js$/,
include: es2015Deps,
use: [babelConfig],
},
],
},
};
}
30 changes: 30 additions & 0 deletions tasks/webpack/compress.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import CompressionPlugin from 'compression-webpack-plugin';
import brotli from 'brotli/compress';

const compressible = /\.(js|css|svg|mp3)$/;

export default function compress() {
return {
plugins: [
// Add Gzip-compressed files.
new CompressionPlugin({
test: compressible,
asset: '[path].gz[query]',
algorithm: 'gzip',
}),
// Add Brotli-compressed files.
new CompressionPlugin({
test: compressible,
asset: '[path].br[query]',
algorithm(buffer, opts, cb) {
const result = brotli(buffer);
if (result) {
cb(null, Buffer.from(result));
} else {
cb(null, buffer);
}
},
}),
],
};
}
80 changes: 80 additions & 0 deletions tasks/webpack/staticPages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import path from 'path';
import HtmlPlugin from 'html-webpack-plugin';
import merge from 'webpack-merge';
import htmlMinifierOptions from '../utils/htmlMinifierOptions';

const context = path.join(__dirname, '../../src');

export default function staticPages(pages, production) {
// Add static pages.
const staticFiles = [];

const pageConfigs = Object.entries(pages).map(([name, pathname]) => {
const fullPath = path.join(__dirname, '../../', pathname);
const config = {
entry: {
[name]: [
path.relative(context, fullPath),
'./markdown.css',
],
},
plugins: [
production ? (
// When compiling static pages in production mode, we use the static page
// contents as the template, and wrap it in the _actual_ template using a
// custom loader.
// This is very hacky indeed.
// The problem is that we need to insert compiled Markdown and any
// potential CSS into the HTML using the HtmlPlugin, but it's really hard
// to find the compiled markdown when you're just in a template.
// This could use a better alternative :p
new HtmlPlugin({
chunks: [name],
filename: `${name}.html`,
template: [
require.resolve('../utils/loadStaticHtmlTemplate'),
'extract-loader',
fullPath,
].join('!'),
inject: false,
minify: htmlMinifierOptions,
})
) : (
new HtmlPlugin({
chunks: [name],
template: './markdown.dev.html',
filename: `${name}.html`,
})
),
],
};

staticFiles.push(fullPath);

return config;
});

const loaders = {
module: {
rules: [
!production && {
// Hot reload static pages in development mode.
test: staticFiles,
use: require.resolve('../utils/insertHtml'),
},
{
test: /\.md$/,
use: [
'html-loader',
require.resolve('../utils/renderMarkdown'),
],
},
].filter(Boolean),
},
};

return merge([
...pageConfigs,
loaders,
]);
}
Loading