Merge pull request #3129 from urbit/lf/hot-reload-redux

interface: add HMR to hot reloading config
This commit is contained in:
matildepark 2020-07-15 19:54:59 -04:00 committed by GitHub
commit 515c1f2303
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 109 additions and 9 deletions

View File

@ -88,6 +88,23 @@ hygiene][contributing].
[contributing]: /CONTRIBUTING.md#git-practice [arvo]: /pkg/arvo
[interface]:/pkg/interface
### Webpack Dev Server
If you are only intending to test the JS on one ship, then you may use the
webpack dev server to allow for HMR. To do this, uncomment the `URL` property
in your urbitrc and replace it with the URL of the urbit that you are testing
on. e.g.
```javascript
module.exports = {
URL: 'http://localhost:80'
}
```
and then run `npm run start` as usual. You can then access a hot reloaded
version of the interface at `http://localhost:9000`. Note that this also works
for non-locally hosted ships.
## Linting
The Urbit interface uses Eslint to lint the JavaScript code. To install the

View File

@ -2,5 +2,6 @@ module.exports = {
URBIT_PIERS: [
"/Users/user/ships/zod/home",
],
herb: false
herb: false,
// URL: 'http://localhost:80'
};

View File

@ -60,6 +60,32 @@ class UrbitShipPlugin {
}
}
let devServer = {
contentBase: path.join(__dirname, '../dist'),
hot: true,
port: 9000,
historyApiFallback: true
}
if(urbitrc.URL) {
devServer = {
...devServer,
index: '',
proxy: {
'/~landscape/js/index.js': {
target: 'http://localhost:9000',
pathRewrite: (req, path) => '/index.js'
},
'**': {
target: urbitrc.URL,
// ensure proxy doesn't timeout channels
proxyTimeout: 0
}
}
}
}
module.exports = {
mode: 'development',
entry: {
@ -76,7 +102,8 @@ module.exports = {
plugins: [
'@babel/plugin-proposal-object-rest-spread',
'@babel/plugin-proposal-optional-chaining',
'@babel/plugin-proposal-class-properties'
'@babel/plugin-proposal-class-properties',
'react-hot-loader/babel'
]
}
},
@ -99,12 +126,7 @@ module.exports = {
extensions: ['.js', '.ts', '.tsx']
},
devtool: 'inline-source-map',
devServer: {
contentBase: path.join(__dirname, '../dist'),
hot: true,
port: 9000,
historyApiFallback: true
},
devServer: devServer,
plugins: [
new UrbitShipPlugin(urbitrc)
// new CleanWebpackPlugin(),

View File

@ -3510,6 +3510,12 @@
"entities": "^2.0.0"
}
},
"dom-walk": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==",
"dev": true
},
"domain-browser": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
@ -4761,6 +4767,16 @@
"is-glob": "^4.0.1"
}
},
"global": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz",
"integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
"dev": true,
"requires": {
"min-document": "^2.19.0",
"process": "^0.11.10"
}
},
"global-modules": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
@ -6113,6 +6129,15 @@
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true
},
"min-document": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
"integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
"dev": true,
"requires": {
"dom-walk": "^0.1.0"
}
},
"mini-create-react-context": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.3.2.tgz",
@ -7327,11 +7352,41 @@
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz",
"integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw=="
},
"react-hot-loader": {
"version": "4.12.21",
"resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-4.12.21.tgz",
"integrity": "sha512-Ynxa6ROfWUeKWsTHxsrL2KMzujxJVPjs385lmB2t5cHUxdoRPGind9F00tOkdc1l5WBleOF4XEAMILY1KPIIDA==",
"dev": true,
"requires": {
"fast-levenshtein": "^2.0.6",
"global": "^4.3.0",
"hoist-non-react-statics": "^3.3.0",
"loader-utils": "^1.1.0",
"prop-types": "^15.6.1",
"react-lifecycles-compat": "^3.0.4",
"shallowequal": "^1.1.0",
"source-map": "^0.7.3"
},
"dependencies": {
"source-map": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
"dev": true
}
}
},
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"react-lifecycles-compat": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==",
"dev": true
},
"react-markdown": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-4.3.1.tgz",

View File

@ -46,6 +46,7 @@
"eslint-plugin-react": "^7.19.0",
"file-loader": "^6.0.0",
"html-webpack-plugin": "^4.2.0",
"react-hot-loader": "^4.12.21",
"sass": "^1.26.5",
"sass-loader": "^8.0.2",
"webpack": "^4.43.0",

View File

@ -1,3 +1,5 @@
import { hot } from 'react-hot-loader/root';
import 'react-hot-loader';
import * as React from 'react';
import { BrowserRouter as Router, Route, withRouter, Switch } from 'react-router-dom';
import styled, { ThemeProvider, createGlobalStyle } from 'styled-components';
@ -45,7 +47,7 @@ const Content = styled.div`
const StatusBarWithRouter = withRouter(StatusBar);
export default class App extends React.Component {
class App extends React.Component {
constructor(props) {
super(props);
this.ship = window.ship;
@ -152,3 +154,5 @@ export default class App extends React.Component {
}
}
export default process.env.NODE_ENV === 'production' ? App : hot(App);