# Reactium Core

Reactium is built on a core framework. The local development and build configuration that comes out of the box is meant to be upgradeable, so long as your application was built off a semver that is minor-version compatible with the current.

Even for larger version steps, we are going to attempt to describe (or automate) much of the migration from one version of Reactium core to another.

Updating core is performed with the **`reactium`** command:

```bash
npx reactium update
```

> See: [Updating](https://docs.reactium.io/reactium/updating) for details

With a number of other front-end frameworks, even those based on React, the philosophy is to entirely hide the local development/build configuration from the developer, sometimes with an eject feature to get raw configuration / build files.

Our philosophy is to create a strong opinion for building a React application, from application structure, to out of the box capabilities such as routing, plugins, and state management, while giving the code maintainer, lead-dev, and ops roles on your team the power to replace, augment, or override behaviors of the build.

## Hacking Core

{% hint style="danger" %}
Should you hack reactium\_modules? Short answer: **no**
{% endhint %}

If you hack on the files in the **`reactium_modules`** directory of your project, those changes will be overwritten when executing routing `reactium install` operations, similar to `npm install` for **`node_modules`**. Instead of modifying these files directly, fork [**Reactium-Core-Plugins** on Github](https://github.com/Atomic-Reactor/Reactium-Core-Plugins) and send us a pull-request. We'll either add your update if appropriate.

That being said, there are a number of build and development overrides built-in to core for your use.

| Reason                                                                                                | Purpose                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | Where                                                                                                                                                                                                                                                                                                   |
| ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [**reactium-gulp.js**](https://docs.reactium.io/domain/buildtime-domain-model#reactium-gulp.js)       | DDD (domain-driven design) artifact to register/unregister gulp tasks with the ReactiumGulp registry, used to generate gulp tasks at build-time. You can use this in a Reactium plugin to alter gulp tasks within your own domain. Final tasks can be overriden by **gulp.tasks.override.js**.                                                                                                                                                                                                                                                 | <p></p><p>Create this file in any of the following:</p><ul><li>In any domain directory under <strong>src/</strong></li><li>In any node module's <strong>reactium-plugin/</strong> directory.</li><li>In any directory within a module under <strong>reactium\_modules/</strong></li></ul>               |
| [**reactium-webpack.js**](https://docs.reactium.io/domain/buildtime-domain-model#reactium-webpack.js) | DDD (domain-driven design) artifact to interact with the ReactiumWebpack registry, used to generate the webpack configuration at build-time. Final configuration can be overridden by **webpack.override.js**                                                                                                                                                                                                                                                                                                                                  | <p></p><p>Create this file in any of the following:</p><ul><li>In any domain directory under <strong>src/</strong></li><li>In any node module's <strong>reactium-plugin/</strong> directory.</li><li>In any directory within a module under <strong>reactium\_modules/</strong></li></ul>               |
| **gulp.config.override.js**                                                                           | <p><strong>Override:</strong> <strong>.core/gulp.config.js</strong></p><ul><li>Change build <strong>src/dest</strong> and <strong>port</strong></li></ul>                                                                                                                                                                                                                                                                                                                                                                                      | <p>Create this file in any of the following:</p><ul><li>Project root</li><li>In any node module's <strong>reactium-plugin/</strong> directory.</li><li>In any directory under <strong>src/</strong></li><li>In any directory within a module under <strong>reactium\_modules/</strong></li></ul>        |
| **gulp.tasks.override.js**                                                                            | <p><strong>Override:</strong> <strong>.core/gulp.tasks.js</strong></p><ul><li>Add pre or post build tasks. <br>Replace built-in tasks.</li><li>See <a href="../../domain#reactium-gulp-js"><strong>reactium-gulp.js</strong> DDD artifact </a>for more portable / modular way to approach changing gulp tasks.</li></ul>                                                                                                                                                                                                                       | Create this file in the project root.                                                                                                                                                                                                                                                                   |
| **manifest.config.override.js**                                                                       | <p><strong>Override:</strong> <strong>.core/reactium-config.js</strong></p><ul><li>Add component search context.</li><li>Add application dependencies to dependency module. </li></ul>                                                                                                                                                                                                                                                                                                                                                         | <p></p><p>Create this file in any of the following:</p><ul><li>Project root</li><li>In any node module's <strong>reactium-plugin/</strong> directory.</li><li>In any directory under <strong>src/</strong></li><li>In any directory within a module under <strong>reactium\_modules/</strong></li></ul> |
| **webpack.override.js**                                                                               | <p><strong>Override:</strong> <strong>.core/webpack.config.js</strong></p><ul><li>Make changes to the Webpack bundling process</li><li>Use this when you want access directly to change the webpack configuration data structure.</li><li>See <strong>reactium-webpack.js</strong> DDD artifact for more portable / modular way to approach manipulating webpack configuration.</li></ul>                                                                                                                                                      | <p></p><p>Create this file in any of the following:</p><ul><li>Project root</li><li>In any node module's <strong>reactium-plugin/</strong> directory.</li><li>In any directory under <strong>src/</strong></li><li>In any directory within a module under <strong>reactium\_modules/</strong></li></ul> |
| **webpack.umd.override.js**                                                                           | <p><strong>Override:</strong> <strong>.core/webpack.config.umd.js</strong></p><ul><li>Make changes to the Webpack bundling process for UMD (Universal Module Definition) modules, created automatically by <a href="../../domain#umd-js"><strong>umd.js</strong> DDD artifacts.</a></li><li>Use this when you want access directly to change the webpack configuration data structure.</li><li>See <strong>reactium-webpack.js</strong> DDD artifact for more portable / modular way to approach manipulating webpack configuration.</li></ul> | <p></p><p>Create this file in any of the following:</p><ul><li>Project root</li><li>In any node module's <strong>reactium-plugin/</strong> directory.</li><li>In any directory under <strong>src/</strong></li><li>In any directory within a module under <strong>reactium\_modules/</strong></li></ul> |
| **babel.config.js**                                                                                   | <p><strong>Override: .core/babel.config.js</strong></p><ul><li>Add Babel presets / plugins. </li><li>Add module alias for both server / compiled front-end.</li></ul>                                                                                                                                                                                                                                                                                                                                                                          | Must exist in the project root.                                                                                                                                                                                                                                                                         |

### gulp.config.override.js

Exports a function that takes core gulp configuration object as a parameter, and returns configuration object used by gulp tasks.

{% hint style="info" %}
In some case Webpack uses the gulp config.
{% endhint %}

{% code title="/gulp.config.override.js" %}

```javascript
module.exports = config => {

    // Electron configuration
    config.dest.electron = 'build-electron';
    config.dest.static = 'build-electron/app/public';
    config.electron = {
        config: {
            width: 1280,
            height: 1024,
            show: false,
            title: 'App Title',
            backgroundColor: '#000000',
        },
        devtools: true,
    };

    // Disable auto launch of default browser
    config.open = false;

    return config;
};
```

{% endcode %}

### gulp.tasks.override.js

Exports a function that takes an object defining core gulp tasks as a parameter, and returns and object whose properties define the tasks run by gulp.

```
Code example
```

### manifest.config.override.js

Exports a function that takes configuration the manifest-tools use to build src/manifest.js as a parameter, and returns new manifest configuration.

{% code title="/manifest.config.override.js" %}

```javascript
module.exports = config => {
    // Disable code splitting for Electron projects
    config.contexts.components.mode = 'sync';
    config.contexts.common.mode = 'sync';
    config.contexts.toolkit.mode = 'sync';
    config.contexts.core.mode = 'sync';

    return config;
};

```

{% endcode %}

### webpack.override.js

Exports a function that takes the core webpack configuration as a parameter, and returns an object that will be used for webpack to build the js bundle.

{% code title="/webpack.override.js" %}

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

/**
 * Passed the current webpack configuration from core
 * @param  {Object} webpackConfig the .core webpack configuration
 * @return {Object} your webpack configuration override
 */
module.exports = webpackConfig => {
    const newWebpackConfig = Object.assign({}, webpackConfig);

    newWebpackConfig.entries['entry'] = path.resolve('/path/to/my/entry');
  

    newWebpackConfig.plugins.push(new webpack.ContextReplacementPlugin(/^my-context/, context => {
      context.request = path.resolve('./src/app/my-context');
    }));

    return newWebpackConfig;
};
```

{% endcode %}

### webpack.umd.override.js

Serves the same purpose at the **webpack.override.js** except overrides the configuration used for each UMD (Universal Module Definition) module that is created by making a [**umd.js** DDD artifact](https://docs.reactium.io/domain#umd-js) in your project. The callback function you export will receive at separate webpack configuration for each umd.js module to be created.

{% code title="/webpack.umd.override.js" %}

```
/**
 * Passed the current webpack configuration from core
 * @param  {Object} umd module manifest configuration, generated when
 * umd files are located.
 * @param  {Object} webpackConfig the .core webpack configuration
 * @return {Object} your webpack configuration override
 */
module.exports = (umd, webpackConfig) => {
    if (umd.libraryName === 'media-uploader') {
        delete webpackConfig.module.rules;
    }
    return webpackConfig;
};

```

{% endcode %}

{% hint style="info" %}
To see what is generated for each umd in the manifest, look in **.tmp/umd-manifest.json** after running the build (**`npm run build`**). This will contain all the objects generated when looking for umd.js DDD artifacts. See the [umd-config.json DDD artifact](https://docs.reactium.io/domain#umd-config-json) for more information on controlling this behavior.
{% endhint %}

### babel.config.js

{% hint style="warning" %}
**Required** and provided by default.
{% endhint %}

Imports babel configuration and exports the configuration used by Webpack and babel-node.

{% code title="/babel.config.js" %}

```javascript
const config = require('./.core/babel.config');

// To add a module resolver for node and webpack
const path = require('path');

const moduleResolver = config.plugins.find(plugin => plugin[0] === 'module-resolver');
moduleResolver[1].alias['redux-addons'] = './src/app/redux-addons';

module.exports = config;
```

{% endcode %}

## Node/Express&#x20;

Important to dev-leads, ops and backend devs, there are a number of ways you can change the behavior of the core express server without hacking **.core**.

### Express Middleware

To add or change the stack of Node / Express middleware for the running server, create a **src/app/server/middleware.js** file, which should export a function taking an array of express middlewares as an argument, and returns the modified list of middlewares.

In this way, you can add/change routing, security configuration, etc to your hearts content.

#### Express Middleware Example #1:

{% code title="/src/app/server/middleware.js" %}

```javascript
module.exports = expressMiddlewares => {

    // Simple Logger
    const mySimpleRequestLogger = (req, res, next) => {
        console.log('SIMPLE LOGGER: REQUEST '+req.path);
        next();
    };

    return [
        {
            name: 'mySimpleRequestLogger',
            use: mySimpleRequestLogger,
        },
        ...expressMiddlewares,
    ];
};
```

{% endcode %}

**Express Middleware Example #2:**

{% code title="/src/app/server/middleware.js" %}

```javascript
// Health check route handler

const express = require('express');
const router = express.Router();

const healthy = router.get('/healthcheck', (req, res) => {
    res.status(200).send('ok');
});

module.exports = expressMiddlewares => {
    return [
        {
            name: 'myRouteHandler',
            use: router,
        },
        ...expressMiddlewares,
    ];
};
```

{% endcode %}

**Express Middleware Example #3:**

{% code title="/src/app/server/middleware.js" %}

```javascript
// More secure Cross Origin Request Sharing for production:

const cors = require('cors');

module.exports = expressMiddlewares => {
    return expressMiddlewares.map(mw => {
        // no change
        if (nw.name !== 'cors' || !('CORS_ORIGIN' in process.env)) {
            return mw;
        }

        // enforce origin
        return {
            name: 'cors',
            use: cors({
                origin: process.env.CORS_ORIGIN,
            }),
        };
    });
};
```

{% endcode %}

### Application Defines

Node/Express **global.defines** variables can be set by creating a **src/app/server/defines.js** file that exports a JavaScript object.

The file will also be used in constructing a Webpack defines plugin values.

Theoretically, your *server-side* and FE *(front-end)* code could make reference to values specified here.

Contrived **src/app/server/defines.js**:

{% code title="/src/app/server/defines.js" %}

```
module.exports = {
    foo: 'bar',
};
```

{% endcode %}

Isomorphic Define JS somewhere in front-end React code:

{% code title="/src/app/server/defines.js" %}

```javascript
let fooValue;
if (typeof window !== 'undefined') {
    fooValue = foo; // webpack define plugin
} else {
    fooValue = defines.foo; // node express global
}
```

{% endcode %}

### Environment Variables

Reactium uses the following environment variables:&#x20;

| Variable                    | Description                                                                                                                      |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| **PORT**                    | For environments where running application is specified by **`PORT`** var                                                        |
| **APP\_PORT**               | For environments where running application is specified by **APP\_PORT** var                                                     |
| **PORT\_VAR**               | Tells express where to look in environment variable to get the HTTP port setting                                                 |
| **DEBUG**                   | Enable or Disable logging                                                                                                        |
| **WEBPACK\_RESOURCE\_BASE** | Used to dynamically define the base URL where webpack bundles are served.                                                        |
| **PUBLIC\_DIRECTORY**       | Change the directory that express will serve static assets from                                                                  |
| **ACTINIUM\_APP\_ID**       | Used to identify the application when connecting Reactium to Actinium API. Defaults to **`Actinium`**                            |
| **REST\_API\_URL**          | Used when connecting Reactium to a REST API or Actinium                                                                          |
| **PROXY\_ACTINIUM\_API**    | When set to **`off`**, disables api proxy, and API calls will got direct to the API server.                                      |
| **PROXY\_API\_PATH**        | Defaults to **`/api`**. The path used to proxy to the API server. Use in tandem with **`REST_API_URL`** to control API behavior. |
| **ACTINIUM\_API\_ENABLED**  | When set to **`off`**, Actinium/Parse API will not be loaded.                                                                    |

#### WEBPACK\_RESOURCE\_BASE

Use this environment variable when you plan to upload your webpack assets to a CDN. It defaults to serving webpack assets from the document root at `/assets/js/.` If you wanted to upload the js folder to cdn.example.com for example, you might start the server like so:

```sh
WEBPACK_RESOURCE_BASE=https://cdn.example.com/js/ npm start
```

> **Default: /assets/js/**

**PORT**

Any TCP port appropriate for HTTP protocol (**port.proxy** in **./core/gulp.config.js**) where running application port is specified by **PORT** var.

> **Default:** **3030**

{% hint style="danger" %}
Some environments like [Heroku](https://devcenter.heroku.com/articles/deploying-nodejs) automatically set this value
{% endhint %}

#### APP\_PORT

Any TCP port appropriate for HTTP protocol (**port.proxy** in **./core/gulp.config.js**) where running application port is specified by **APP\_PORT** var.

> **Default:** **3030**

{% hint style="danger" %}
Some environments automatically set this value
{% endhint %}

#### DEBUG

Logging can be helpful for troubleshooting server-side rendering issues.&#x20;

{% hint style="info" %}
Server-side logging can drive front-end devs batty
{% endhint %}

* **off** to suppress logging to STDOUT
* **on** to enable logging

> **Default:** **off**

#### PUBLIC\_DIRECTORY

Full-path to public assets directory used the static middleware module.&#x20;

{% hint style="info" %}
If you have changed the build process to output static assets (js/css/images, etc) you will want to specify this value.&#x20;
{% endhint %}

> **Default: ./public**

#### **ACTINIUM\_APP\_ID**

Used by `@atomic-reactor/reactium-api` Reactium module, specify the Actinium Application ID used by [Actinium API](https://docs.reactium.io/actinium/actinium-core).

> **Default: Actinium**

#### **REST\_API\_URL**

Used by `@atomic-reactor/reactium-api` Reactium module, specify the fully qualified URL to the [Actinium API](https://docs.reactium.io/actinium/actinium-core) server.

{% hint style="info" %}
By default, this URL is proxied from any request on the Reactium host with path prefix /api. e.g. <https://myreactiumhost/api> proxies requests to <https://myactinumhost/api>
{% endhint %}

> **Default**: <http://localhost:9000/api>

{% hint style="warning" %}
While this default value eases local development, it is an unlikely value for production.
{% endhint %}

#### **PROXY\_ACTINIUM\_API**

Used by `@atomic-reactor/reactium-api` Reactium module, can be used to disable the proxy middleware to the Actinium API.

* **on**: Actinium API proxy is enabled. API calls direct through Reactium back-end and are proxied to Actinium API.
* **off**: Actinium API proxy is disabled. API calls go direct to Actinium API from the Reactium front-end.

> **Default**: on

{% hint style="info" %}
By proxying through the Reactium back-end, you won't have to worry about CORS.
{% endhint %}

#### **PROXY\_API\_PATH**

Used by `@atomic-reactor/reactium-api` Reactium module, can be used to set the front-end path that proxies to the Actinium API.

> **Default**: /api

#### **ACTINIUM\_API\_ENABLED**

Used by `@atomic-reactor/reactium-api` Reactium module, can be used to disable just the Actinium API.

* **on**: Actinium API is enabled
* **off**: Actinium API is disabled

> **Default**: on

{% hint style="info" %}
You can also uninstall the module, using arcli.
{% endhint %}

## Single Page App Template

The default templates are good for simple SPAs, but inevitably you will need to provide a different template for rendering your application's **index.html**.

To do so, generate server templates using ARCLI:&#x20;

```bash
reactium server template
```

Modify the newly created templates found in: **/src/app/server/template** directory

Reactium core will use your custom templates to serve your SPA so long as your template **version** string satisfies the **semver** property found for your **@atomic-reactor/reactium-core,** in your `reactiumDependencies` section of `package.json`.

You may need to update these templates after major and minor version updates of core.

To find out the **version** and **semver**:&#x20;

```bash
reactium version
```

{% hint style="danger" %}
**Important:** replace the **version** property string found in the SPA templates with the version number found in **reactium\_modules/@atomic-reactor/reactium-core/reactium-config.js**
{% endhint %}

## Static Build Template

There is a **/src/index-static.html** file provided, which can be used to compile a static **index.html** file when running static build:&#x20;

```
$ npm run static
```

This is for Reactium applications that will be served by another web-server like Apache, Nginx, Tomcat, etc.&#x20;

{% hint style="info" %}
Supports only front-end rendered React
{% endhint %}
