From abffd4062dac445db44ee4e121aff4aa5e44eea8 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Tue, 13 Oct 2020 11:45:43 +1000 Subject: [PATCH 1/4] interface: disable source maps on production builds Source maps have never worked correctly on production builds, and the way that they are bundled into the JS itself negatively impacts our time to first paint. As such, we disable them for a significant bundle size improvement (10MB -> 2.4MB) --- pkg/interface/config/webpack.prod.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/interface/config/webpack.prod.js b/pkg/interface/config/webpack.prod.js index 7a0e5a2e7..4db3bf13f 100644 --- a/pkg/interface/config/webpack.prod.js +++ b/pkg/interface/config/webpack.prod.js @@ -41,7 +41,7 @@ module.exports = { resolve: { extensions: ['.js', '.ts', '.tsx'] }, - devtool: 'inline-source-map', + devtool: 'none', // devServer: { // contentBase: path.join(__dirname, './'), // hot: true, From e7d32612525dfc69f82f1da20c1b8d5577fc83d2 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Tue, 13 Oct 2020 11:49:57 +1000 Subject: [PATCH 2/4] interface: do not bundle extra locales Landscape is not localised in any fashion and we never change the default locale. As such, the locales that moment.js includes in the bundle are redundant and can be removed --- pkg/interface/config/webpack.prod.js | 2 ++ pkg/interface/package.json | 1 + 2 files changed, 3 insertions(+) diff --git a/pkg/interface/config/webpack.prod.js b/pkg/interface/config/webpack.prod.js index 4db3bf13f..99acbd028 100644 --- a/pkg/interface/config/webpack.prod.js +++ b/pkg/interface/config/webpack.prod.js @@ -1,6 +1,7 @@ const path = require('path'); // const HtmlWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); +const MomentLocalesPlugin = require('moment-locales-webpack-plugin'); module.exports = { mode: 'production', @@ -49,6 +50,7 @@ module.exports = { // historyApiFallback: true // }, plugins: [ + new MomentLocalesPlugin(), new CleanWebpackPlugin(), // new HtmlWebpackPlugin({ // title: 'Hot Module Replacement', diff --git a/pkg/interface/package.json b/pkg/interface/package.json index df701fd8a..2d7cc68fc 100644 --- a/pkg/interface/package.json +++ b/pkg/interface/package.json @@ -71,6 +71,7 @@ "eslint-plugin-react": "^7.19.0", "file-loader": "^6.0.0", "html-webpack-plugin": "^4.2.0", + "moment-locales-webpack-plugin": "^1.2.0", "react-dnd": "^11.1.3", "react-hot-loader": "^4.12.21", "sass": "^1.26.5", From 6794a930b5f9aefd9f5078a7af4d71e0e5f01312 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Tue, 13 Oct 2020 11:52:14 +1000 Subject: [PATCH 3/4] interface: rewrite lodash imports with babel Due to lodash's packaging mechanism, it is unable to treeshake unless you always import from it in a certain fashion. This commit adds a babel plugin to rewrite these imports for us. --- pkg/interface/config/webpack.prod.js | 1 + pkg/interface/package-lock.json | Bin 474948 -> 476336 bytes pkg/interface/package.json | 1 + pkg/interface/src/logic/lib/util.js | 21 +++++++----- .../landscape/components/Participants.tsx | 31 ++++++++---------- 5 files changed, 28 insertions(+), 26 deletions(-) diff --git a/pkg/interface/config/webpack.prod.js b/pkg/interface/config/webpack.prod.js index 99acbd028..be6bb5bbb 100644 --- a/pkg/interface/config/webpack.prod.js +++ b/pkg/interface/config/webpack.prod.js @@ -17,6 +17,7 @@ module.exports = { options: { presets: ['@babel/preset-env', '@babel/typescript', '@babel/preset-react'], plugins: [ + 'lodash', '@babel/transform-runtime', '@babel/plugin-proposal-object-rest-spread', '@babel/plugin-proposal-optional-chaining', diff --git a/pkg/interface/package-lock.json b/pkg/interface/package-lock.json index bac79dd3b023fcdfcda5faf20d27601eaa0265fa..812ebc3298bfdfb7d3a0b14b4cebf9bb2c351ac5 100644 GIT binary patch delta 804 zcmaKpPi)d~6vtBvY;)p*n^Va&8#ps%1xjJv4pS&>41w}T3T*LGN`XQt6iO+a^t9|? zvZXOUJsIyV8e?RMiP1!F#_Z(PgS(n6n&@dp$Tr={!%KeoyqEmm_w(NWo_M}->F!Ht zWE;Z4y%_8Q{%z=7@9j-!r>VS12AU0DtDIvi3f5j0<#?7tt%_)m5zbaX#Fyg1dOf+O z*gHx-L)EOfH73+oIvFX&`4WX9>5$rdxKJeW=~cfg#iSUK!&T2WOZV3{6gvg;)g0K` zfK4!F!+`O#76XrWAj4!2(~Y7Xv1jQl%Of?uS>OcZkRtt2)TEtG`q#px5T5jv(>z+J z5iAj?G--cuxwsapl&fK@uj!0XR7rNH6so@=E)fC3M=Qa>pGGSIAsR!E1E1 z9hV|ixecZsL38RPaYi-h2f)qOkZ};nvJ!1`EvO*n3-n*dR2EGlogFZ zJ-BStILzSPfqrzjMl)r)z#;-&0Z;C0roiqCNWbpcfqJFsdUoIkvqL#9pJ(f=zyR+< z=mPk$2QQlcGPalgFtF_(LtHjDfZjl6lMs=j)G`{R-OK!vBZY;6X%1`W7rYq&oz+{q zpZ4IdH%?brLF#E^Xr66=ryq1P;7dd6TC7x0HjoyZ?XP>Jx%cmX`@ncdb4A@B(o%6R z=awB&K1RjxKt|?55lInhgtt1Mt|V9L6iMP7!+DEjbjh1rU}axaZjz1yO5(|4uz-mu z8VLK!rB$>OcQ)t*lefDt0YJm>{7C=&Cvt=9di`YgnMJ$%eGoZPt9rI3!2U&e4!j-H z4O&hJ@2jh`Vw0=0$HVPAhi#9ZcLr4;Fh7?(MRIBR=Z zgrtV175JK%R)!Zll{$t5Bs+)c=lfeErnz~9RR)(=rkA<fs;`;WDZ{#@bv!E)|X`)g@d NAZFYCTAKZ+1^})qJyQSx diff --git a/pkg/interface/package.json b/pkg/interface/package.json index 2d7cc68fc..619ccae0f 100644 --- a/pkg/interface/package.json +++ b/pkg/interface/package.json @@ -64,6 +64,7 @@ "@typescript-eslint/parser": "^3.8.0", "babel-eslint": "^10.1.0", "babel-loader": "^8.1.0", + "babel-plugin-lodash": "^3.3.4", "babel-plugin-root-import": "^6.5.0", "clean-webpack-plugin": "^3.0.0", "cross-env": "^7.0.2", diff --git a/pkg/interface/src/logic/lib/util.js b/pkg/interface/src/logic/lib/util.js index 3de0e8515..fe3e07d76 100644 --- a/pkg/interface/src/logic/lib/util.js +++ b/pkg/interface/src/logic/lib/util.js @@ -1,4 +1,5 @@ import _ from 'lodash'; +import f from 'lodash/fp'; export const MOBILE_BROWSER_REGEX = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i; @@ -8,11 +9,12 @@ export function clamp(x,min,max) { // color is a #000000 color export function adjustHex(color, amount) { - const res = _.chain(color.slice(1)) - .split('').chunk(2) // get individual color channels - .map(c => parseInt(c.join(''), 16)) // as hex - .map(c => clamp(c + amount, 0, 255).toString(16)) // adjust - .join('').value(); + const res = f.flow( + f.split(''), f.chunk(2), // get individual color channels + f.map(c => parseInt(c.join(''), 16)), // as hex + f.map(c => clamp(c + amount, 0, 255).toString(16)), // adjust + f.join('') + )(color.slice(1)) return `#${res}`; } @@ -91,10 +93,11 @@ export function uxToHex(ux) { } export function hexToUx(hex) { - const ux = _.chain(hex.split('')) - .chunk(4) - .map(x => _.dropWhile(x, y => y === 0).join('')) - .join('.'); + const ux = f.flow( + f.chunk(4), + f.map(x => _.dropWhile(x, y => y === 0).join('')), + f.join('.') + )(hex.split('')) return `0x${ux}`; } diff --git a/pkg/interface/src/views/landscape/components/Participants.tsx b/pkg/interface/src/views/landscape/components/Participants.tsx index 374c8b6b8..20b30d50e 100644 --- a/pkg/interface/src/views/landscape/components/Participants.tsx +++ b/pkg/interface/src/views/landscape/components/Participants.tsx @@ -17,6 +17,7 @@ import { StatelessTextInput as Input, } from "@tlon/indigo-react"; import _ from "lodash"; +import f from "lodash/fp"; import VisibilitySensor from "react-visibility-sensor"; import { Contact, Contacts } from "~/types/contact-update"; @@ -90,7 +91,7 @@ const Tab = ({ selected, id, label, setSelected }) => ( borderBottom={selected === id ? 1 : 0} borderBottomColor="black" mr={2} - cursor='pointer' + cursor="pointer" onClick={() => setSelected(id)} > {label} @@ -141,11 +142,11 @@ export function Participants(props: { const filtered = useMemo( () => - _.chain(participants) - .filter(tabFilters[filter]) - .filter(searchParticipant(search)) - .chunk(8) - .value(), + f.flow( + f.filter(tabFilters[filter]), + f.filter(searchParticipant(search)), + f.chunk(8) + )(participants), [search, filter, participants] ); @@ -288,22 +289,18 @@ function Participant(props: { }); }, [api, association]); - const avatar = ( - (contact?.avatar !== null) && !props.hideAvatars) - ? - : ; + const avatar = + contact?.avatar !== null && !props.hideAvatars ? ( + + ) : ( + + ); const hasNickname = contact.nickname && !props.hideNicknames; return ( <> - - {avatar} - + {avatar} {hasNickname && ( From f14c0ee19e576eeade49ebc3ce6e5fbd358c08ed Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Wed, 14 Oct 2020 13:26:40 +1000 Subject: [PATCH 4/4] interface, glob: serve source maps externally --- pkg/arvo/app/glob.hoon | 35 +++++++++++++------ pkg/arvo/mar/map.hoon | 18 ++++++++++ pkg/interface/config/webpack.prod.js | 2 +- .../src/views/apps/chat/ChatResource.tsx | 1 + 4 files changed, 44 insertions(+), 12 deletions(-) create mode 100644 pkg/arvo/mar/map.hoon diff --git a/pkg/arvo/app/glob.hoon b/pkg/arvo/app/glob.hoon index 0d09b1959..3e111a29a 100644 --- a/pkg/arvo/app/glob.hoon +++ b/pkg/arvo/app/glob.hoon @@ -85,20 +85,33 @@ %glob-make :_ this =/ home=path /(scot %p our.bowl)/home/(scot %da now.bowl) - =+ .^(=tube:clay %cc (weld home /js/mime)) + =+ .^(=js=tube:clay %cc (weld home /js/mime)) + =+ .^(=map=tube:clay %cc (weld home /map/mime)) =+ .^(arch %cy (weld home /app/landscape/js/bundle)) - =/ bundle=path - %- need - ^- (unit path) + =/ bundle-hash=@t + %- need + ^- (unit @t) %- ~(rep by dir) - |= [[file=@t ~] out=(unit path)] + |= [[file=@t ~] out=(unit @t)] ?^ out out - ?. =((end 3 5 file) 'index') - ~ - `/[file]/js - =+ .^(js=@t %cx :(weld home /app/landscape/js/bundle bundle)) - =+ !<(=mime (tube !>(js))) - =/ =glob:glob (~(put by *glob:glob) bundle mime) + ?. ?& =((end 3 6 file) 'index.') + !=('sj.' (end 3 3 (swp 3 file))) + == + out + ``@t`(rsh 3 6 file) + =/ js-name + (cat 3 'index.' bundle-hash) + =/ map-name + (cat 3 js-name '.js') + =+ .^(js=@t %cx :(weld home /app/landscape/js/bundle /[js-name]/js)) + =+ .^(map=@t %cx :(weld home /app/landscape/js/bundle /[map-name]/map)) + =+ !<(=js=mime (js-tube !>(js))) + =+ !<(=map=mime (map-tube !>(map))) + =/ =glob:glob + %- ~(gas by *glob:glob) + :~ /[js-name]/js^js-mime + /[map-name]/map^map-mime + == =/ =path /(cat 3 'glob-' (scot %uv (sham glob)))/glob [%pass /make %agent [our.bowl %hood] %poke %drum-put !>([path (jam glob)])]~ :: diff --git a/pkg/arvo/mar/map.hoon b/pkg/arvo/mar/map.hoon new file mode 100644 index 000000000..2ef7c206d --- /dev/null +++ b/pkg/arvo/mar/map.hoon @@ -0,0 +1,18 @@ +:: +:::: /hoon/map/mar + :: Mark for js source maps +/? 310 +:: +=, eyre +|_ mud/@ +++ grow + |% + ++ mime [/application/octet-stream (as-octs:mimes:html (@t mud))] + -- +++ grab + |% :: convert from + ++ mime |=({p/mite q/octs} (@t q.q)) + ++ noun cord :: clam from %noun + -- +++ grad %mime +-- diff --git a/pkg/interface/config/webpack.prod.js b/pkg/interface/config/webpack.prod.js index be6bb5bbb..85f431360 100644 --- a/pkg/interface/config/webpack.prod.js +++ b/pkg/interface/config/webpack.prod.js @@ -43,7 +43,7 @@ module.exports = { resolve: { extensions: ['.js', '.ts', '.tsx'] }, - devtool: 'none', + devtool: 'source-map', // devServer: { // contentBase: path.join(__dirname, './'), // hot: true, diff --git a/pkg/interface/src/views/apps/chat/ChatResource.tsx b/pkg/interface/src/views/apps/chat/ChatResource.tsx index 59e8f5f5d..ec64f1a7b 100644 --- a/pkg/interface/src/views/apps/chat/ChatResource.tsx +++ b/pkg/interface/src/views/apps/chat/ChatResource.tsx @@ -1,6 +1,7 @@ import React, { useRef, useCallback } from "react"; import { RouteComponentProps } from "react-router-dom"; import { Col } from "@tlon/indigo-react"; +import _ from 'lodash'; import { Association } from "~/types/metadata-update"; import { StoreState } from "~/logic/store/type";