meanjs-core

    0.0.4 • Public • Published

    mean-core

    MEAN.JS - Core services for the MEAN.JS boilerplate. Full-Stack JavaScript Using MongoDB, Express, AngularJS, and Node.js From Creators of MEAN.IO - http://meanjs.org

    This is a proposal to:

    • Separate boilerplate example code from core functionality
    • Standardize a way for contributed modules.
    • Use npm package manager to update core code w/o requiring a git merge

    Code

    Status: psuedocode

    To play with this code:

    1. fork boilerplate: git@github.com:MichaelJCole/mean.git
    2. checkout meanjs-core branch
    3. npm install && grunt build
    4. grunt

    It's stored in 3 repos.

    • boilerplate: meanjs-core branch, forked repo: git@github.com:MichaelJCole/mean.git
    • mean-core: master branch, this repo you're reading: git@github.com:MichaelJCole/mean-core.git
    • mean-module: master branch, this repo: git@github.com:MichaelJCole/mean-module.git

    This will download and install mean-core and mean-module from github.

    How to use mean-core:

    mean-core functionality is in a separate npm package from the Yoeman boilerplate.

    In package.json

    The boilerplate includes mean-core:

    "dependencies": {
      // ...
      "mean-core": "git://github.com/MichaelJCole/mean-core",
      // ...
    }
    

    How to use in the boilerplate

    mean-core's functionality is exposed in several places:

    app.config
    app.core.[module].[export]
    req.config
    req.core.[module].[export]
    

    The boilerplate uses these core functions, allowing the end developer to add, delete, re-mix, and mash them up as needed:

    // Core and Module functions are exposed on app.core and req.core objects.
    
    // e.g. In users.server.controllers.js, use req.core.[modulename].[export]
    exports.signup = function(req, res) {
      // ...
      // 
      // Then save the user 
      user.save(function(err) {
        if (err) {
          // ...
        } else {
          // ...
          // Send confirmation email
          req.core.users.sendConfirmEmail(user, req.config);
        }
      });
    
    // e.g. In users.server.routes.js, use app.core.[modulename].[export]
    module.exports = function(app) {
      // User Routes
      // ...
      app.route('/auth/confirm/:confirmationCode').get(app.core.users.confirmEmailLink);
      // ...
    }
    

    An open question is how to organize the module exports. I'm aware of three modules: users, core, and articles.

    Using a contributed MEAN.JS module 'myModule'

    Add to package.json:

    "dependencies": {
      // ...
      "mean-core": "git://github.com/MichaelJCole/mean-core",
      "mean-module": "git://github.com/MichaelJCole/mean-module"
      // ...
    }
    

    Configure your app

    In the boilerplate server.js:

    // Note: developers add modules here:
    var meanModules = [
      require('mean-module')(db, config) // pass db and config if needed.
    ];
    
    // ...
    
    // Init the express application
    var app = require('./config/express')(db, config, meanModules);
    

    server.js is intended for the end developer to customize.

    Boilerplate code uses mean contributed modules

    config/express.js wires these modules into:

    app.mean.[module].[export]
    req.mean.[module].[export]
    

    Creating your own MEAN.JS module

    To extend mean-core with a module of your own:

    1. create a github repo for your myModule.
    2. expose your functionality via exports.
    exports.name = 'moduleName';
    
    exports.myModule.controller.myFunc(req, res, next) {
      console.log("hello world");
      next();
    }
    

    To use:

    // e.g. In users.server.routes.js, use app.core.[modulename].[export]
    module.exports = function(app) {
      // User Routes
      // ...
      app.route('/auth/confirm/:confirmationCode').get(app.mean.betterUsers.betterConfirmLink);
      // ...
    }
    

    Summary:

    This allows for:

    • package.json and server.js are files for dev to add contributed modules.
    • config/express.js is still boilerplate, but most likely won't be customized (easier updates)
    • namespaces aren't poluted:
    // Config
    app.config
    req.config
    // Core functionality
    app.core.[module].[export]
    req.core.[module].[export]
    // Contributed modules
    app.mean.[module].[export]
    req.mean.[module].[export]
    

    Note: it may be worth separating config for core and contributed, but that's another topic.

    How's it work:

    1. Add dependencies to package.json
    2. Changes to server.js:
    var meanModules = [
      require('mean-module')(config) // edit config files if needed.
    ];
    // ...
    var app = require('./config/express')(db, config, meanModules);
    
    

    The file config/express.js :

      // ...
    
      // Get core exports
      var core = require('mean-core')(db, config)
    
      // Apply exports to app
      app.set('config', config);
      app.set('core', core);
      app.set('mean', meanModules);
    
      // Middleware to adjust req
      app.use(function(req, res, next) {
        res.locals.url = req.protocol + ':// ' + req.headers.host + req.url;
        // Add application config to all incoming requests
        req.config = config;
        req.core = coreExports;
        req.mean = meanExports;
        next();
      });
    
      // ...
    

    How to develop in mean-core:

    1. Clone your own repo
    2. Use npm-link to link to your local mean-core https://www.npmjs.org/doc/cli/npm-link.html http://justjs.com/posts/npm-link-developing-your-own-npm-modules-without-tears
    cd mean-core
    sudo npm link
    cd ../mean-module
    sudo npm link
    cd ../project
    npm link meanjs-core
    npm link meanjs-module
    

    Now, when you require('mean-core'), Node.js will find a symlink to your local copies.

    Core versioning and compatibility promises:

    TBD.

    Etc.

    Express middleware

    Express modules like mean-seo could also be added in express.js, if they were defined like this:

    exports.middleware = function()
    

    name collisions

    Module names should not collide, unless the modules are drop-in replacements for one another.

    Data Models

    Data models should be strictly boilerplate. This prevents the need for inheritance, sub-classing, or baloney like that.

    Core and Contrib modules can store/read data in the model.decor attribute(?) as a sub-document.

    core.[moduleName].property
    mean.[moduleName].property
    

    More complex data requirements will require customizing the models by hand.

    Not addressed

    Angular modules. Haven't figured this out yet. Ideas? PHP's Symfony project handled client modules via symlinks.

    Keywords

    none

    Install

    npm i meanjs-core

    DownloadsWeekly Downloads

    0

    Version

    0.0.4

    License

    MIT

    Last publish

    Collaborators

    • michaelcole