Add example shwing how to customise, make customising work and document all the ways in which browserify will break and how to work around it being dumb.

This commit is contained in:
David Baker 2015-07-06 14:13:02 +01:00
parent 7a8eae09ff
commit 6c35908949
7 changed files with 161 additions and 11 deletions

View file

@ -30,3 +30,10 @@ Note that you may need to restart the CSS builder if you add a new file. Note
that `npm start` builds debug versions of the the javascript and CSS, which are that `npm start` builds debug versions of the the javascript and CSS, which are
much larger than the production versions build by the `npm run build` commands. much larger than the production versions build by the `npm run build` commands.
IMPORTANT: If you customise components in your application (and hence require
react from your app) you must be sure to:
1. Make your app depend on react directly
2. If you `npm link` matrix-react-sdk, manually remove the 'react' directory
from matrix-react-sdk's `node_modules` folder, otherwise browserify will
pull in both copies of react which causes the app to break.

View file

@ -0,0 +1,40 @@
/*
Copyright 2015 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
var React = require('react');
var MTextTileController = require("matrix-react-sdk/src/controllers/molecules/MTextTile");
module.exports = React.createClass({
displayName: 'MTextTile',
mixins: [MTextTileController],
render: function() {
var content = this.props.mxEvent.getContent();
return (
<span className="mx_MTextTile" onClick={this.onClick}>
{content.body}
</span>
);
},
onClick: function(ev) {
global.alert(this.props.mxEvent.getContent().body);
}
});

View file

@ -0,0 +1,4 @@
matrix-react-example
====================
An example of how to use the Matrix React SDK to build a more customised app

View file

@ -0,0 +1,12 @@
<!doctype html>
<html lang="en" style="height: 100%; overflow: hidden">
<head>
<meta charset="utf-8">
<title>Matrix Flux</title>
</head>
<body style="height: 100%; ">
<section id="matrixchat" style="height: 100%; "></section>
<script src="bundle.js"></script>
<link rel="stylesheet" href="node_modules/matrix-react-sdk/bundle.css">
</body>
</html>

40
examples/custom/index.js Normal file
View file

@ -0,0 +1,40 @@
/*
Copyright 2015 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
// Remember to make your project depend on react directly as soon as
// you add a require('react') to any file in your project. Do not rely
// on react being pulled in via matrix-react-sdk: browserify breaks
// horribly in this situation and can end up pulling in multiple copies
// of react.
var React = require("react");
// We pull in the component broker first, separately, as we need to replace
// components before the SDK loads.
var ComponenetBroker = require("matrix-react-sdk/src/ComponentBroker");
var CustomMTextTile = require('./CustomMTextTile');
ComponenetBroker.set('molecules/MTextTile', CustomMTextTile);
var MatrixReactSdk = require("matrix-react-sdk");
//var MatrixReactSdk = require("../../src/index");
React.render(
<MatrixReactSdk.MatrixChat />,
document.getElementById('matrixchat')
);

View file

@ -0,0 +1,29 @@
{
"name": "matrix-react-example",
"version": "0.0.1",
"description": "Example usage of matrix-react-sdk",
"author": "matrix.org",
"repository": {
"type": "git",
"url": "https://github.com/matrix-org/matrix-react-sdk"
},
"license": "Apache-2.0",
"devDependencies": {
"browserify": "^10.2.3",
"envify": "^3.4.0",
"http-server": "^0.8.0",
"matrix-react-sdk": "../../",
"npm-css": "^0.2.3",
"parallelshell": "^1.2.0",
"reactify": "^1.1.1",
"uglify-js": "^2.4.23",
"watchify": "^3.2.1"
},
"scripts": {
"build": "browserify -t [ envify --NODE_ENV production ] -g reactify index.js | uglifyjs -c -m -o bundle.js",
"start": "parallelshell 'watchify -v -d -g reactify index.js -o bundle.js' 'http-server'"
},
"dependencies": {
"react": "^0.13.3"
}
}

View file

@ -16,31 +16,48 @@ limitations under the License.
'use strict'; 'use strict';
var components = {};
function load(name) { function load(name) {
var module = require("../skins/base/views/"+name); var module = require("../skins/base/views/"+name);
components[name] = module;
return module; return module;
}; };
module.exports = { var ComponentBroker = function() {
get: function(name) { this.components = {};
if (components[name]) return components[name]; };
components[name] = load(name); ComponentBroker.prototype = {
return components[name]; get: function(name) {
if (this.components[name]) {
return this.components[name];
}
this.components[name] = load(name);
return this.components[name];
}, },
set: function(name, module) { set: function(name, module) {
components[name] = module; this.components[name] = module;
} }
}; };
// Statically require all the components we know about, // We define one Component Broker globally, because the intention is
// otherwise browserify has no way of knowing what module to include // very much that it is a singleton. Relying on there only being one
// copy of the module can be dicey and not work as browserify's
// behaviour with multiple copies of files etc. is erratic at best.
// XXX: We can still end up with the same file twice in the resulting
// JS bundle which is nonideal.
if (global.componentBroker === undefined) {
global.componentBroker = new ComponentBroker();
}
module.exports = global.componentBroker;
// We need to tell browserify to include all the components
// by direct require syntax in here, but we don't want them
// to be evaluated in this file because then we wouldn't be
// able to override them. if (0) does this.
// Must be in this file (because the require is file-specific) and // Must be in this file (because the require is file-specific) and
// must be at the end because the components include this file. // must be at the end because the components include this file.
if (0) {
require('../skins/base/views/atoms/LogoutButton'); require('../skins/base/views/atoms/LogoutButton');
require('../skins/base/views/atoms/EnableNotificationsButton'); require('../skins/base/views/atoms/EnableNotificationsButton');
require('../skins/base/views/atoms/MessageTimestamp'); require('../skins/base/views/atoms/MessageTimestamp');
@ -62,3 +79,4 @@ require('../skins/base/views/organisms/RoomList');
require('../skins/base/views/organisms/RoomView'); require('../skins/base/views/organisms/RoomView');
require('../skins/base/views/templates/Login'); require('../skins/base/views/templates/Login');
require('../skins/base/views/organisms/Notifier'); require('../skins/base/views/organisms/Notifier');
}