Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modular architecture with appmodules #7

Merged
merged 17 commits into from
Oct 5, 2016
Merged

Modular architecture with appmodules #7

merged 17 commits into from
Oct 5, 2016

Conversation

mrodem
Copy link
Contributor

@mrodem mrodem commented Sep 30, 2016

This PR introduces a major architectural change. Instead of having only one mode of operation (BLE), we now support multiple "appmodules". When starting the application, the users can now choose which appmodule they want to use. See doc/README.md for more information on appmodules.

The appmodule approach has been implemented by having multiple npm packages in the same repository (monorepo). To handle multiple packages, we are using lerna which iterates over packages in the packages directory, performing operations like install, build, test, publish, etc.

The scripts in the top-level package.json has been changed to use lerna, so we can still run npm install to initialize the project and npm start to start the application. The difference is that these commands now operate on packages in the packages directory. When running npm install, all dependencies for all packages will be pulled down, and local packages will be linked and built. Common development dependencies are defined in the top-level package.json, so that they can be reused by all packages.

We currently have the following packages:

packages
├── nrfconnect-appmodule-ble
├── nrfconnect-appmodule-sample
├── nrfconnect-core
└── nrfconnect-loader

The BLE-code that was previously on the top-level of the project has now been moved to nrfconnect-appmodule-ble. A sample appmodule has been added to nrfconnect-appmodule-sample, to make it easy to start developing new appmodules. The new entrypoint of the application is nrfconnect-loader, which presents the user with an appmodule selection UI. Common code and resources are located in nrfconnect-core.

Unit testing with jest has been introduced, and a few simple tests have been added for the nrfconnect-loader and nrfconnect-appmodule-sample packages. Tests are executed by running npm test, either in the root directory (tests all packages), or in each package directory.

React et.al is defined as peerDependencies in nrfconnect-core/package.json.
These are installed at development time, but they are not bundled with the
library, so those who depend on nrfconnect-core need to add their own React
dependency in their package.json. This works fine when the library is built and
published, but during development there will be a node_modules directory (with
React) in nrfconnect-core, and this causes problems.

When other projects import React components from nrfconnect-core, the Node
module loader will first look for React in nrfconnect-core/node_modules. The
other projects will provide their own React dependency, and that leads to two
copies of React being loaded at the same time. In general, we do not want
anything from nrfconnect-core/node_modules to be loaded by other projects. To
avoid this we patch Node's module loader.

For more info see:
https://www.sharpoblunto.com/News/2016/01/25/testing-react-component-libraries-using-npm-link
@mrodem
Copy link
Contributor Author

mrodem commented Oct 4, 2016

Stumbled upon this: facebook/create-react-app#675. The create-react-app project is planning to use a webpack alias to tackle the duplicate react issue (0c9b61f). I tried the proposed webpack solution last week, but could not make it work. Will be interesting to see create-react-app's solution.

@@ -87,7 +88,7 @@ class DiscoveredDevices extends React.PureComponent {
<div>
<h4>
Discovered devices
<img className='spinner' src='resources/ajax-loader.gif' height='16' width='16' style={progressStyle} />
<img className='spinner' src={spinnerImage} height='16' width='16' style={progressStyle} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should spinner be made a separate component with size as a prop? This is at least the third time I see it in this commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Spinner should be a component. Will add it.

@@ -10,8 +10,6 @@
*
*/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not strict any more?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the ES2015 spec, module code is always strict mode. Should not be necessary to add "use strict" anymore for ES2015 modules.

http://stackoverflow.com/questions/31685262/not-recommended-to-write-out-use-strict-with-es6

@@ -10,10 +10,10 @@
*
*/

'use strict';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove strict?

minHeight: 499,
show: false
}, options);
var browserWindow = new electron.BrowserWindow(mergedOptions);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use let instead of var (also valid for rest of file).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Used var here to be consistent with what has been done before. I guess it was done this way because this code is not being transpiled, but let is supported now, so I agree that let is the way to go.

Will switch to let for all the main index.js files.

import React, { PropTypes } from 'react';
import { FormGroup, ControlLabel, FormControl, InputGroup } from 'react-bootstrap';

class TextInput extends React.PureComponent {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be named the same as the file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch. Will fix.

@mrodem
Copy link
Contributor Author

mrodem commented Oct 5, 2016

Added Spinner component, changed from var to let, and now using correct name in the SelectList component. Good feedback, thanks.

@bihanssen bihanssen merged commit 019f595 into master Oct 5, 2016
@bihanssen
Copy link
Contributor

Great work, thanks!

@bihanssen bihanssen deleted the plugin-loader branch October 5, 2016 18:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants