MM-46274 Add ability to run Boards as a product in development
This commit is contained in:
parent
765fbc88e9
commit
d462d9a5d7
8 changed files with 2458 additions and 227 deletions
3
Makefile
3
Makefile
|
@ -186,6 +186,9 @@ watch-plugin: modd-precheck ## Run and upload the plugin to a development server
|
|||
live-watch-plugin: modd-precheck ## Run and update locally the plugin in the development server
|
||||
cd mattermost-plugin; make live-watch
|
||||
|
||||
watch-product: ## Run the product as something the Mattermost web app will watch for
|
||||
cd mattermost-plugin; make watch-product
|
||||
|
||||
mac-app: server-mac webapp ## Build Mac application.
|
||||
rm -rf mac/temp
|
||||
rm -rf mac/dist
|
||||
|
|
|
@ -175,6 +175,10 @@ endif
|
|||
deploy-from-watch: bundle
|
||||
./build/bin/pluginctl deploy $(PLUGIN_ID) dist/$(BUNDLE_NAME)
|
||||
|
||||
.PHONE: watch-product
|
||||
watch-product: apply
|
||||
cd webapp && npm run start:product
|
||||
|
||||
## Setup dlv for attaching, identifying the plugin PID for other targets.
|
||||
.PHONY: setup-attach
|
||||
setup-attach:
|
||||
|
|
2543
mattermost-plugin/webapp/package-lock.json
generated
2543
mattermost-plugin/webapp/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -11,7 +11,8 @@
|
|||
"test": "jest --forceExit --detectOpenHandles --verbose",
|
||||
"test:watch": "jest --watch",
|
||||
"test-ci": "jest --forceExit --detectOpenHandles --maxWorkers=2",
|
||||
"check-types": "tsc"
|
||||
"check-types": "tsc",
|
||||
"start:product": "webpack serve --mode=development"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "7.17.6",
|
||||
|
@ -78,7 +79,8 @@
|
|||
"ts-loader": "9.2.8",
|
||||
"typescript": "4.6.2",
|
||||
"webpack": "5.70.0",
|
||||
"webpack-cli": "4.9.2"
|
||||
"webpack-cli": "4.10.0",
|
||||
"webpack-dev-server": "4.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": "3.21.1",
|
||||
|
|
|
@ -14,9 +14,8 @@ import {selectTeam} from 'mattermost-redux/actions/teams'
|
|||
import {SuiteWindow} from '../../../webapp/src/types/index'
|
||||
import {UserSettings} from '../../../webapp/src/userSettings'
|
||||
|
||||
|
||||
const windowAny = (window as SuiteWindow)
|
||||
windowAny.baseURL = '/plugins/focalboard'
|
||||
windowAny.baseURL = process.env.TARGET_IS_PRODUCT ? '/plugins/boards' : '/plugins/focalboard'
|
||||
windowAny.frontendBaseURL = '/boards'
|
||||
windowAny.isFocalboardPlugin = true
|
||||
|
||||
|
@ -408,11 +407,3 @@ export default class Plugin {
|
|||
this.registry?.unregisterWebSocketEventHandler(wsClient.clientPrefix + ACTION_UPDATE_BLOCK)
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
registerPlugin(id: string, plugin: Plugin): void
|
||||
}
|
||||
}
|
||||
|
||||
window.registerPlugin(manifest.id, new Plugin())
|
||||
|
|
14
mattermost-plugin/webapp/src/plugin_entry.ts
Normal file
14
mattermost-plugin/webapp/src/plugin_entry.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import manifest from './manifest'
|
||||
|
||||
import Plugin from './index'
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
registerPlugin(id: string, plugin: Plugin): void
|
||||
}
|
||||
}
|
||||
|
||||
window.registerPlugin(manifest.id, new Plugin())
|
4
mattermost-plugin/webapp/src/remote_entry.ts
Normal file
4
mattermost-plugin/webapp/src/remote_entry.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import('./index')
|
|
@ -5,16 +5,21 @@ const exec = require('child_process').exec;
|
|||
const path = require('path');
|
||||
|
||||
const webpack = require('webpack');
|
||||
const {ModuleFederationPlugin} = require('webpack').container;
|
||||
|
||||
const tsTransformer = require('@formatjs/ts-transformer');
|
||||
|
||||
const PLUGIN_ID = require('../plugin.json').id;
|
||||
|
||||
const packageJson = require('./package.json');
|
||||
|
||||
const NPM_TARGET = process.env.npm_lifecycle_event; //eslint-disable-line no-process-env
|
||||
const TARGET_IS_PRODUCT = NPM_TARGET === 'start:product' || NPM_TARGET === 'build:product';
|
||||
|
||||
let mode = 'production';
|
||||
let devtool;
|
||||
const plugins = [];
|
||||
if (NPM_TARGET === 'debug' || NPM_TARGET === 'debug:watch') {
|
||||
if (NPM_TARGET === 'debug' || NPM_TARGET === 'debug:watch' || NPM_TARGET === 'start:product') {
|
||||
mode = 'development';
|
||||
devtool = 'source-map';
|
||||
plugins.push(
|
||||
|
@ -49,10 +54,8 @@ if (NPM_TARGET === 'build:watch' || NPM_TARGET === 'debug:watch' || NPM_TARGET =
|
|||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
entry: [
|
||||
'./src/index.tsx',
|
||||
],
|
||||
const config = {
|
||||
entry: TARGET_IS_PRODUCT ? './src/remote_entry.ts' : './src/plugin_entry.ts',
|
||||
resolve: {
|
||||
modules: [
|
||||
'src',
|
||||
|
@ -61,7 +64,6 @@ module.exports = {
|
|||
],
|
||||
alias: {
|
||||
moment: path.resolve(__dirname, '../../webapp/node_modules/moment/'),
|
||||
'react-intl': path.resolve(__dirname, '../../webapp/node_modules/react-intl/'),
|
||||
},
|
||||
extensions: ['*', '.js', '.jsx', '.ts', '.tsx'],
|
||||
},
|
||||
|
@ -120,30 +122,80 @@ module.exports = {
|
|||
},
|
||||
],
|
||||
},
|
||||
externals: {
|
||||
react: 'React',
|
||||
redux: 'Redux',
|
||||
'react-redux': 'ReactRedux',
|
||||
'mm-react-router-dom': 'ReactRouterDom',
|
||||
'prop-types': 'PropTypes',
|
||||
'react-bootstrap': 'ReactBootstrap',
|
||||
|
||||
},
|
||||
output: {
|
||||
devtoolNamespace: PLUGIN_ID,
|
||||
path: path.join(__dirname, '/dist'),
|
||||
publicPath: '/',
|
||||
filename: 'main.js',
|
||||
},
|
||||
devtool,
|
||||
mode,
|
||||
plugins,
|
||||
};
|
||||
|
||||
if (TARGET_IS_PRODUCT) {
|
||||
function makeSingletonSharedModules(packageNames) {
|
||||
const sharedObject = {};
|
||||
|
||||
for (const packageName of packageNames) {
|
||||
const version = packageJson.dependencies[packageName];
|
||||
|
||||
sharedObject[packageName] = {
|
||||
requiredVersion: version,
|
||||
singleton: true,
|
||||
version,
|
||||
};
|
||||
}
|
||||
|
||||
return sharedObject;
|
||||
}
|
||||
|
||||
config.plugins.push(new ModuleFederationPlugin({
|
||||
name: PLUGIN_ID,
|
||||
filename: 'remote_entry.js',
|
||||
exposes: {
|
||||
'.': './src/index',
|
||||
|
||||
// This probably won't need to be exposed in the long run, but its a POC for exposing multiple modules
|
||||
'./manifest': './src/manifest',
|
||||
},
|
||||
shared: [
|
||||
'@mattermost/client',
|
||||
'prop-types',
|
||||
|
||||
makeSingletonSharedModules([
|
||||
'react',
|
||||
'react-dom',
|
||||
'react-intl',
|
||||
'react-redux',
|
||||
'react-router-dom',
|
||||
]),
|
||||
],
|
||||
}));
|
||||
|
||||
config.plugins.push(new webpack.DefinePlugin({
|
||||
'process.env.TARGET_IS_PRODUCT': TARGET_IS_PRODUCT, // TODO We might want a better name for this
|
||||
}));
|
||||
} else {
|
||||
config.resolve.alias['react-intl'] = path.resolve(__dirname, '../../webapp/node_modules/react-intl/');
|
||||
|
||||
config.outputs = {
|
||||
devtoolNamespace: PLUGIN_ID,
|
||||
path: path.join(__dirname, '/dist'),
|
||||
publicPath: '/',
|
||||
filename: 'main.js',
|
||||
};
|
||||
}
|
||||
|
||||
const env = {};
|
||||
env.RUDDER_KEY = JSON.stringify(process.env.RUDDER_KEY || ''); //eslint-disable-line no-process-env
|
||||
env.RUDDER_DATAPLANE_URL = JSON.stringify(process.env.RUDDER_DATAPLANE_URL || ''); //eslint-disable-line no-process-env
|
||||
|
||||
module.exports.plugins.push(new webpack.DefinePlugin({
|
||||
config.plugins.push(new webpack.DefinePlugin({
|
||||
'process.env': env,
|
||||
}));
|
||||
|
||||
if (NPM_TARGET === 'start:product') {
|
||||
config.devServer = {
|
||||
port: 9006,
|
||||
devMiddleware: {
|
||||
writeToDisk: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = config;
|
||||
|
|
Loading…
Reference in a new issue