Skip to content

Commit

Permalink
feat(compiler): component can be class (#454)
Browse files Browse the repository at this point in the history
* feat(compiler): component can be class

* feat(compiler): component can be class

* docs(readme): component as class

* fix(compiler): typeof to determine if name
  • Loading branch information
redgeoff authored Sep 1, 2021
1 parent 8072962 commit 92e3731
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 7 deletions.
29 changes: 26 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -656,12 +656,12 @@ Since all MSON code can be compiled to JS code, you can use MSON components in a
import compiler from 'mson/lib/compiler';

// Compile the MyAccount component
const MyAccount = compiler.compile({
component: 'MyAccount'
const CompiledMyAccount = compiler.compile({
component: MyAccount
});

// Instantiate the JS class with a default value
const myAccount = new MyAccount({
const myAccount = new CompiledMyAccount({
// Default values
value: {
firstName: 'Bob'
Expand All @@ -682,6 +682,29 @@ if (myAccount.hasErr()) {
```
In other words, you can use MSON in your existing JS code to save time writing complex code. By declaring components in MSON, you’ll remove a lot of boilerplate code and reduce the possibility of bugs. You’ll also have code that has a standard structure and is framework agnostic. And this code doesn’t add any unneeded frameworks or back-end dependencies to your codebase.
### Component as a Class or Compiled Component
In the above example, we used:
```js
const CompiledMyAccount = compiler.compile({
component: MyAccount
});
```
whereby, `MyAccount` is actually a class (compiled component). This can be handy as it means that we didn't have to register `MyAccount` with the compiler and we can import components using the native constructs present in JavaScript. On the other hand, our definition:
```js
{
component: MyAccount
}
```
can no longer be serialized into a JSON string as it references a JavaScript class. JSON serialization could be a requirement if, for example, we want to store our definitions in a database. MSON gives you the freedom to make this decision as you can always use the following instead:
```js
compiler.registerComponent('MyAccount', MyAccount);

const CompiledMyAccount = compiler.compile({
component: 'MyAccount'
});
```
### Reusing MSON Code Throughout the Full Stack
MSON components can be shared by both the front end and back end, allowing for key logic to be written once and then reused. For example, the same form validation rules can be enforced in the browser and by your back-end API.
Expand Down
10 changes: 6 additions & 4 deletions src/compiler/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ export class Compiler {
return !!this._components[name];
}

getComponent(name) {
if (this.exists(name)) {
return this._components[name];
getComponent(componentOrName) {
if (typeof componentOrName !== 'string') {
return componentOrName;
} else if (this.exists(componentOrName)) {
return this._components[componentOrName];
} else {
throw new MissingComponentError('missing component ' + name);
throw new MissingComponentError(`missing component ${componentOrName}`);
}
}

Expand Down
25 changes: 25 additions & 0 deletions src/compiler/compiler.raw-js.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Compiler } from './compiler';
import components from '../components';
import TextField from '../fields/text-field';

let compiler = null;

class NameField extends TextField {
className = 'app.NameField';

create(props) {
super.create(props);
this.set({ minLength: 5 });
}
}

beforeEach(() => {
compiler = new Compiler({ components: { ...components } });
});

it('should support class as component', () => {
const name = compiler.newComponent({
component: NameField,
});
expect(name.get('minLength')).toEqual(5);
});

0 comments on commit 92e3731

Please sign in to comment.