Let's face it. We all make mistakes when we code. Best practices on the web can change so fast that we often don't even know that we failed to Do the Right Thing™.
You know what's good for that? Continuous Integration. But sometimes that's not enough. Sometimes you've implemented some sweeping change and CI doesn't catch it until you try to merge it upstream. Sometimes reusing an anti-pattern slows down your app just a little bit. And then a little bit more. And then, finally, performance dips below the threshold your CI tools are checking for. And you get to clean up the mess.
So, what's better than continuous integration? Tools that notify you the moment you do something wrong. And what's even better than that? Tools that can explain to you what you did wrong and how to avoid it in the future. That's SMW.
Table of Contents generated with DocToc
Want to contribute to SMW? Great! Here are some guidelines.
Trust in .eslintrc
. Beyond what's explicated there, follow these rules:
- Open/close indentation: For any opening paren/brace/bracket that starts its own indentation level, give the closing paren/brace/bracket its own line:
const foo = {
bar: 0, baz: 1, quz: 2,
};
let foo = [
bar, baz, quz,
];
foo(
bar, baz, quz
);
- File and module loading: Prefer
require('external-package-name')
andrequire('../relative/path/to/local/File.es6.js')
. This is often accompanied by FOAM dependency declarations. See FOAM and module loading for details.
First source scripts/dev_env.sh
:
. ./scripts/dev_env.sh
Now you can safely use these npm scripts to your advantage:
npm run develop
: Watch dependencies and continuously rebuild Javascript bundlesnpm run build
: Build Javascript bundles (one-shot)npm run lint
: As above, but first run the linternpm run unit
: Run NodeJS unit testsnpm run integration
: Run NodeJS integration testsnpm run test
: Run all NodeJS testsnpm run coverage
: Generate a test coverage report (look in.coverage
directory)
Files that use ECMAScript 2015 (the ECMAScript formerly known as 6) features
should end in .es6.js
; build rules depend on this pattern. Generated
Javascript bundles (and nothing else) ends in .bundle.js
.
Directories at a glance:
lib
: Codemain
: Program entry point codestatic
: Assets that can be served staticallystatic/bundle
: Bundled/compiled assets (generated vianpm
scripts)scripts
: Shell scripts
config
: Toolchain configurationtest
: Teststest/any
: Test code that runs in any environmenttest/node
: Test code that runs only in NodeJStest/browser
: Test code that runs only in the browsertest/**/*-test*.js
: Unit teststest/**/*-integration*.js
: Integration teststest/**/*-helper*.js
: Jasmine-style test helpers
SMW uses Jasmine for testing, Webpack for ECMAScript compatibility and packaging, and FOAM for everything else.
SMW is built using a holistic modeling framework called FOAM. Learning FOAM itself is beyond the scope of of this README. Some FOAM resources are listed at the end of this section.
SMW uses Webpack for its own code, but not for the FOAM framework itself. FOAM is loaded in the browser using:
<script language="javascript" src="path/to/foam.js"></script>
as in the Jasmine SpecRunner.
FOAM is loaded in NodeJS using:
require('foam2-experimental');
as in the Jasmine FOAM Helper.
FOAM injects packaged-named FOAM dependencies into instance contexts, but
does not support automagically loading dependencies
(yet). This
means that typical code that requires the SMW dependency
tools.web.strict.Foo
, and uses it in the context of tools.web.strict.Bar
looks something like this:
require('./Foo.es6.js'); // Tell Node/Webpack that we need this file.
foam.CLASS({
package: 'tools.web.strict',
name: 'Bar',
requires: ['tools.web.strict.Foo'], // Tell FOAM we need tools.web.strict.Foo.
// ...
methods: [
function fooBar() {
let foo = this.Foo.create({/* ... */);
// ...
}
]
// ...
});
Yes, this is somewhat redundant. The FOAM team is working on it.
- FOAM2 experimental repository: SMW consumes a branch of this
- FOAM2 official repository: All the features that have been thoroughly documented and tested
- FOAMByExample: This is an Javascript description of a by-example tutorial. (Meant-for-human-consumption version hopefully coming soon.)
- YouTube Channel for videos about FOAM
- Slides and video from talk at EmpireJS
- Slides and video from talk at Full-Stack Toronto