From f4d1cb7e1e15dbea916db8fc3d420b1923e7c0f6 Mon Sep 17 00:00:00 2001 From: uwap Date: Wed, 14 Feb 2018 06:23:48 +0100 Subject: [PATCH] Reduce production built size --- .babelrc | 2 +- package.json | 3 ++- src/components/App.js | 16 ++++++++++------ src/components/ControlMap.js | 19 ++++++++++--------- src/components/UiItemList/UiItem.js | 11 ++++++----- src/components/UiItemList/index.js | 1 - src/connectMqtt.js | 4 ++-- src/utils/keyOf.js | 4 ++-- src/utils/parseIconName.js | 1 - src/utils/state.js | 6 +++--- webpack.common.js | 7 +++++-- webpack.prod.js | 10 +++++----- yarn.lock | 10 ++++++++++ 13 files changed, 56 insertions(+), 38 deletions(-) diff --git a/.babelrc b/.babelrc index eabd309..1d5a59d 100644 --- a/.babelrc +++ b/.babelrc @@ -1,6 +1,6 @@ { "presets": [ - "env", "react" + ["env", { modules: false }], "react" ], "plugins": [ "transform-class-properties" diff --git a/package.json b/package.json index b01031b..938d999 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "dependencies": { "babel-preset-env": "^1.6.0", "leaflet": "^1.3.1", - "lodash": "^4.17.4", + "lodash-es": "^4.17.4", "material-ui": "npm:material-ui@next", "material-ui-old": "npm:material-ui@latest", "mdi": "^2.0.46", @@ -44,6 +44,7 @@ "flow-typed": "^2.3.0", "html-webpack-plugin": "^2.30.1", "husky": "^0.14.3", + "lodash-webpack-plugin": "^0.11.4", "style-loader": "^0.20.1", "webpack": "^3.1.0", "webpack-dev-server": "^2.11.1", diff --git a/src/components/App.js b/src/components/App.js index 7edd809..6190265 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -1,6 +1,10 @@ // @flow import React from "react"; -import _ from "lodash"; +import map from "lodash/map"; +import mapValues from "lodash/mapValues"; +import filter from "lodash/filter"; +import keys from "lodash/keys"; +import merge from "lodash/merge"; import type { Config, Control, Topics } from "config/types"; @@ -37,7 +41,7 @@ class App extends React.Component { this.state = { selectedControl: null, drawerOpened: false, - mqttState: _.mapValues(this.topics, (topic) => ({ + mqttState: mapValues(this.topics, (topic) => ({ actual: topic.defaultValue, internal: keyOf(topic.values, topic.defaultValue) })), @@ -46,7 +50,7 @@ class App extends React.Component { onConnect: () => this.setState({ mqttConnected: true }), onReconnect: () => this.setState({ mqttConnected: false }), onDisconnect: () => this.setState({ mqttConnected: false }), - subscribe: _.map(this.topics, (x) => x.state) + subscribe: map(this.topics, (x) => x.state) }), mqttConnected: false }; @@ -74,8 +78,8 @@ class App extends React.Component { } receiveMessage(rawTopic: string, message: Object) { - const topics = _.filter( - _.keys(this.topics), + const topics = filter( + keys(this.topics), (k) => this.topics[k].state === rawTopic ); if (topics.length === 0) { @@ -85,7 +89,7 @@ class App extends React.Component { const topic = topics[i]; const parseValue = this.topics[topic].parseState; const val = parseValue == null ? message.toString() : parseValue(message); - this.setState({mqttState: _.merge(this.state.mqttState, + this.setState({mqttState: merge(this.state.mqttState, { [topic]: { actual: val, internal: keyOf(this.topics[topic].values, val) || val diff --git a/src/components/ControlMap.js b/src/components/ControlMap.js index 3ce54ab..5cfc10d 100644 --- a/src/components/ControlMap.js +++ b/src/components/ControlMap.js @@ -1,8 +1,9 @@ // @flow import React from "react"; import { Map, ImageOverlay, Marker, LayersControl } from "react-leaflet"; -import Leaflet from "leaflet"; -import _ from "lodash"; +import { CRS, point, divIcon } from "leaflet"; +import map from "lodash/map"; +import mapValues from "lodash/mapValues"; import parseIconName, { controlGetIcon } from "utils/parseIconName"; import type { Controls, Control } from "config/types"; @@ -37,7 +38,7 @@ export default class ControlMap extends React.Component { return ( + crs={CRS.Simple}> {this.renderMarkers()} {this.renderLayers()} @@ -45,23 +46,23 @@ export default class ControlMap extends React.Component { } renderMarkers() { - return _.map(this.props.controls, this.renderMarker.bind(this)); + return map(this.props.controls, this.renderMarker.bind(this)); } createLeafletIcon(control: Control) { const icon = controlGetIcon(control, this.props.state); const iconClass = parseIconName(`${icon} 36px`); - return Leaflet.divIcon({ - iconSize: Leaflet.point(36, 36), - iconAnchor: Leaflet.point(18, 18), + return divIcon({ + iconSize: point(36, 36), + iconAnchor: point(18, 18), html: `` }); } iconColor(control: Control): string { - const ints = _.mapValues(this.props.state, (x) => x.internal || x.actual); - const acts = _.mapValues(this.props.state, (x) => x.actual); + const ints = mapValues(this.props.state, (x) => x.internal || x.actual); + const acts = mapValues(this.props.state, (x) => x.actual); if (control.iconColor != null) { return control.iconColor(ints, acts, this.props.state); } diff --git a/src/components/UiItemList/UiItem.js b/src/components/UiItemList/UiItem.js index 649b93d..740a3f0 100644 --- a/src/components/UiItemList/UiItem.js +++ b/src/components/UiItemList/UiItem.js @@ -1,6 +1,7 @@ // @flow import React from "react"; -import _ from "lodash"; +import keys from "lodash/keys"; +import map from "lodash/map"; import { ListItemSecondaryAction, ListItemText, @@ -142,11 +143,11 @@ export class DropDown extends UiControl { runPrimaryAction = (next?: Actual) => { if (this.isEnabled()) { const control = this.props.item; - const keys = _.keys(control.options); + const optionKeys = keys(control.options); const value = this.getValue(); - const valueIndex = keyOf(keys, value); + const valueIndex = keyOf(optionKeys, value); if (next == null) { - this.changeState(keys[(valueIndex + 1) % keys.length]); + this.changeState(optionKeys[(valueIndex + 1) % optionKeys.length]); } else { this.changeState(next); } @@ -171,7 +172,7 @@ export class DropDown extends UiControl { disabled={!this.isEnabled()} input={} > - {_.map(options, (v, k) => {v})} + {map(options, (v, k) => {v})} ); diff --git a/src/components/UiItemList/index.js b/src/components/UiItemList/index.js index 527b115..18d6239 100644 --- a/src/components/UiItemList/index.js +++ b/src/components/UiItemList/index.js @@ -1,6 +1,5 @@ // @flow import React from "react"; -import _ from "lodash"; import { ListItem, ListItemIcon, diff --git a/src/connectMqtt.js b/src/connectMqtt.js index bf959f0..0085f28 100644 --- a/src/connectMqtt.js +++ b/src/connectMqtt.js @@ -1,6 +1,6 @@ // @flow import mqtt from "mqtt"; -import _ from "lodash"; +import uniq from "lodash/uniq"; // TODO: type mqtt.js @@ -22,7 +22,7 @@ export default function connectMqtt( const client = mqtt.connect(url); client.on("connect", () => { if (settings.subscribe != null) { - client.subscribe(_.uniq(settings.subscribe)); + client.subscribe(uniq(settings.subscribe)); } if (settings.onConnect != null) { settings.onConnect(client); diff --git a/src/utils/keyOf.js b/src/utils/keyOf.js index ac15802..6021f84 100644 --- a/src/utils/keyOf.js +++ b/src/utils/keyOf.js @@ -1,8 +1,8 @@ // @flow -import _ from "lodash"; +import findKey from "lodash/findKey"; const keyOf = (map: Map, value: b): ?a => ( - _.findKey(map, (x) => x === value) + findKey(map, (x) => x === value) ); export default keyOf; diff --git a/src/utils/parseIconName.js b/src/utils/parseIconName.js index 50fb1b5..44b7b86 100644 --- a/src/utils/parseIconName.js +++ b/src/utils/parseIconName.js @@ -1,6 +1,5 @@ // @flow import * as React from "react"; -import _ from "lodash"; import { getInternals, getActuals } from "utils/state"; import type { Control } from "config/types"; diff --git a/src/utils/state.js b/src/utils/state.js index 94fcd48..c68269c 100644 --- a/src/utils/state.js +++ b/src/utils/state.js @@ -1,8 +1,8 @@ // @flow -import _ from "lodash"; +import mapValues from "lodash/mapValues"; export const getInternals = (state: State): Map => - _.mapValues(state, (x) => x.internal || x.actual); + mapValues(state, (x) => x.internal || x.actual); export const getActuals = (state: State): Map => - _.mapValues(state, (x) => x.actual); + mapValues(state, (x) => x.actual); diff --git a/webpack.common.js b/webpack.common.js index d5457c6..88f4b86 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -12,7 +12,10 @@ const preBuildScripts = process.env.NO_FLOW == undefined ? module.exports = { resolve: { modules: [path.resolve(__dirname, "src"), "node_modules"], - extensions: ['.js', '.jsx'] + extensions: ['.js', '.jsx'], + alias: { + 'lodash': 'lodash-es' + } }, output: { path: path.resolve(__dirname, 'dist'), @@ -30,6 +33,6 @@ module.exports = { title: 'Space Map', template: 'index.ejs' }), - new ExtractTextPlugin("styles.css") + new ExtractTextPlugin("styles.css"), ] }; diff --git a/webpack.prod.js b/webpack.prod.js index fa01ede..c71e613 100644 --- a/webpack.prod.js +++ b/webpack.prod.js @@ -3,6 +3,7 @@ const path = require('path'); const merge = require('webpack-merge'); const common = require('./webpack.common.js'); const ExtractTextPlugin = require("extract-text-webpack-plugin"); +const LodashModuleReplacementPlugin = require('lodash-webpack-plugin'); const extractCSS = ExtractTextPlugin.extract({ fallback: "style-loader", @@ -26,7 +27,6 @@ module.exports = env => merge(common, { entry: { main: [configPath(env), path.resolve(__dirname, 'src/index.jsx')], - vendor: ['react', 'material-ui', 'mqtt', 'lodash'] }, module: { loaders: [ @@ -36,16 +36,16 @@ module.exports = env => merge(common, { }, devtool: "source-map", plugins: [ - new webpack.optimize.UglifyJsPlugin(), new webpack.DefinePlugin({ 'process.env': { 'NODE_ENV': JSON.stringify('production') } }), + new LodashModuleReplacementPlugin(), + new webpack.optimize.UglifyJsPlugin(), + new webpack.optimize.OccurrenceOrderPlugin(), new webpack.HashedModuleIdsPlugin(), - new webpack.optimize.CommonsChunkPlugin({ - name: 'vendor' - }), + new webpack.optimize.AggressiveMergingPlugin(), new webpack.optimize.CommonsChunkPlugin({ name: 'runtime' }), diff --git a/yarn.lock b/yarn.lock index a1d0a3a..db1948c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3781,6 +3781,16 @@ lodash-es@^4.0.0, lodash-es@^4.2.1: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7" +lodash-es@^4.17.4: + version "4.17.5" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.5.tgz#9fc6e737b1c4d151d8f9cae2247305d552ce748f" + +lodash-webpack-plugin@^0.11.4: + version "0.11.4" + resolved "https://registry.yarnpkg.com/lodash-webpack-plugin/-/lodash-webpack-plugin-0.11.4.tgz#6c3ecba3d4b8d24b53940b63542715c5ed3c4ac5" + dependencies: + lodash "^4.17.4" + lodash.assign@^4.0.3, lodash.assign@^4.0.6: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7"