Skip to content

Exclude / tree-shake Blueprint icon package dependency #25

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 10 commits into from
Jul 17, 2020
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

## v6.0.0-SNAPSHOT - unreleased

### 🎁 New Features

* App builds now load only a handful of `@blueprintjs` icons that are actually used by components.
This change significantly reduces build size as BP ships a large set of generic SVG icons and
bundles them all by default, but Hoist already includes FontAwesome as our standard icon library.
* If the full set of Blueprint icons are required for a special app use-case, `configureWebpack()`
now supports a new `loadAllBlueprintJsIcons` argument to revert to the previous behavior.
* Requires `hoist-react` v35.2 or higher to supply the more minimal set of icon SVGs. Older
versions of HR are compatible with this version of dev-utils, but the icons optimization will
not be activated.

### 📚 Libraries

* @xh/eslint-config `2.2 -> 2.3`
Expand Down
15 changes: 14 additions & 1 deletion configureWebpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ try {reactPkg = require('react/package')} catch (e) {reactPkg = {version: 'NOT_F
* exclude from dupe package checking. Defaults to ['tslib'].
* @param {string} [env.baseUrl] - root path prepended to all relative URLs called via FetchService
* (the core Hoist service for making Ajax requests). Defaults to `/api/` in production mode to
* work with proxy-based deployments and to `$devServerHost:$devServerGrailsPort` in dev mode.
* work with proxy-based deployments and to `$devHost:$devGrailsPort` in dev mode.
* This should not typically need to be changed at the app level.
* @param {string[]} [env.babelIncludePaths] - additional paths to pass Babel for transpiling via
* settings shared with app-level and @xh/hoist code. Intended for custom packages.
Expand Down Expand Up @@ -97,6 +97,9 @@ try {reactPkg = require('react/package')} catch (e) {reactPkg = {version: 'NOT_F
* here to the Babel loader preset-env preset config.
* @param {Object} [env.terserOptions] - options to spread onto / override defaults passed here to
* the Terser minification plugin for production builds.
* @param {boolean} [env.loadAllBlueprintJsIcons] - false (default) to only load the BlueprintJs
* icons required by Hoist React components, resulting in a much smaller bundle size. Set to
* true if your app wishes to access all the BP icons (but consider FontAwesome instead!).
*/
function configureWebpack(env) {
if (!env.appCode) throw 'Missing required "appCode" config - cannot proceed';
Expand Down Expand Up @@ -170,6 +173,10 @@ function configureWebpack(env) {
path.resolve(basePath, '../../hoist-react') :
path.resolve(basePath, 'node_modules/@xh/hoist');

// Resolve Hoist-based path to replacement Blueprint icons (if available, requires HR >= v35.2.
const bpIconStubs = path.resolve(hoistPath, 'static/requiredBlueprintIcons.js'),
loadAllBlueprintJsIcons = env.loadAllBlueprintJsIcons === true || !bpIconStubs;

// Tell webpack where to look for modules when resolving imports - this is the key to getting
// inlineHoist mode to look in within the checked-out hoist-react project at hoistPath.
if (inlineHoist) {
Expand Down Expand Up @@ -420,6 +427,12 @@ function configureWebpack(env) {
// Clean (remove) the output directory before each run.
new CleanWebpackPlugin(),

// Load only the BlueprintJS icons used by Hoist-React components.
!loadAllBlueprintJsIcons ? new webpack.NormalModuleReplacementPlugin(
/.*\/generated\/iconSvgPaths.*/,
bpIconStubs,
) : undefined,

// Inject global constants at compile time.
new webpack.DefinePlugin({
'process.env': {NODE_ENV: JSON.stringify(process.env.NODE_ENV)},
Expand Down