I'm trying to create an Electron-based application, and I'm preparing it for distribution. During development, I'd like to serve my files using Webpack's hot reload server.
I've had this working for a while and I'm able to perform hot reloads just fine - if I modify a *.tsx file, I can see the change rendered in the app within a few seconds.
However, if I try to force reload the application (via the Ctrl+R shortcut electron-debug
exposes), I frequently end up with console errors like this:
txDefinitions:1 GET http://127.0.0.1:1212/txDefinitions 404 (Not Found)
VM100 inject.js:20 Refused to execute inline script because it violates the following Content Security Policy directive: "default-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-WmbEu4eDLdH+hVT61zcbSRd5/NZfakiDSshvOiu8aVM='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.
module.exports @ VM100 inject.js:20
__webpack_require__ @ VM100 inject.js:11
(anonymous) @ VM100 inject.js:16
(anonymous) @ VM100 inject.js:17
runContentScript @ C:\Users\<me>\WebstormProjects\<product>\node_modules\electron\dist\resources\el…:23
onceWrapper @ events.js:293
emitNone @ events.js:91
emit @ events.js:188
VM102 pagewrap.bundle.js:3 Refused to execute inline script because it violates the following Content Security Policy directive: "default-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-7YtVEVH7kw4pB6y76DBpIzGrzbhYaS5jbslO0CKXyxc='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.
Additionally, my application looks like this:
In this case, I tried reloading after having navigated to /txDefinitions
.
The only situation in which a 404 error does not occur is immediately after launching the dev server, before attempting any navigation. In this case, I get back the index page. I would like to configure it so that it always reloads the index page when I force-reload the application - as if I had just started up the dev server - regardless of where I'd previously navigated to.
My configuration is largely based off that of electron-react-boilerplate
. Below are the parts of my codebase I think are most relevant:
webpack.config.renderer.dev.js
/* Imports */
const port = process.env.PORT || 1212
const publicPath = `http://127.0.0.1:${port}/dist`
const outputPath = path.resolve(__dirname, 'app/dist')
export default merge.smart(baseConfig, {
devtool: 'inline-source-map',
target: 'electron-renderer',
entry: {
'app': [
'react-hot-loader/patch',
`webpack-dev-server/client?http://127.0.0.1:${port}/`,
'webpack/hot/only-dev-server',
'./app/index.tsx'
]
},
output: {
path: outputPath,
filename: '[name].js',
publicPath
},
/* ... */
devServer: {
port,
publicPath,
contentBase: outputPath,
inline: true,
lazy: false,
hot: true,
headers: {'Access-Control-Allow-Origin': '*'},
historyApiFallback: {
verbose: true,
disableDotRule: false
},
setup () {
if (process.env.START_HOT) {
spawn(
'npm',
['run', 'start-hot-renderer'],
{shell: true, env: process.env, stdio: 'inherit'}
)
.on('close', code => process.exit(code))
.on('error', spawnError => console.error(spawnError))
}
}
}
})
webpack.config.main.js
import * as path from 'path'
import * as merge from 'webpack-merge'
import baseConfig from './webpack.config.base.js'
export default merge.smart(baseConfig, {
devtool: 'source-map',
target: 'electron-main',
entry: './app/main.development',
output: {
path: path.resolve(__dirname, 'app'),
filename: 'main.js',
libraryTarget: 'commonjs2'
}
})
app/main.development.ts
import {app, BrowserWindow} from 'electron';
import * as path from 'path';
import * as url from 'url';
import {REDUX_ACTION_IPC_CHANNEL} from './constants';
import createMenu from './menu';
let mainWindow;
const createDispatch = (window: Electron.BrowserWindow) =>
(action: any) => window.webContents.send(REDUX_ACTION_IPC_CHANNEL, action);
function getAppURL () {
if (process.env.NODE_ENV === 'development') {
const port = process.env.PORT || 1212;
return url.format({
pathname: `127.0.0.1:${port}/dist/app.html`,
protocol: 'http:',
slashes: true
});
} else {
return url.format({
pathname: path.join(__dirname, 'dist/app.html'),
protocol: 'file:',
slashes: true
});
}
}
if (process.env.NODE_ENV === 'development') {
require('electron-debug')();
const p = path.join(__dirname, '..', 'app', 'node_modules');
require('module').globalPaths.push(p);
}
function installExtensions () {
if (process.env.NODE_ENV === 'development') {
const installer = require('electron-devtools-installer');
const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
const extensions = [
'REACT_DEVELOPER_TOOLS',
'REDUX_DEVTOOLS'
];
return Promise
.all(extensions.map((name) => installer.default(installer[name], forceDownload)))
.catch(console.log);
}
return Promise.resolve([]);
}
function createWindow () {
mainWindow = new BrowserWindow({width: 800, height: 600});
const dispatch = createDispatch(mainWindow);
const menu = createMenu(dispatch);
mainWindow.setMenu(menu);
mainWindow.loadURL(getAppURL());
if (process.env.NODE_ENV === 'development') {
mainWindow.webContents.openDevTools();
}
mainWindow.on('closed', () => {
mainWindow = null;
});
}
app.on('ready', () => installExtensions().then(createWindow));
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (mainWindow === null) {
createWindow();
}
});
app/index.tsx
/* Imports */
const history = createHistory();
const sagaMonitor = isDev ? createSagaMonitor() : undefined;
const sagaView = isDev ? <DockableSagaView monitor={sagaMonitor}/> : null;
const store = createStore(undefined, sagaMonitor, history);
ipcRenderer.on(REDUX_ACTION_IPC_CHANNEL, (_, action) => store.dispatch(action));
const render = (Component) =>
ReactDOM.render(
<AppContainer>
<div>
<Provider store={store}>
<HotKeys className='hotkeys' keyMap={keyMap}>
{Component()}
</HotKeys>
</Provider>
{sagaView}
</div>
</AppContainer>,
document.getElementById('root')
);
render(() => Routing(history));
// Hot Module Replacement API
if ((module as any).hot) {
(module as any).hot.accept('./routes', () => {
const NextRouter = require('./routes').default;
render(() => NextRouter(history));
});
}
package.json
"hot-updates-server": "cross-env NODE_ENV=development node --trace-warnings -r babel-register ./node_modules/webpack-dev-server/bin/webpack-dev-server --config webpack.config.renderer.dev.js",
"start-hot-renderer": "cross-env HOT=1 NODE_ENV=development electron -r ts-node/register -r babel-register ./app/main.development",
"dev": "cross-env START_HOT=1 npm run hot-updates-server"
Finally, an example of the logs I see in my IDE when I execute npm run dev
, navigate to /txDefinitions
and try force-reloading the application:
C:\Users\<me>\WebstormProjects\<product>>npm run dev
> @<company>/<product>@0.1.0 dev C:\Users\<me>\WebstormProjects\<product>
> cross-env START_HOT=1 npm run hot-updates-server
> @<company>/<product>@0.1.0 hot-updates-server C:\Users\<me>\WebstormProjects\<product>
> cross-env NODE_ENV=development node --trace-warnings -r babel-register ./node_modules/webpack-dev-server/bin/webpack-dev-server --config webpack.config.renderer.dev.js
Project is running at http://localhost:1212/
webpack output is served from http://127.0.0.1:1212/dist
Content not from webpack is served from C:\Users\<me>\WebstormProjects\<product>\app\dist
404s will fallback to /index.html
[at-loader] Using typescript@2.3.2 from typescript and "tsconfig.json" from C:\Users\<me>\WebstormProjects\<product>/tsconfig.json.
> @<company>/<product>@0.1.0 start-hot-renderer C:\Users\<me>\WebstormProjects\<product>
> cross-env HOT=1 NODE_ENV=development electron -r ts-node/register -r babel-register ./app/main.development
webpack: wait until bundle finished: /dist/app.html
[at-loader] Checking started in a separate process...
[at-loader] Ok, 0.863 sec.
Hash: 0bef45449bb336ed5781
Version: webpack 2.5.1
Time: 25285ms
Asset Size Chunks Chunk Names
af7ae505a9eed503f8b8e6982036873e.woff2 77.2 kB [emitted]
f4769f9bdb7466be65088239c12046d1.eot 20.1 kB [emitted]
e18bbf611f2a2e43afc071aa2f4e1512.ttf 45.4 kB [emitted]
fa2772327f55d8198301fdb8bcfc8158.woff 23.4 kB [emitted]
448c34a56d699c29117adc64c43affeb.woff2 18 kB [emitted]
674f50d287a8c48dc19ba404d20fe713.eot 166 kB [emitted]
912ec66d7572ff821749319396470bde.svg 444 kB [emitted] [big]
b06871f281fee6b241d60582ae9369b9.ttf 166 kB [emitted]
89889688147bd7575d6327160d64e760.svg 109 kB [emitted]
fee66e712a8a08eef5805a46892932ad.woff 98 kB [emitted]
vendor.js 17.2 MB 0 [emitted] [big] vendor
app.js 478 kB 1 [emitted] [big] app
manifest.js 73.7 kB 2 [emitted] manifest
base.css 195 kB 1 [emitted] app
modules.css 23.4 kB 1 [emitted] app
app.html 934 bytes [emitted]
chunk {0} vendor.js (vendor) 6 MB {2} [initial] [rendered]
[./node_modules/react-dom/index.js] ./~/react-dom/index.js 59 bytes {0} [built]
[./node_modules/react-hot-loader/index.js] ./~/react-hot-loader/index.js 41 bytes {0} [built]
[./node_modules/react-hot-loader/lib/patch.js] ./~/react-hot-loader/lib/patch.js 209 bytes {0} [built]
[./node_modules/react-hot-loader/patch.js] ./~/react-hot-loader/patch.js 41 bytes {0} [built]
[./node_modules/react-redux/es/index.js] ./~/react-redux/es/index.js 230 bytes {0} [built]
[./node_modules/redux-saga-devtools/lib/index.js] ./~/redux-saga-devtools/lib/index.js 943 bytes {0} [built]
[./node_modules/strip-ansi/index.js] ./~/strip-ansi/index.js 161 bytes {0} [built]
[./node_modules/webpack-dev-server/client/index.js?http:/127.0.0.1:1212] (webpack)-dev-server/client?http://127.0.0.1:1212/ 5.68 kB {0} [built]
[./node_modules/webpack-dev-server/client/index.js?http:/localhost:1212] (webpack)-dev-server/client?http://localhost:1212 5.68 kB {0} [built]
[./node_modules/webpack-dev-server/client/overlay.js] (webpack)-dev-server/client/overlay.js 3.73 kB {0} [built]
[./node_modules/webpack-dev-server/client/socket.js] (webpack)-dev-server/client/socket.js 897 bytes {0} [built]
[./node_modules/webpack/hot/dev-server.js] (webpack)/hot/dev-server.js 1.57 kB {0} [built]
[./node_modules/webpack/hot/emitter.js] (webpack)/hot/emitter.js 77 bytes {0} [built]
[./node_modules/webpack/hot/log-apply-result.js] (webpack)/hot/log-apply-result.js 1.02 kB {0} [built]
[./node_modules/webpack/hot/only-dev-server.js] (webpack)/hot/only-dev-server.js 2.29 kB {0} [built]
+ 2025 hidden modules
chunk {1} app.js, base.css, modules.css (app) 167 kB {0} [initial] [rendered]
[./app/constants.ts] ./app/constants.ts 851 bytes {1} [built]
[./app/index.tsx] ./app/index.tsx 2.5 kB {1} [built]
[./app/keymap.json] ./app/keymap.json 47 bytes {1} [built]
[./app/routes.tsx] ./app/routes.tsx 3.5 kB {1} [built]
[./app/state/store.dev.ts] ./app/state/store.dev.ts 1.92 kB {1} [built]
[./app/state/store.prod.ts] ./app/state/store.prod.ts 1.54 kB {1} [built]
[./app/state/store.ts] ./app/state/store.ts 1 kB {1} [built]
[./app/util.ts] ./app/util.ts 846 bytes {1} [built]
[./app/views/app.global.css] ./app/views/app.global.css 41 bytes {1} [built]
[./app/views/containers/Notifications/Notifications.ts] ./app/views/containers/Notifications/Notifications.ts 1.24 kB {1} [built]
[13] multi (webpack)-dev-server/client?http://localhost:1212 webpack/hot/dev-server react-hot-loader/patch webpack-dev-server/client?http://127.0.0.1:1212/ webpack/hot/only-dev-server ./app/index.tsx 88 bytes {1} [built]
[./app/views/containers/SideBar/SideBar.ts] ./app/views/containers/SideBar/SideBar.ts 1.39 kB {1} [built]
[./app/views/containers/candb/index.ts] ./app/views/containers/candb/index.ts 1.34 kB {1} [built]
[./app/views/containers/index.ts] ./app/views/containers/index.ts 1.36 kB {1} [built]
[./app/views/layouts/Page/Page.tsx] ./app/views/layouts/Page/Page.tsx 1.36 kB {1} [built]
+ 69 hidden modules
chunk {2} manifest.js (manifest) 0 bytes [entry] [rendered]
Child html-webpack-plugin for "app.html":
chunk {0} app.html 547 kB [entry] [rendered]
[./node_modules/html-webpack-plugin/lib/loader.js!./node_modules/html-webpack-template/index.ejs] ./~/html-webpack-plugin/lib/loader.js!./~/html-webpack-template/index.ejs 6.74 kB {0} [built]
[./node_modules/lodash/lodash.js] ./~/lodash/lodash.js 540 kB {0} [built]
[./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 517 bytes {0} [built]
Child extract-text-webpack-plugin:
chunk {0} extract-text-webpack-plugin-output-filename 211 kB [entry] [rendered]
[./node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.eot] ./~/bootstrap/dist/fonts/glyphicons-halflings-regular.eot 82 bytes {0} [built]
[./node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.svg] ./~/bootstrap/dist/fonts/glyphicons-halflings-regular.svg 82 bytes {0} [built]
[./node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf] ./~/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf 82 bytes {0} [built]
[./node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.woff] ./~/bootstrap/dist/fonts/glyphicons-halflings-regular.woff 83 bytes {0} [built]
[./node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2] ./~/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 84 bytes {0} [built]
[./node_modules/css-loader/index.js?source-map&camelCase!./app/views/app.global.css] ./~/css-loader?source-map&camelCase!./app/views/app.global.css 863 bytes {0} [built]
[./node_modules/css-loader/index.js?source-map&camelCase!./node_modules/bootstrap/dist/css/bootstrap.css] ./~/css-loader?source-map&camelCase!./~/bootstrap/dist/css/bootstrap.css 154 kB {0} [built]
[./node_modules/css-loader/index.js?source-map&camelCase!./node_modules/font-awesome/css/font-awesome.css] ./~/css-loader?source-map&camelCase!./~/font-awesome/css/font-awesome.css 42 kB {0} [built]
[./node_modules/css-loader/index.js?source-map&camelCase!./node_modules/react-bootstrap-table/dist/react-bootstrap-table-all.min.css] ./~/css-loader?source-map&camelCase!./~/react-bootstrap-table/dist/react-bootstrap-table-all.min.css 11.2 kB {0} [built]
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
[./node_modules/font-awesome/fonts/fontawesome-webfont.eot] ./~/font-awesome/fonts/fontawesome-webfont.eot 82 bytes {0} [built]
[./node_modules/font-awesome/fonts/fontawesome-webfont.eot?v=4.7.0] ./~/font-awesome/fonts/fontawesome-webfont.eot?v=4.7.0 82 bytes {0} [built]
[./node_modules/font-awesome/fonts/fontawesome-webfont.svg?v=4.7.0] ./~/font-awesome/fonts/fontawesome-webfont.svg?v=4.7.0 82 bytes {0} [built]
[./node_modules/font-awesome/fonts/fontawesome-webfont.ttf?v=4.7.0] ./~/font-awesome/fonts/fontawesome-webfont.ttf?v=4.7.0 82 bytes {0} [built]
[./node_modules/font-awesome/fonts/fontawesome-webfont.woff2?v=4.7.0] ./~/font-awesome/fonts/fontawesome-webfont.woff2?v=4.7.0 84 bytes {0} [built]
+ 1 hidden modules
Child extract-text-webpack-plugin:
chunk {0} extract-text-webpack-plugin-output-filename 2.92 kB [entry] [rendered]
[./node_modules/css-loader/index.js?modules&sourceMap&camelCase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./node_modules/sass-loader/lib/loader.js!./app/views/layouts/Page/Page.scss] ./~/css-loader?modules&sourceMap&camelCase&impor
tLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./~/sass-loader/lib/loader.js!./app/views/layouts/Page/Page.scss 665 bytes {0} [built]
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
Child extract-text-webpack-plugin:
chunk {0} extract-text-webpack-plugin-output-filename 6.97 kB [entry] [rendered]
[./node_modules/css-loader/index.js?modules&sourceMap&camelCase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./node_modules/sass-loader/lib/loader.js!./app/views/components/PropertyFormView/PropertyFormView.scss] ./~/css-loader?module
s&sourceMap&camelCase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./~/sass-loader/lib/loader.js!./app/views/components/PropertyFormView/PropertyFormView.scss 4.71 kB {0} [built]
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
Child extract-text-webpack-plugin:
chunk {0} extract-text-webpack-plugin-output-filename 6.77 kB [entry] [rendered]
[./node_modules/css-loader/index.js?modules&sourceMap&camelCase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./node_modules/sass-loader/lib/loader.js!./app/views/components/DetailPane/DetailPane.scss] ./~/css-loader?modules&sourceMap&
camelCase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./~/sass-loader/lib/loader.js!./app/views/components/DetailPane/DetailPane.scss 4.51 kB {0} [built]
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
Child extract-text-webpack-plugin:
chunk {0} extract-text-webpack-plugin-output-filename 5.96 kB [entry] [rendered]
[./node_modules/css-loader/index.js?modules&sourceMap&camelCase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./node_modules/sass-loader/lib/loader.js!./app/views/components/TreeView/TreeView.scss] ./~/css-loader?modules&sourceMap&came
lCase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./~/sass-loader/lib/loader.js!./app/views/components/TreeView/TreeView.scss 3.7 kB {0} [built]
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
Child extract-text-webpack-plugin:
chunk {0} extract-text-webpack-plugin-output-filename 4.07 kB [entry] [rendered]
[./node_modules/css-loader/index.js?modules&sourceMap&camelCase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./node_modules/sass-loader/lib/loader.js!./app/views/components/AboutModal/AboutModal.scss] ./~/css-loader?modules&sourceMap&
camelCase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./~/sass-loader/lib/loader.js!./app/views/components/AboutModal/AboutModal.scss 1.81 kB {0} [built]
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
Child extract-text-webpack-plugin:
chunk {0} extract-text-webpack-plugin-output-filename 4.56 kB [entry] [rendered]
[./node_modules/css-loader/index.js?modules&sourceMap&camelCase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./node_modules/sass-loader/lib/loader.js!./app/views/components/candb/DefinitionForm/DefinitionForm.scss] ./~/css-loader?modu
les&sourceMap&camelCase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./~/sass-loader/lib/loader.js!./app/views/components/candb/DefinitionForm/DefinitionForm.scss 2.3 kB {0} [built]
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
Child extract-text-webpack-plugin:
chunk {0} extract-text-webpack-plugin-output-filename 6.85 kB [entry] [rendered]
[./node_modules/css-loader/index.js?modules&sourceMap&camelCase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./node_modules/sass-loader/lib/loader.js!./app/views/components/SideBar/SideBar.scss] ./~/css-loader?modules&sourceMap&camelC
ase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./~/sass-loader/lib/loader.js!./app/views/components/SideBar/SideBar.scss 4.59 kB {0} [built]
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
Child extract-text-webpack-plugin:
chunk {0} extract-text-webpack-plugin-output-filename 3.15 kB [entry] [rendered]
[./node_modules/css-loader/index.js?modules&sourceMap&camelCase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./node_modules/sass-loader/lib/loader.js!./app/views/components/candb/CreateDefinitionModal/CreateDefinitionModal.scss] ./~/c
ss-loader?modules&sourceMap&camelCase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./~/sass-loader/lib/loader.js!./app/views/components/candb/CreateDefinitionModal/CreateDefinitionModal.scss 892 bytes {0} [built]
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
Child extract-text-webpack-plugin:
chunk {0} extract-text-webpack-plugin-output-filename 4.6 kB [entry] [rendered]
[./node_modules/css-loader/index.js?modules&sourceMap&camelCase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./node_modules/sass-loader/lib/loader.js!./app/views/components/_shared.scss] ./~/css-loader?modules&sourceMap&camelCase&impo
rtLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./~/sass-loader/lib/loader.js!./app/views/components/_shared.scss 2.34 kB {0} [built]
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
Child extract-text-webpack-plugin:
chunk {0} extract-text-webpack-plugin-output-filename 7.5 kB [entry] [rendered]
[./node_modules/css-loader/index.js?modules&sourceMap&camelCase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./node_modules/sass-loader/lib/loader.js!./app/views/components/candb/DefinitionTable/DefinitionTable.scss] ./~/css-loader?mo
dules&sourceMap&camelCase&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]!./~/sass-loader/lib/loader.js!./app/views/components/candb/DefinitionTable/DefinitionTable.scss 5.24 kB {0} [built]
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
webpack: Compiled successfully.
Rewriting GET /txDefinitions to /index.html
Edit
In case it's helpful, these are the logs I see immediately after launching the application:
dev-server.js:49 [HMR] Waiting for update signal from WDS...
only-dev-server.js:66 [HMR] Waiting for update signal from WDS...
warning.js:36 Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead.
redux-logger.js:1 action @@router/LOCATION_CHANGE @ 12:42:17.215
client?fd75:45 [WDS] Disconnected!
I see the 'waiting for update signal...' log twice, which is the same thing that happens with the Electron react boilerplate code anyway. Although I see a 'Disconnected!' log soon after, hot updates still work fine.
Edit 2
I have made significant progress by following @echizen's answer here and making the following change within webpack.config.renderer.dev.js
:
/* ... */
historyApiFallback: {
index: `${publicPath}/app.html`, // Added this
verbose: true,
disableDotRule: false
},
/* ... */
This now allows my application to reload the same path as it was on previously.
While this is a significant step forward, it's not exactly what I want. I'm creating an editor, meaning some of the navigation paths are dynamic and dependant on the document I have loaded. After performing a page reload, the Redux state is reset, meaning some of the paths become invalid and generating a 404 error if I was at that point before performing the reload.
I'd like to see if there's a way I can get the application to always reset to the index page on reload.