diff --git a/README.md b/README.md index a21157af6..835bdb2b7 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,14 @@ To build you will need to have [Node.js](https://nodejs.org/en/) and [Composer]( - Watch for changes `npm run watch` - Production build `npm run build` +### Faster frontend developing with HMR + +You can enable HMR (Hot module replacement) to avoid page reloads when working on the frontend: + +1. ☑️ Install and enable [`hmr_enabler` app](https://github.com/nextcloud/hmr_enabler) +2. 🏁 Run `npm run serve` +3. 🌍 Open the normal Nextcloud server URL (not the URL given by above command) + ### GitHub Codespaces / VS Code devcontainer - Open code spaces or the repository in VS Code to start the dev container diff --git a/package.json b/package.json index 7ddedaee8..f2781e52c 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "build": "NODE_ENV=production webpack --progress --config webpack.js", "dev": "NODE_ENV=development webpack --progress --config webpack.js", "watch": "NODE_ENV=development webpack --progress --watch --config webpack.js", + "serve": "webpack serve --node-env development --allowed-hosts all --config webpack.js", "lint": "eslint --ext .js,.vue src", "lint:fix": "eslint --ext .js,.vue src --fix", "lint:cypress": "eslint --ext .js cypress", diff --git a/src/init-calendar.js b/src/init-calendar.js index 51cc96c82..6c603432e 100644 --- a/src/init-calendar.js +++ b/src/init-calendar.js @@ -23,6 +23,8 @@ import { subscribe } from '@nextcloud/event-bus' import { generateUrl } from '@nextcloud/router' +import './shared-init.js' + subscribe('calendar:handle-todo-click', ({ calendarId, taskId }) => { const deckAppPrefix = 'app-generated--deck--board-' if (calendarId.startsWith(deckAppPrefix)) { diff --git a/src/init-collections.js b/src/init-collections.js index f26565ee4..a3f8ddd91 100644 --- a/src/init-collections.js +++ b/src/init-collections.js @@ -26,10 +26,7 @@ import './../css/collections.css' import FileSharingPicker from './views/FileSharingPicker.js' import { buildSelector } from './helpers/selector.js' -// eslint-disable-next-line -__webpack_nonce__ = btoa(OC.requestToken); -// eslint-disable-next-line -__webpack_public_path__ = OC.linkTo('deck', 'js/'); +import './shared-init.js' Vue.prototype.t = t Vue.prototype.n = n diff --git a/src/init-dashboard.js b/src/init-dashboard.js index 18be0c35b..9b579fb91 100644 --- a/src/init-dashboard.js +++ b/src/init-dashboard.js @@ -22,12 +22,9 @@ import './css/dashboard.scss' -const debug = process.env.NODE_ENV !== 'production' +import './shared-init.js' -// eslint-disable-next-line -__webpack_nonce__ = btoa(OC.requestToken); -// eslint-disable-next-line -__webpack_public_path__ = OC.linkTo('deck', 'js/'); +const debug = process.env.NODE_ENV !== 'production' document.addEventListener('DOMContentLoaded', () => { OCA.Dashboard.register('deck', async (el) => { diff --git a/src/init-reference.js b/src/init-reference.js index 08b804742..fa983ebcb 100644 --- a/src/init-reference.js +++ b/src/init-reference.js @@ -28,6 +28,8 @@ import CommentReferenceWidget from './views/CommentReferenceWidget.vue' import { translate, translatePlural } from '@nextcloud/l10n' +import './shared-init.js' + Vue.prototype.t = translate Vue.prototype.n = translatePlural Vue.prototype.OC = window.OC diff --git a/src/init-talk.js b/src/init-talk.js index 943cbe22b..7d798ad97 100644 --- a/src/init-talk.js +++ b/src/init-talk.js @@ -27,10 +27,7 @@ import CardCreateDialog from './CardCreateDialog.vue' import { buildSelector } from './helpers/selector.js' import './init-collections.js' -// eslint-disable-next-line -__webpack_nonce__ = btoa(OC.requestToken); -// eslint-disable-next-line -__webpack_public_path__ = OC.linkTo('deck', 'js/'); +import './shared-init.js' Vue.prototype.t = t Vue.prototype.n = n diff --git a/src/main.js b/src/main.js index 8f519b11e..bfb7d761c 100644 --- a/src/main.js +++ b/src/main.js @@ -25,23 +25,17 @@ import router from './router.js' import store from './store/main.js' import { sync } from 'vuex-router-sync' import { translate, translatePlural } from '@nextcloud/l10n' -import { generateFilePath } from '@nextcloud/router' import { showError } from '@nextcloud/dialogs' import { subscribe } from '@nextcloud/event-bus' import { Tooltip } from '@nextcloud/vue' import ClickOutside from 'vue-click-outside' +import './shared-init.js' import './models/index.js' import './sessions.js' // the server snap.js conflicts with vertical scrolling so we disable it document.body.setAttribute('data-snap-ignore', 'true') -// eslint-disable-next-line -__webpack_nonce__ = btoa(OC.requestToken) -if (!process.env.HOT) { - // eslint-disable-next-line - __webpack_public_path__ = generateFilePath('deck', '', 'js/') -} sync(store, router) Vue.prototype.t = translate diff --git a/src/shared-init.js b/src/shared-init.js new file mode 100644 index 000000000..9752aee3a --- /dev/null +++ b/src/shared-init.js @@ -0,0 +1,12 @@ +import { generateFilePath } from '@nextcloud/router' + +// eslint-disable-next-line +__webpack_nonce__ = btoa(OC.requestToken) + +if (!process.env.WEBPACK_SERVE) { + // eslint-disable-next-line + __webpack_public_path__ = generateFilePath('deck', '', 'js/') +} else { + // eslint-disable-next-line + __webpack_public_path__ = 'http://127.0.0.1:3000/' +} diff --git a/webpack.hot.js b/webpack.hot.js deleted file mode 100644 index 5c8e113b7..000000000 --- a/webpack.hot.js +++ /dev/null @@ -1,26 +0,0 @@ -const webpack = require('webpack'); -const merge = require('webpack-merge'); -const dev = require('./webpack.dev.js'); - -module.exports = merge(dev, { - devServer: { - hot: true, - port: 3000, - /** - * This makes sure the main entrypoint is written to disk so it is - * loaded by Nextcloud though our existing addScript calls - */ - writeToDisk: (filePath) => { - return /deck\.js$/.test(filePath); - }, - headers: { - 'Access-Control-Allow-Origin': '*' - } - }, - plugins: [ - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), - 'process.env.HOT': true - }) - ] -}) diff --git a/webpack.js b/webpack.js index 2a7ce762d..2b32457bb 100644 --- a/webpack.js +++ b/webpack.js @@ -1,8 +1,9 @@ const webpackConfig = require('@nextcloud/webpack-vue-config') +const webpack = require('webpack') const path = require('path') const buildMode = process.env.NODE_ENV -const isDev = buildMode === 'development' +const isDevServer = process.env.WEBPACK_SERVE webpackConfig.entry = { ...webpackConfig.entry, @@ -13,14 +14,22 @@ webpackConfig.entry = { reference: path.join(__dirname, 'src', 'init-reference.js'), } -webpackConfig.stats = { - context: path.resolve(__dirname, 'src'), - assets: true, - entrypoints: true, - chunks: true, - modules: true, +if (isDevServer) { + webpackConfig.output.publicPath = 'http://127.0.0.1:3000/' + webpackConfig.plugins.push( + new webpack.DefinePlugin({ + 'process.env.WEBPACK_SERVE': true, + }) + ) +} else { + webpackConfig.stats = { + context: path.resolve(__dirname, 'src'), + assets: true, + entrypoints: true, + chunks: true, + modules: true, + } } - // Workaround for https://github.com/nextcloud/webpack-vue-config/pull/432 causing problems with nextcloud-vue-collections webpackConfig.resolve.alias = {}