kadirahq / mantra Goto Github PK
View Code? Open in Web Editor NEWMantra - An Application Architecture for Meteor
Home Page: https://kadirahq.github.io/mantra/
Mantra - An Application Architecture for Meteor
Home Page: https://kadirahq.github.io/mantra/
Once we have the spec finalized do we have plans for how we're going to host the documentation? Is it going to stay on github, or do we want something more oriented towards documentation?
I'd suggest going with something like Readme.io, which offers free hosting for open source projects, but I'd be interested to hear if others have better solutions.
How do I set up the head tag.. for example..
<head>
<meta charset="utf-8">
<meta name="description" content="webkid react starterkit">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>webkid react starterkit</title>
<link rel="stylesheet" href="css/main.css">
</head>
Currently, we don't have support for SSR.
Also our directory layout does not support it.
We need to work on it.
This is because of current state of Meteor 1.3
I didn't wanted to put code into imports
directory and but we can't put them into a common place because, there might be some modules (code) available only for client.
Then even the user don't wanna use SSR, he'll has to face issues of SSR.
May be we need to put the app into the imports directory anyway
Will be Mantra opinionated about directory structure?
For example code to configure user accounts as they are created? Or other manipulation of Meteor.users (e.g., adding roles).
Maybe in server/lib?
Shouldn't we move all the meteor method call to use async/await as with 1.3 the ecmascript package will also enable its support. That should make method calls much more cleaner.
I have a simple container to manage the state of my Nav bar.
import TopNav from '../components/nav/topNav/index.jsx';
import {useDeps} from 'react-simple-di';
import {composeWithTracker, composeAll} from 'react-komposer';
export const composer = ({context}, onData) => {
const {LocalState} = context();
const navOpen = LocalState.get('TOPNAV_OPEN');
onData(null, {navOpen});
};
export const topNavDepsMapper = (context, actions) => ({
openNav: actions.topNav.openTheSideNav,
closeNav: actions.topNav.closeTheSideNav,
context: () => context
});
export default composeAll(
composeWithTracker(composer),
useDeps(topNavDepsMapper)
)(TopNav);
composer manages the state
topNavDepsMapper exposes (injects) the functions
this is my component
import React from 'react';
import Sticky from 'react-sticky';
import LeftNav from 'material-ui/lib/left-nav';
import MenuItem from 'material-ui/lib/menus/menu-item';
import RaisedButton from 'material-ui/lib/raised-button';
class TopNav extends React.Component {
handleToggle() {
const {openNav} = this.props;
console.log(this);
openNav();
}
render(){
const {navOpen} = this.props;
return (
<div>
<LeftNav open={false}>
<MenuItem>Menu Item</MenuItem>
</LeftNav>
<Sticky className="topNav mobile hidden" topOffset={542}>
<nav>
<ul>
<li><a onTouchTap={this.handleToggle.bind(this)}>MENU Item</a></li>
</ul>
</nav>
</Sticky>
</div>
);
}
}
export default TopNav;
but for some reason my props is empty in the TopNav Component... What am i missing here?
Hi,
I was thinking if it is better to use atomic design as one way to structure Mantra's React UI components: http://patternlab.io/about.html
I am going to try to create my own Mantra like structure with Atomic Design (and might use Redux + RXJS). Will let you know what I'll learn
Why is that? Not that I am pushing for Redux... but I really like your way of handling and building things and I have been following you ever since. I have a small hobby project (my website) and would like to use Mantra architecture to test it out... but I really like Redux as well... what's your opinion about it?
why are you preferring class extends React.Component
?
is it only preferred in demo app, or it's a Mantra standard?
I am not as familiar with Github as I should be, I apologize. If I base my new app on this kickstarter; what is the best way to sync new changes that happen to this repository? As I build up my app and I start adding new custom files; what is the best way to stay in sync with the architecture of this starter project? Is there an easy way to find out what changed from the time I cloned this repository? Or is there a way to merge the changes to my app?
Best regards,
Chris
First of all, thank you for putting so much love in this project. It seems very promising and exciting so far!
I am posting here to start the discussion on the testing structure and guidelines.
By now I am following the xolvio's recommendations for testing and I am pretty satisfied with it. Those guys have a lot of experience on Meteor testing and I assume the community would agree that it is by far the best testing structure for Meteor, so let's use their work as comparison here.
Given that, the questions that come to my mind are:
I understand that mantra is mainly a spec for client side, but isn't leaving out the server side killing the idea of: "so it’s very important to have a common standard everyone follows. That’s what this specification does."
https://kadirahq.github.io/mantra/#sec-Core-Components.Server-Side
I don't know if this counts for a lot of companies, but at least "we" did mainly server side testing till now and client-side was more like "monkeytesting(https://en.wikipedia.org/wiki/Monkey_test)" without automation. Now when following mantra for the next projects we have client side testing but have to find our own solution for server side testing again. That's kind of confusing as mantra tries to be "a common standard everyone follows".
So why the restriction? Just waiting for meteor 1.3s built in testing or is this a long term decision?
Dears, this project looks very nice. I am a bit struggling with configuring wallaby.js with the demo app. Wallaby was mentioned also in #15 and it is one great testing tool. Have you had a chance to configure it? I got this so far, but no luck as I am receiving many errors:
var babel = require('babel-core');
module.exports = function (wallaby) {
return {
files: [
'client/containers/*.js'
],
tests: [
'client/containers/tests/*.js'
],
compilers: {
'**/*.js': wallaby.compilers.babel({
babel: babel,
presets: ['es2015', 'react']
// babel options
// like `stage: n` for Babel 5.x or `presets: [...]` for Babel 6
})
},
// preprocessors: {
// // NOTE: If you're using Babel 6, you should also add `presets: ['es2015']`.
// // You will also need to
// // npm install babel-core (and require it instead of babel)
// // and
// // npm install babel-preset-es2015
// // See http://babeljs.io/docs/plugins/preset-es2015/
// '**/*.js': file => require('babel').transform(file.content, {sourceMap: true, presets: ['es2015'] })
// },
testFramework: 'mocha'
};
};
I receive very basic errors such as Can't find variable: exports
.
Any help would be greatly appreciated!
Thanks!
According to Roadmap, code generator might be available on the 4th week of January.
Please update information about it.
Wondering about the relationship between the Babel support that seems to be built-in to 1.3 (escmscript) and the Babel packages in package.json. Is Babel in package.json for testing or does it override the Babel that seems to come with escmscript or is it something else altogether?
Thanks!
Since Mantra is already introducing a set of standards for Meteor apps. Maybe you can also add feross/standard to introduce JS and JSX style standard to make it more maintainable?
I saw this awesome talk on using Seneca js to scale Meteor. Does it make sense to bake microservices into mantra using Seneca?
https://www.youtube.com/watch?v=9FDWv0BDKtI
I saw this in the sample app, it doesn't seem like a very clean isomorphic solution. I understand for latency compensation it's nice to have the "saving: true" attribute. I'm wondering if there's a better way to achieve this that doesn't require duplicating all the code.
@arunoda so I have been thinking about the container components approach and realized that sometimes the containers could be abstracted to more universal composer functions and later combined in a more 'on demand' manner.
Take a look at the _colors module
I have the following structure:
I also have the data rendering / functional components:
and instead of using containers I have a abstract list of composers function:
/_colors/composers/colors/edit.jsx:
import {useDeps} from 'react-simple-di';
import {composeWithTracker, composeAll} from 'react-komposer';
import {singleComposer} from './single.jsx';
export const editComposer = ({context, clearErrors}, onData) => {
const {LocalState} = context();
const error = LocalState.get('_colors.SAVING_ERROR');
onData(null, {error});
// clearErrors when unmounting the component
return clearErrors;
};
export const depsMapper = (context, actions) => ({
submitAction: actions._colors.update,
clearErrors: actions._colors.clearErrors,
context: () => context
});
export default (component) => composeAll(
composeWithTracker(singleComposer),
composeWithTracker(editComposer),
useDeps(depsMapper)
)(component);
/_colors/components/colors/edit.jsx:
import React from 'react';
import Sidebar from './_sidebar.jsx';
// import Container from '../../containers/colors/edit.jsx';
import dataComposer from '../../composers/colors/edit.jsx';
import Component from './_form.jsx';
const Container = dataComposer(Component);
export default class extends React.Component {
render() {
const {_id} = this.props;
return (
<div className="bs-docs-section clearfix">
<div className="row">
<div className="col-md-3">
<Sidebar />
</div>
<div className="col-md-9">
<Container _id={_id}/>
</div>
</div>
</div>
);
}
}
view / composer | collection | single | add | edit |
---|---|---|---|---|
collection | X | |||
single | X | X | ||
add | X | |||
edit | X |
Of course if you want ready to use container components nothing is stopping you and they will be even simpler to write given a set of well designed composer functions.
/_colors/containers/colors/edit.jsx:
import dataComposer from '../../composers/colors/edit.jsx';
import Component from '../../components/colors/_form.jsx';
export default dataComposer(Component);
Benefits?
What do you think?
Hi, folks. Will Mantra become a kind of MeteorKitchen replacement?
@arunoda I am having some issues with composeAll. I seems that it is not passing all predefined in composer functions properties to the final component.
I checked in the source code of react-komposer and it appears that there are no limits on the number of composers functions within composeAll method.
So I just wanted to confirm with you that writing a method like this is fine?:
export default (component) => composeAll(
composeWithTracker(ColorSingleComposer),
composeWithTracker(ColorsUpdateComposer),
useDeps(depsMapper)
)(component)
If I'm accessing a different app from the client of this Mantra app (as per, say BulletProof Meteor). Where do I expose the other app/service? In initContext()
?
Great timing @arunoda, I was beginning to worry about the state of Meteor.
Do you have plans to support React Native with Mantra? Any idea what that might look like?
Chris
I know this is an early draft but I am always concerned with deployments. So far I tried both mup and mupx. Both failed with various erros. I have a fresh droplet and am testing it on two laptops. Currently mup consistently fails with the following:
=> Archiving failed: ENOENT: no such file or directory, stat '/var/folders/d4/1q4nn2cx65zgq1766v00kvyc0000gn/T/c0c22722-5274-467c-82e8-f5884d88bb56/bundle/programs/server/npm/react-runtime-prod/node_modules/react/node_modules/envify/node_modules/jstransform/node_modules/esprima-fb/.#README.md
The first thanks a lot to Arunoda
.
I would like to create 2 app/module on one project (integration). For example
1- Loan System
2- Saving System
There is a part written about naming convention for publications:
When naming publications and methods, they should follow this naming convention:
[filename].[name]
For example, if we need to create a method called create inside the posts file, we name it
posts.create
.
Looking at the sample-blog-app
, I can find the publications: posts.list
, posts.single
and posts.comments
. All pretty obvious. But what will the naming convention be for more specific actions. Like publish all posts for one author?
posts.by-author
posts.list-by-author
posts.list_by_author
posts.listByAuthor
posts.forAuthor
posts.list.author
Is there a suggestion for this edge-case? I think my favorite would be posts.list-by-author
. (Only not sure if we should do list-by-author
or list-for-author
. But that's more a grammar thing).
In the documentation it says in Section 3.1.2.1
This directory contains all actions in the app. Here’s a sample directory layout inside it
But I think this is now module specific, right?
So it should say:
This direction contains all actions in the module
Or am I missing something?
@arunoda I am assuming there will be lot of existing apps that would like to transition in to Mantra specified architecture. Most of the refactoring of the apps usually happen in a phased manner to reduce the risk. I was wondering will there be guidelines or spec details as how the existing app can take different refactoring paths in to Mantra?
I could be wrong but by default Meteor loads everything from the client
folder to the client.
Could mantra possibly be a place to define a spec to async load components?
With or similar to Webpack's code splitting?
or would this be something that shouldn't be in the spec?
When I'm looking at the latest code samples, I can see that validation code is written at multiple places. Is there really no better solution for this?
// in the action
create({Meteor, LocalState, FlowRouter}, title, content) {
if (!title || !content) {
return LocalState.set('SAVING_ERROR', 'Title & Content are required!');
}
// .. cut for clarity
Meteor.call('posts.create', id, title, content, (err) => {
if (err) {
return LocalState.set('SAVING_ERROR', err.message);
}
});
// .. cut for clarity
},
// in the methods
Meteor.methods({
'posts.create'(_id, title, content) {
check(_id, String);
check(title, String);
check(content, String);
// .. cut for clarity
Posts.insert(post);
}
});
I think there must be a better solution for this, by using aldeed:simple-scheme and mdg:validated-method?
I have require-login container here:
import RequireLogin from '../components/require-login/index.jsx';
import {useDeps} from 'react-simple-di';
import {composeWithTracker, composeAll} from 'react-komposer';
export const composer = ({context}, onData) => {
const {Meteor} = context();
const currentUser = !!Meteor.user();
const loggingIn = Meteor.loggingIn();
onData(null, {currentUser, loggingIn});
};
export default composeAll(
composeWithTracker(composer),
useDeps()
)(RequireLogin);
and require-login component here:
import React from 'react';
class RequireLogin extends React.Component {
notLoggedIn() {
// Do something if user is not logged in
return <p>Not Authorized to see this</p>;
}
getContent() {
const {currentUser} = this.props;
console.log('currentUser', currentUser); // returns undefined <========
return currentUser ? this.props.children : this.notLoggedIn();
}
render() {
const {loggingIn} = this.props;
console.log('loggingIn', loggingIn); // returns undefined <========
return (
<div className="require-login">
{loggingIn ? <p>Logging in</p> : this.getContent()}
</div>
);
}
}
RequireLogin.propTypes = {
children: React.PropTypes.element.isRequired
};
export default RequireLogin;
Any ideas why currentUser
and loggingIn
return undefined
? Thank you.
@arunoda how I pull in a CSS framework like Semantic UI?
Where would server side helpers go? On the client side, utility functions can live under /client/libraries
as explained here. What about on the server side?
Lots of discussion on meteor forum around webpack. Does webpack fit anywhere within Mantra?
https://forums.meteor.com/t/why-is-the-meteor-install-1-3-api-better-than-webpack-in-meteor/14480/51
Will there be or is there already a current kickstarter template for those of us wanting to convert an existing monolith meteor application or start a new one?
@arunoda I am looking extensively into react-komposer and shifting my thinking to Mantra architecture (https://kadirahq.github.io/mantra/#sec-Containers ) and I still have questions with regards to the standard react component lifecycle.
Your container + ui component approach suggests that logic is to be kept in the container and actions. Considering the "state" is to be avoided, are we also supposed stay away from componentWillMount / Unmount, getDefaultProps/ defaultProps, etc?
I'm publishing my helper, T
, in the context. My components should be translated using that.
But I came to this problem:
A component has no access to context
, since that's the function of actions and containers.
But making an object of translated strings on the context and then accessing them with this.props
doesn't feels right. It's too troublesome.
How would you solve this? Creating a global object of translations? Passing T
over with onData
? Creating an action
to translate the strings?
😉
is it possible to make more than one subscribe call in a container..?
This is kind of a general question and maybe there's no real answer, but I've been struggling with how to manage pages in my React directory structure.
What I mean by "page" is a top-level component called by a route, that may also handle the layout (assuming it's not handled at the router level). The issue is that pages can sometimes be containers (i.e. they load data and then pass it on to a "dumb" component), or sometimes be dumb component themselves (they're just static pages).
And on the other hand, not all containers are pages. Sometimes a smaller component embedded in your UI will need its own data, too, even though it's not a top-level page.
So giving pages their own directory makes the smart/dumb component distinction less clear. On the other hand, splitting components by smart/dumb is less intuitive and makes it harder to find pages…
Any thoughts?
I feel there are two camps with React. People who want to use inline styling and people who want to use some form of CSS whether it's SCSS, LESS, or Post CSS. How will Mantra address styling design patterns while keeping in mind the modularized design principles of React?
There's a interesting read about styling React Components in Sass here... http://hugogiraudel.com/2015/06/18/styling-react-components-in-sass/
Also another good article in favor of inline styles...
https://css-tricks.com/the-debate-around-do-we-even-need-css-anymore/
Another Good Read about different styling patterns with React...
http://survivejs.com/webpack_react/styling_react/
Check sashko's point over here: https://forums.meteor.com/t/checkout-mantra-an-application-architecture-for-meteor/16066/9?u=arunoda
It's a valid question. Using a app wide state manager if a good solution. What if, those component does not need to put them in a app wide state manager.
Need to find something for this without breaking anything.
Besides a directory layout and such things, I think it's also pretty convinient to have some linter configurations inside this repo?
Something like a .jscsrc
, .jshintrc
, .eslintrc
? I think we can use the file in the sample-blog-app
to get started: https://github.com/mantrajs/mantra-sample-blog-app/blob/master/.eslintrc
What is the best way to handle multiple subscriptions inside a container including case where a subscription depends on the result of another one.
In our mantra demo lets say we want to subscribe to a post, postComments
and lets say the overall total comments each user that left a comment have.
Let's create an an open source app we can actually use, with mantra. This would be better than using Discourse: we discuss, learn, and do QA testing all at the same time.
My idea is not so much a reference app, but an app we can use for experimentation. And importantly something that we keep in a working state.
I'd be willing to set it up on modulus and host it out of my pocket at least for a few months.
I need to use some of the React lifecycle functions such as componentDidMount.
For example to initialise semantic ui components such as tabs.
What is the recommended way of doing this?
Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.