-
Notifications
You must be signed in to change notification settings - Fork 5
Setup
A17 Behaviors have principally been developed to work with a Webpack build process. The build includes both ESM and CommonJS modules.
This setup guide will talk through:
- installing
a17-behaviors
andwebpack
- a note on
a17-behaviors
dependencies - a file structure,
- a basic Webpack set up,
- required CSS
- creating a behavior,
- importing behaviors,
- and finally, initialising behavior management.
$ npm install @area17/a17-behaviors
$ npm install webpack
$ npm install webpack-cli
$ npm install webpack-merge
$ npm install webpack-watch-files-plugin
a17-behaviors
has a dependency on a17-helpers
for:
-
isBreakpoint
- a utility to compare a given breakpoint name with the currently displayed breakpoint, allows straight comparisons like "is breakpoint medium?" (isBreakpoint('md')
) and also, more useful comparisons like "is breakpoint larger than medium?" (isBreakpoint('md+')
), used when wanting to trigger behaviors at certain breakpoints -
purgeProperties
- a utility to remove all properties from an object, used when destroying behaviors on DOM nodes removed from the document -
resized
- a debounced resize event which also keeps track of the currently active breakpoint
Webpack configuration is a world and mystery all to itself sometimes. This setup guide assumes Webpack 5. Your exact set up will change depending on your project needs, this example intentionally keeps it simple.
This set up is split into 3 files:
-
webpack.common.js
- shared set up between environments -
webpack.dev.js
- development specific setup (you may want to include Webpack dev server here) -
webpack.prod.js
- production code specific set up
For dynamic behaviors, there is a little more Webpack setup required, see Dynamic behaviors.
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: {
application: './src/application.js',
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'public'),
clean: true,
publicPath: process.env.ASSET_PATH || '/'
}
};
const webpack = require('webpack');
const path = require('path');
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'development',
devtool: 'inline-source-map',
plugins: [
new webpack.DefinePlugin({
'process.env.MODE': JSON.stringify('development'),
}),
]
});
const webpack = require('webpack');
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'production',
plugins: [
new webpack.DefinePlugin({
'process.env.MODE': JSON.stringify('production'),
}),
],
});
Is sending process.env.MODE = 'development'
instead of process.env.MODE = 'production'
. This allows for additional debugging options when running behaviors in the browser. If you don't require them, then you don't need to send any process.env.MODE
.
To enable breakpoint checking we need a way for the JavaScript to easily be able to determine the currently active breakpoint, this simple CSS allows this.
Set up :root
variables changing a --breakpoint
value at each of your breakpoints, with the name of your breakpoint. If using A17 Tailwind Plugins or A17 SCSS Utilities then this set up is likely done for you.
We could use window.matchMedia
for this instead, but, it would mean sharing and comparing breakpoint information and its easier just to read it from a CSS variable.
<style>
:root {
--breakpoint: xs;
}
@media screen and (min-width: 544px) {
:root {
--breakpoint: sm;
}
}
@media screen and (min-width: 650px) {
:root {
--breakpoint: md;
}
}
@media screen and (min-width: 990px) {
:root {
--breakpoint: lg;
}
}
@media screen and (min-width: 1300px) {
:root {
--breakpoint: xl;
}
}
@media screen and (min-width: 1520px) {
:root {
--breakpoint: xxl;
}
}
</style>
import { createBehavior } from '@area17/a17-behaviors';
const myBehavior = createBehavior('myBehavior',
{
alert(val) {
window.alert('Hello world!');
}
},
{
init() {
this.$node.addEventListener('click', this.alert);
},
destroy() {
this.$node.removeEventListener('click', this.alert);
}
}
);
export default myBehavior;
export { default as myBehavior } from './behaviors/myBehavior';
export { default as anotherBehavior } from './behaviors/anotherBehavior';
Of course, in your project, you're likely to have many "critical" behaviors.
import { manageBehaviors } from '@area17/a17-behaviors';
import * as Behaviors from './behaviors'; // Critical behaviors
window.A17 = window.A17 || {}; // currently namespaced name *is* important
document.addEventListener('DOMContentLoaded', () => {
// expose manageBehaviors
window.A17.behaviors = manageBehaviors;
// init behaviors!
window.A17.behaviors.init(Behaviors, {
breakpoints: ['sm', 'md', 'lg', 'xl'] // tell this app what your breakpoint names are, in size order, manageBehaviors will read a CSS variable and compare for media scoped behaviors, default is ['xs', 'sm', 'md', 'lg', 'xl', 'xxl']
});
});
In your terminal, in your project root directory:
$ webpack --config webpack.dev.js