Direflow v3.4.0 Release Notes

Direflow v3.4.0 Release Notes

Β·

11 min read

We are happy to announce that Direflow v. 3.4 has been released πŸŽ‰

New features

  • Split Direflow Components into separate bundles

  • Improved way to configure Direflow Components

  • Make Direflow Setup β€˜NPM-ready’ as part of CLI flow

  • Load scripts asynchronously with external-loader plugin

  • Provide all answers in CLI flow as inline options

  • Export Direflow Components as regular React components

Recently introduced

  • React module is loaded asynchronously

  • Inbuilt support for Material UI

Split Direflow Components into separate bundles

With this feature, you now get the ability to split your Direflow Components into separate bundles.

To use this feature, provide the --split argument to the build command.

yarn build --split
# or
npm run build --split

This feature introduces some breaking changes in the structure of the setup. Let’s go through them.

Each Direflow Component will have its own index.js file

When you create a new Direflow Setup, the folder structure will look like this

.
β”œβ”€β”€ public
β”‚   β”œβ”€β”€ index.css
β”‚   └── index.html
β”œβ”€β”€ src
β”‚   β”œβ”€β”€ direflow-components
β”‚   β”‚   └── my-component
β”‚   β”‚       β”œβ”€β”€ test
β”‚   β”‚       β”‚   └── App.test.js
β”‚   β”‚       β”œβ”€β”€ App.css
β”‚   β”‚       β”œβ”€β”€ App.js
β”‚   β”‚       └── index.js
β”‚   β”œβ”€β”€ component-exports.js
β”‚   └── index.js
β”œβ”€β”€ direflow-webpack.js
β”œβ”€β”€ package.json
└── README.md

Note that my-component now has its own index.js file.

If we have multiple Direflow Components, the folder structure will look like this:

.
β”œβ”€β”€ public
β”‚   β”œβ”€β”€ index.css
β”‚   └── index.html
β”œβ”€β”€ src
β”‚   β”œβ”€β”€ direflow-components
β”‚   β”‚   β”œβ”€β”€ my-component-1
β”‚   β”‚   β”‚   β”œβ”€β”€ ...
β”‚   β”‚   β”‚   └── index.js
β”‚   β”‚   β”œβ”€β”€ my-component-2
β”‚   β”‚   β”‚   β”œβ”€β”€ ...
β”‚   β”‚   β”‚   └── index.js
β”‚   β”‚   └── my-component-3
β”‚   β”‚       β”œβ”€β”€ ...
β”‚   β”‚       └── index.js
β”‚   └── index.js
β”œβ”€β”€ direflow-webpack.js
β”œβ”€β”€ package.json
└── README.md

Inside these index.js files, we configure the Direflow Component that the file belongs to:

*// src/direflow-components/direflow-component-1/index.js
*import { DireflowComponent } from 'direflow-component';
import App from './App';

DireflowComponent.create({
  component: App,
  configuration: {
    tagname: 'cool-component',
  },
});

The Direflow Setup will contain a main index.js file

You may also have noticed, that there exists a main index.js file directly inside src.

This file is the entry file of the setup, and it is required to exist in order for the setup to work. In this index.js file, it is practical to add any additional functionality or meta-logic for the setup, if needed. For instance, this is a good place to hook into your Web Component one it's mounted on the DOM:

*// src/index.js
*import CoolComponent from "./cool-component";

CoolComponent.then((element) => {
  // Access DOM node when it's mounted
  console.log('cool-component is mounted on the DOM', element);
});

This may not be needed, and the main index.js file can be left blank. (But not removed).

How to benefit from the --split feature

Using the split command in combination with the build will produce a build folder looking like this example:

.
└── build
    β”œβ”€β”€ main.js
    β”œβ”€β”€ myComponent1.js
    β”œβ”€β”€ myComponent2.js
    β”œβ”€β”€ myComponent3.js
    └── ...(.js)

The main.js file will contain the code in your main index.js file. If the main index.js file is empty, the main.js file can be excluded.

Important notes

When using the --split feature, each bundle will be build to function independently. That means, that you can include direflowComponent1.js in your host application, and expect the Web Component to work.

As a consequence, that also means that if both direflow-component-1 and direflow-component-2 is using a third-party dependency, or a shared module from the Direflow Setup, these will be included in both bundles.

If you find that your Direflow Components most often goes together, it may not be beneficial to use the --split feature.

Alternatively, you can combine both the--split and --vendor options:

yarn build --split --vendor
# or
npm run build --split --vendor

This will produce a build folder looking like this example:

.
└── build
    β”œβ”€β”€ main.js
    β”œβ”€β”€ vendor.js
    β”œβ”€β”€ myComponent1.js
    β”œβ”€β”€ myComponent2.js
    β”œβ”€β”€ myComponent3.js
    └── ...(.js)

In this case, all third-party dependencies will be collected in vendor.js.

If your setup needs more advanced build configuration, you can still add/override your own Webpack config in direflow-webpack.js.

Of course, you can still configure all components in the main index.js file. But in that case, the --split feature will have no effect.

Improved way to configure Direflow Components

We have introduced a cleaner way to configure a Direflow Component.

A very basic example looks like this:

import { DireflowComponent } from 'direflow-component';
import App from './App';

DireflowComponent.create({
  component: App,
  configuration: {
    tagname: 'cool-component',
  },
});

This new way of configuration introduces some breaking changes. Let’s go through them.

DireflowComponent is no longer instantiated

As we see above, we don’t need to create an instance of DireflowComponent anymore.

In order to configure a new Direflow Component, we simply use one static method:

DireflowComponent.create();

Configuration

Additionally, we don’t need to use a separate configure() method anymore. Everything is now configured in one configuration object that is passed to the create() method.

The configuration object looks like this:

{
  component: React.Component; // React Component,
  configuration: {
    tagname: string; // Tag name for the custom element, 
    useShadow?: boolean; // Whether to use Shadow Root
  },
  plugins?: Array<{ name, options? }>; // List of Direflow plugins
  properties?: object; // Set of properties 
}

New ways to provide properties

We also introduced 2 new ways of registering properties of the Direflow Component.

Method 1 β€” defaultProps

You can now simply set the defaultProps of the root React Component.

const App = (props) => {
  ...
}

App.defaultProps = {
  componentTitle: 'Awesome Component',
  sampleList: [
    'Create with React',
    'Build as Web Component',
    'Use it anywhere!',
  ],
}

Method 2 β€” class decorator

If you’re using a class component as the root React component, you can configure properties using a decorator.

import { DireflowConfiguration } from 'direflow-component';

@DireflowConfiguration({
  properties: {
    componentTitle: 'Awesome Component',
    sampleList: [
      'Create with React',
      'Build as Web Component',
      'Use it anywhere!',
    ],
  }
})
class App extends React.Component {
  ...
}

In fact, you can configure your entire Direflow Component using only the decorator, if preferred.

import { DireflowConfiguration } from 'direflow-component';

@DireflowConfiguration({
  configuration: {
    tagname: 'cool-component',
  },
  plugins: [
    {
      name: 'styled-components',
    }
  ],
  properties: {
    componentTitle: 'Awesome Component',
    sampleList: [
      'Create with React',
      'Build as Web Component',
      'Use it anywhere!',
    ],
  }
})
class App extends React.Component {
  ...
}

Since decorators is still an experimental feature, you must enable them in your setup.

See how to do that here: https://direflow.io/properties#prerequisites

Make Direflow Setup β€˜NPM-ready’ as part of CLI flow

When using direflow create, you can now choose to make your setup β€˜NPM-ready’.

If you choose β€˜yes’, additional fields will be added to the package.json of the boilerplate.

These fields include: author, license, keywords, homepage, repository, bugs, main and files.

Load scripts asynchronously with external-loader plugin

When using the external-loader plugin, you now have the option to load script files asynchronously.

Example:

plugins: [
  {
    name: 'external-loader',
    options: {
      paths: [
        {
          src: '[https://code.jquery.com/jquery-3.3.1.slim.min.js'](https://code.jquery.com/jquery-3.3.1.slim.min.js'),
          async: true,
        },
      ],
    }
  }
];

This will result in a script tag in the head section, that looks like this:

<script async src="[https://code.jquery.com/jquery-3.3.1.slim.min.js](https://code.jquery.com/jquery-3.3.1.slim.min.js')"></script>

Note the β€˜async’ attribute on the script tag.

Provide all answers in CLI flow as inline options

Finally, we have added the ability to provide all answers in the CLI flow as inline options.

That means, that you can now do this:

direflow create cool-new-component

The CLI flow will now prompt you for the remaining questions.

You can also choose to provide everything you need to specify in one long command:

direflow create cool-component -d "This component is pretty cool" --ts --eslint --npm

Export Direflow Components as regular React components

It is now possible to create a regular React component library out of your Direflow setup. This gives you the ability to maintain both a React component library and a Web Component library from the same source.

When you create a new Direflow Setup, a new file will be included: src/component-exports. This is the entry file of the React component library. In this file, we export all the components we need for our library:

import CoolComponent from './direflow-components/cool-component/App';
import AwesomeComponent from './direflow-components/awesome-component/App';

export {
  CoolComponent,
  AwesomeComponent,
}

Now, we can build the library using the command: npm run build:lib. This will create a folder /lib containing all the bundled files.

Now, add a field to package.json:

"main": "lib/component-exports.js"

And we’re ready to publish the React component library with npm publish.

Read more about this feature here: https://direflow.io/get-started#build-react-component-library

React module is loaded asynchronously

All React dependencies are now loaded asynchronously, as well as the polyfills and internals for Web Components.

This brings the initial bundle size of a Direflow Setup down to only 49kb!

It also means that when multiple Direflow bundles are included in a host application, they will all reuse the same React module.

Similarly, if the host application already uses React, any Direflow bundles that are included will simply β€œhook into” that React module instead of loading its own.

Inbuilt support for Material UI

Direflow now has inbuilt support for Material UI.

In order to include Material UI in your setup, simply install Material UI:

yarn add @material-ui/core
# or
npm install @material-ui/core

Then add the material-ui plugin to your Direflow Component:

plugins: [
  {
    name: 'material-ui'
  },
  ...
]

We have gathered a list of tips and best practices when using Material UI with Direflow. Read more about them here: https://direflow.io/additional#tips-for-material-ui

Migrating from 3.3 or below

If you are updating a Direflow Setup from v. 3.3 or below, you’ll have to make some changes in order to get the new setup to work.

Install direflow-scripts

First up, you need to install a new package: direflow-scripts.

npm install direflow-scripts

No go and change the scripts section of your package.json file:

"scripts": {
  "start": "direflow-scripts start",
  "build": "direflow-scripts build",
  "build:lib": "direflow-scripts build:lib",
  "test": "direflow-scripts test"
},

Use webpackConfig from direflow-scripts

Next, go to direflow-webpack.js and change the require statement on the first line:

const { webpackConfig } = require('direflow-scripts');

Move your components to src/direflow-components

Finally, move all your Direflow Components to src/direflow-components as shown here:

.
β”œβ”€β”€ public
β”‚   β”œβ”€β”€ index.css
β”‚   └── index.html
**β”œβ”€β”€ src
β”‚   β”œβ”€β”€ direflow-components
β”‚   β”‚   β”œβ”€β”€ my-component-1
β”‚   β”‚   β”‚   β”œβ”€β”€ ...
β”‚   β”‚   β”‚   └── index.js
β”‚   β”‚   β”œβ”€β”€ my-component-2
β”‚   β”‚   β”‚   β”œβ”€β”€ ...
β”‚   β”‚   β”‚   └── index.js
β”‚   β”‚   └── my-component-3
β”‚   β”‚       β”œβ”€β”€ ...
β”‚   β”‚       └── index.js**
β”‚   └── index.js
β”œβ”€β”€ direflow-webpack.js
β”œβ”€β”€ package.json
└── README.md

If you want to use the new --split feature, make sure to include an index.js or index.tsx file for each Direflow Component as seen in the example above.

However, this is optional. You can still create all the Direflow Components from src/index if you prefer.

Thank you to the community

Recently, Direflow has welcomed new collaborators, and we have received more contributions and community PRs.

THANK YOU!! πŸ‘πŸ‘πŸ‘

The time and effort that is put into this, thus the diversity of multiple developers from all across the world is what makes Direflow progress! πŸš€

Get started with Direflow

You can read all about how to get started using Direflow on our official webpage: https://direflow.io/

Your help is wanted!

If you find a bug or have a nice idea or a suggestion: Please create an issue on Direflow’s GitHub page.

If you have improved Direflow in any way, please create a Pull Request. It is greatly appreciated πŸ’œ

Please let us know if you build something cool with Direflow! It would be awesome to showcase it on our webpage πŸ€™