Skip to content

Instantly share code, notes, and snippets.

@jsteenkamp
Last active August 29, 2015 14:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jsteenkamp/67cbdc305b54d84e5adb to your computer and use it in GitHub Desktop.
Save jsteenkamp/67cbdc305b54d84e5adb to your computer and use it in GitHub Desktop.
Angular 1.x Component Architecture Application using JSPM for ES6 and importing CSS and HTML

##Component module structure

app.js
/components
  /list
      list.js
      router.js
      controller.js
      template.html
      styles.scss // this is converted to styles.css by your SCSS pre-processor

The list module is imported into your main app using

import listModule from './components/list/list'

Inject in the main app using

listModule.name

###Controller and ES6 class

I recommend using the controller-no-class style. Why?

##CSS

A CSS wrapper class gives us CSS specificity to modularize the component CSS. All CSS selectors are effectively globals so we cannot get isolation. This approach means we do not need convoluted naming conventions (BEM, SMACSS, ATOMIC) that add error prone naming conventions via verbose markup, and do not solve the real problem.

Use your CSS pre-processor to generate modular CSS and clean HTML.

To import CSS install the jspm CSS plugin

##ES6

ES6 transpiling is handled automatically by jspm using Traceur or Babel. I recommend Babel as it does not require an additional run-time.

Using jspm.io we can bundle everything into a single javascript file using the sfx command:

jspm bundle-sfx path/to/entry/file path/to/output/file;

Tip: If you are using WebStorm set your JavaScript language version to JSX Harmony to prevent "file not found" warning for the HTML file import.

'use strict';
// vendor modules
import angular from 'angular';
import 'angular-touch';
import 'angular-animate';
import 'angular-aria';
import 'angular-ui-router';
// app modules
import listModule from './components/list/list';
import listService from './services/list/list';
// main app module
let app = angular.module('app', [
// vendor modules
'ngTouch',
'ngAnimate',
'ngAria',
'ui.router',
// component modules
listModule.name,
// services modules
listService.name
]);
app.config(['$urlRouterProvider', '$locationProvider', ($urlRouterProvider, $locationProvider) => {
$locationProvider.html5Mode(true);
$httpProvider.useApplyAsync(true);
$urlRouterProvider.otherwise('/');
}]);
// start app
angular.element(document).ready(() => {
angular.bootstrap(document, ['app'], {
strictDi: true
});
});
'use strict';
// you can use lodash _.extend(this, ...) or Object.assign( ... )
let controller = (listData) => Object.assign({
listData: listData,
myMethod() {
}
});
// listData is resolved by ui router
export default ['listData', controller];
'use strict';
class Controller {
constructor(listData) {
this.items = listData;
},
myMethod: () => {
}
}
// listData is resolved by ui router
export default ['listData', Controller];
'use strict';
import router from './router';
import Controller from './controller';
export default angular.module('app.component.list', [])
.config(router)
.controller('ListController', Controller);
'use strict';
// jspm imports CSS (install plugin) and HTML
import './styles.css!';
import template from './list.html!text';
let router = ($stateProvider) => $stateProvider.state('list', {
abstract: false,
parent: 'layout',
url: '',
views: {
'content': {
controller: 'ListController',
controllerAs: 'list',
bindToController: true,
template: template,
resolve: {
listData: ['ListService', ListService => ListService.listItems()]
}
}
}
});
export default ['$stateProvider', router];
.component-list {
margin: 8px 16px;
h3 {
color: #3c3c3c;
font-size: 24px;
font-weight: 400;
}
p {
margin: 4px 16px;
font-size: 14px;
}
}
<div class="component-list">
<ul>
<li ng-repeat="item in list.items">
<h3>{{ item.title }}</h3>
<p>{{ item.description }}</p>
</li>
</ul>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment