dna

Evolution-based components.

Getting started with DNA

Setup a project

Although DNA works well used via CDN as a global object of the browser page, in order to build a large scale application you may need a project with bundlers, dev tools, preprocessors and more. In this guide we will use npm and Webpack for all of this needs (by the way, DNA still be compatible with other tools like RollupJS, Babel CLI, Browserify...).

Create the project

# Create project structure
mkdir sample && cd sample
mkdir app && mkdir dist
# Install dev dependencies
npm install webpack webpack-cli --save-dev
npm init -y

Config webpack

Webpack is a powerful tool that can do a lot of thing, so we have to configure it with our needs:

# Install dependencies
npm install -D babel-loader babel-core babel-preset-env
# Create config files
touch webpack.config.js

webpack.config.js

const path = require('path');
const webpack = require('webpack');

module.exports = {
    context: path.join(__dirname, 'app'),
    module: {
        rules: [
            {
                test: /\.js$/,
                loader: 'babel-loader',
                query: {
                    presets: [
                        ['env', { modules: false }],
                    ],
                },
            },
        ],
    },
    resolve: {
        modules: [
            path.join(__dirname, 'node_modules'),
        ],
    },
};

Install DNA

The DNA project is composed by a pattern library (built on the top of Custom Elements v1 specs) and a custom implementation. The pattern library, alias @dnajs/core, defines mixins and helpers for components creation and initialization. You can directly use this package if you want to manage yourself the component life cycle, but a set of ready-to-use implementation is provided too.

Well written DNA components can switch the implementation library for fast and good interoperability. ❤️

Official implementations of the DNA pattern library are:

Incremental DOM

NPM

npm install @dnajs/idom

This package uses Incremental DOM library api and notifications to trigger component life cycle, so every component set up by an IDOM patch works as well the native Custom Element implementation, but without requiring a polyfill and with a large browser support. IDOM can really speed up your component rendering too if used for templating thanks to its fast DOM diffing algorithm.

Custom Elements v1

NPM

npm install @dnajs/custom-elements-v1

Simply define DNA components as Custom Elements and let the browser to handle components life cycle. This is the easiest way to get started with DNA, but browser support is still not complete, unless you are using a polyfill. Components are fully compatible with Polymer 2 components or any other CE implementation.

Custom Elements v0

NPM

npm install @dnajs/custom-elements-v0

Similar to the v1 implementation, but with Custom Elements v0 specs support.

React

NPM

npm install @dnajs/react

You can also use DNA components in your React application thanks to this package, which provides an adapter for React components.

Import and usage

Now we are ready to write our first DNA component and the shell where it will be rendered.

mkdir app/components && mkdir app/components/hello-world
touch app/components/hello-world/hello-world.js
touch app/index.js
touch dist/index.html

app/components/hello-world/hello-world.js

import { BaseComponent, define } from '@dnajs/idom';

// define and export our component class extending the DNA's BaseComponent.
export class HelloWorld extends BaseComponent {
    // the component is in the DOM.
    connectedCallback() {
        // call the super `BaseComponent` callback.
        super.connectedCallback();
        console.log('Hello!');
    }
}

// now we define our component.
define('hello-world', HelloWorld);

app/index.js

import { HelloWorld } from './components/hello-world/hello-world';
import { render } from '@dnajs/idom';

// render a HelloWorld instance into the document body.
render(document.body, HelloWorld);

dist/index.html

<html>
    <head>
        <title>My sample DNA app</title>
    </head>
    <body>
        <script src="bundle.js"></script>
    </body>
</html>

GoGoGo!

Now it is all set. Just build our simple application and open index.html.

npx webpack app/index.js -o dist/bundle.js
open dist/index.html

We can see the 'Hello' log in the console. Our component has been successfully loaded!