mirror of https://github.com/embarklabs/embark.git
fix(plugins/basic-pipeline): ensure correct webpack config is loaded
When making `basic-pipeline` in 948956ab1f
we've introduced a regression
and with this fix, a behaviour change as well::
1. The `webpackConfigName` passed to `Engine` is completely ignored, caused it to be
`undefined` down the line when the plugin tries to do its work (we essentially broke bundling)
2. With that configuration being ignored, we need a new way to make this configurable.
Since `basic-pipeline` is now a true plugin, it makes sense for itself to have configuration
options for that, while still providing decent defaults.
3. The trickly thing is that `webpackConfigName` used to have different values per command.
For example `build` used to use `production` while `run` used `development` as config.
4. This commit introduces new configuration options for `basic-pipeline` that lets users configure
the `webpackConfigName` per environment:
```json
// embark.json
{
...
"plugins": {
"embark-basic-pipeline": {
"development": {
webpackConfigName: "development"
},
"production": {
webpackConfigName: "production"
}
}
}
}
```
^ These are also the defaults. So not providing this configuration will make
Embark imply it.
Notice that this does not account for the "different config per command" case.
This means `embark build` will also use `development` by default.
Prior to this commit and the one mentioned above, the `webpackConfigName` was configurable
through the CMD `--pipeline` option. Since this a) no longer a built-in feature
and b) ignored at the moment anyways, I've removed the `--pipeline` options
from all commands as well.
BREAKING CHANGES
The commands `embark eject-webpack` and `embark eject-build-config` are no longer available.
The `--pipeline` option has been removed from all commands that used to support it.
This commit is contained in:
parent
5fe318bf23
commit
031ebe8bb2
|
@ -22,7 +22,6 @@ class Cmd {
|
||||||
this.simulator();
|
this.simulator();
|
||||||
this.test();
|
this.test();
|
||||||
this.reset();
|
this.reset();
|
||||||
this.ejectWebpack();
|
|
||||||
this.graph();
|
this.graph();
|
||||||
this.scaffold();
|
this.scaffold();
|
||||||
this.upload();
|
this.upload();
|
||||||
|
@ -137,7 +136,6 @@ class Cmd {
|
||||||
.option('-c, --client [client]', __('Use a specific ethereum client [%s] (default: %s)', 'geth, parity', 'geth'))
|
.option('-c, --client [client]', __('Use a specific ethereum client [%s] (default: %s)', 'geth, parity', 'geth'))
|
||||||
.option('--loglevel [loglevel]', __('level of logging to display') + ' ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'info')
|
.option('--loglevel [loglevel]', __('level of logging to display') + ' ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'info')
|
||||||
.option('--locale [locale]', __('language to use (default: en)'))
|
.option('--locale [locale]', __('language to use (default: en)'))
|
||||||
.option('--pipeline [pipeline]', __('webpack config to use (default: production)'))
|
|
||||||
.description(__('deploy and build dapp at ') + 'dist/ (default: development)')
|
.description(__('deploy and build dapp at ') + 'dist/ (default: development)')
|
||||||
.action((env, _options) => {
|
.action((env, _options) => {
|
||||||
setOrDetectLocale(_options.locale);
|
setOrDetectLocale(_options.locale);
|
||||||
|
@ -145,7 +143,6 @@ class Cmd {
|
||||||
_options.logFile = _options.logfile; // fix casing
|
_options.logFile = _options.logfile; // fix casing
|
||||||
_options.logLevel = _options.loglevel; // fix casing
|
_options.logLevel = _options.loglevel; // fix casing
|
||||||
_options.onlyCompile = _options.contracts;
|
_options.onlyCompile = _options.contracts;
|
||||||
_options.webpackConfigName = _options.pipeline || 'production';
|
|
||||||
this.embark.build(_options);
|
this.embark.build(_options);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -163,7 +160,6 @@ class Cmd {
|
||||||
.option('--logfile [logfile]', __('filename to output logs (default: %s)', 'none'))
|
.option('--logfile [logfile]', __('filename to output logs (default: %s)', 'none'))
|
||||||
.option('--loglevel [loglevel]', __('level of logging to display') + ' ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'info')
|
.option('--loglevel [loglevel]', __('level of logging to display') + ' ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'info')
|
||||||
.option('--locale [locale]', __('language to use (default: en)'))
|
.option('--locale [locale]', __('language to use (default: en)'))
|
||||||
.option('--pipeline [pipeline]', __('webpack config to use (default: development)'))
|
|
||||||
.option('--no-single-use-auth-token', __('disable the single use of token in cockpit'))
|
.option('--no-single-use-auth-token', __('disable the single use of token in cockpit'))
|
||||||
.description(__('run dapp (default: %s)', 'development'))
|
.description(__('run dapp (default: %s)', 'development'))
|
||||||
.action((env, options) => {
|
.action((env, options) => {
|
||||||
|
@ -178,7 +174,6 @@ class Cmd {
|
||||||
useDashboard: !options.nodashboard,
|
useDashboard: !options.nodashboard,
|
||||||
logFile: options.logfile,
|
logFile: options.logfile,
|
||||||
logLevel: options.loglevel,
|
logLevel: options.loglevel,
|
||||||
webpackConfigName: options.pipeline || 'development',
|
|
||||||
openBrowser: !options.nobrowser ? null : false,
|
openBrowser: !options.nobrowser ? null : false,
|
||||||
singleUseAuthToken: options.singleUseAuthToken
|
singleUseAuthToken: options.singleUseAuthToken
|
||||||
});
|
});
|
||||||
|
@ -216,7 +211,6 @@ class Cmd {
|
||||||
.option('--logfile [logfile]', __('filename to output logs (default: %s)', 'none'))
|
.option('--logfile [logfile]', __('filename to output logs (default: %s)', 'none'))
|
||||||
.option('--loglevel [loglevel]', __('level of logging to display') + ' ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'info')
|
.option('--loglevel [loglevel]', __('level of logging to display') + ' ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'info')
|
||||||
.option('--locale [locale]', __('language to use (default: en)'))
|
.option('--locale [locale]', __('language to use (default: en)'))
|
||||||
.option('--pipeline [pipeline]', __('webpack config to use (default: development)'))
|
|
||||||
.option('--no-single-use-auth-token', __('disable the single use of token in cockpit'))
|
.option('--no-single-use-auth-token', __('disable the single use of token in cockpit'))
|
||||||
.description(__('Start the Embark console'))
|
.description(__('Start the Embark console'))
|
||||||
.action((env, options) => {
|
.action((env, options) => {
|
||||||
|
@ -227,8 +221,7 @@ class Cmd {
|
||||||
locale: options.locale,
|
locale: options.locale,
|
||||||
logFile: options.logfile,
|
logFile: options.logfile,
|
||||||
logLevel: options.loglevel,
|
logLevel: options.loglevel,
|
||||||
singleUseAuthToken: options.singleUseAuthToken,
|
singleUseAuthToken: options.singleUseAuthToken
|
||||||
webpackConfigName: options.pipeline || 'development'
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -246,7 +239,6 @@ class Cmd {
|
||||||
.option('--logfile [logfile]', __('filename to output logs (default: %s)', 'none'))
|
.option('--logfile [logfile]', __('filename to output logs (default: %s)', 'none'))
|
||||||
.option('--loglevel [loglevel]', __('level of logging to display') + ' ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'info')
|
.option('--loglevel [loglevel]', __('level of logging to display') + ' ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'info')
|
||||||
.option('--locale [locale]', __('language to use (default: en)'))
|
.option('--locale [locale]', __('language to use (default: en)'))
|
||||||
.option('--pipeline [pipeline]', __('webpack config to use (default: development)'))
|
|
||||||
.option('--no-single-use-auth-token', __('disable the single use of token in cockpit'))
|
.option('--no-single-use-auth-token', __('disable the single use of token in cockpit'))
|
||||||
.description(__('run dapp (default: %s)', 'development'))
|
.description(__('run dapp (default: %s)', 'development'))
|
||||||
.action((env, options) => {
|
.action((env, options) => {
|
||||||
|
@ -261,7 +253,6 @@ class Cmd {
|
||||||
useDashboard: !options.nodashboard,
|
useDashboard: !options.nodashboard,
|
||||||
logFile: options.logfile,
|
logFile: options.logfile,
|
||||||
logLevel: options.loglevel,
|
logLevel: options.loglevel,
|
||||||
webpackConfigName: options.pipeline || 'development',
|
|
||||||
openBrowser: !options.nobrowser ? null : false,
|
openBrowser: !options.nobrowser ? null : false,
|
||||||
singleUseAuthToken: options.singleUseAuthToken
|
singleUseAuthToken: options.singleUseAuthToken
|
||||||
});
|
});
|
||||||
|
@ -346,7 +337,6 @@ class Cmd {
|
||||||
.option('--loglevel [loglevel]', __('level of logging to display') + ' ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'info')
|
.option('--loglevel [loglevel]', __('level of logging to display') + ' ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'info')
|
||||||
.option('--locale [locale]', __('language to use (default: en)'))
|
.option('--locale [locale]', __('language to use (default: en)'))
|
||||||
.option('-c, --client [client]', __('Use a specific ethereum client [%s] (default: %s)', 'geth, parity', 'geth'))
|
.option('-c, --client [client]', __('Use a specific ethereum client [%s] (default: %s)', 'geth, parity', 'geth'))
|
||||||
.option('--pipeline [pipeline]', __('webpack config to use (default: production)'))
|
|
||||||
.description(__('Upload your dapp to a decentralized storage') + '.')
|
.description(__('Upload your dapp to a decentralized storage') + '.')
|
||||||
.action((env, _options) => {
|
.action((env, _options) => {
|
||||||
setOrDetectLocale(_options.locale);
|
setOrDetectLocale(_options.locale);
|
||||||
|
@ -358,7 +348,6 @@ class Cmd {
|
||||||
_options.ensDomain = _options.ens;
|
_options.ensDomain = _options.ens;
|
||||||
_options.logFile = _options.logfile; // fix casing
|
_options.logFile = _options.logfile; // fix casing
|
||||||
_options.logLevel = _options.loglevel; // fix casing
|
_options.logLevel = _options.loglevel; // fix casing
|
||||||
_options.webpackConfigName = _options.pipeline || 'production';
|
|
||||||
this.embark.upload(_options);
|
this.embark.upload(_options);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -399,7 +388,6 @@ class Cmd {
|
||||||
options.logLevel = options.loglevel; // fix casing
|
options.logLevel = options.loglevel; // fix casing
|
||||||
options.onlyCompile = options.contracts;
|
options.onlyCompile = options.contracts;
|
||||||
options.client = options.client || 'geth';
|
options.client = options.client || 'geth';
|
||||||
options.webpackConfigName = options.pipeline || 'development';
|
|
||||||
options.contractOrFile = contractOrFile;
|
options.contractOrFile = contractOrFile;
|
||||||
options.fields = fields;
|
options.fields = fields;
|
||||||
|
|
||||||
|
@ -419,17 +407,6 @@ class Cmd {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ejectWebpack() {
|
|
||||||
program
|
|
||||||
.command('eject-build-config')
|
|
||||||
.alias('eject-webpack')
|
|
||||||
.description(__('copy the default build config into your dapp for customization'))
|
|
||||||
.action(() => {
|
|
||||||
this.embark.initConfig('development', {interceptLogs: false});
|
|
||||||
this.embark.ejectWebpack();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
versionCmd() {
|
versionCmd() {
|
||||||
program
|
program
|
||||||
.command('version')
|
.command('version')
|
||||||
|
@ -467,7 +444,7 @@ class Cmd {
|
||||||
suggestion = 'build --contracts';
|
suggestion = 'build --contracts';
|
||||||
} else {
|
} else {
|
||||||
const { proposeAlternative } = require('embark-utils');
|
const { proposeAlternative } = require('embark-utils');
|
||||||
let dictionary = ['new', 'demo', 'build', 'run', 'blockchain', 'simulator', 'test', 'upload', 'version', 'console', 'eject-webpack', 'graph', 'help', 'reset'];
|
let dictionary = ['new', 'demo', 'build', 'run', 'blockchain', 'simulator', 'test', 'upload', 'version', 'console', 'graph', 'help', 'reset'];
|
||||||
suggestion = proposeAlternative(cmd, dictionary);
|
suggestion = proposeAlternative(cmd, dictionary);
|
||||||
}
|
}
|
||||||
if (suggestion) {
|
if (suggestion) {
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
import { Config, Events, fs, TemplateGenerator } from 'embark-core';
|
import { Config, Events, TemplateGenerator } from 'embark-core';
|
||||||
import { Engine } from 'embark-engine';
|
import { Engine } from 'embark-engine';
|
||||||
import { __ } from 'embark-i18n';
|
import { __ } from 'embark-i18n';
|
||||||
import { dappPath, joinPath, setUpEnv } from 'embark-utils';
|
import { joinPath, setUpEnv } from 'embark-utils';
|
||||||
import { Logger, LogLevels } from 'embark-logger';
|
import { Logger, LogLevels } from 'embark-logger';
|
||||||
let async = require('async');
|
let async = require('async');
|
||||||
const constants = require('embark-core/constants');
|
const constants = require('embark-core/constants');
|
||||||
const { reset: embarkReset, paths: defaultResetPaths } = require('embark-reset');
|
const { reset: embarkReset, paths: defaultResetPaths } = require('embark-reset');
|
||||||
const cloneDeep = require('clone-deep');
|
const cloneDeep = require('clone-deep');
|
||||||
import findUp from 'find-up';
|
|
||||||
import { readJsonSync } from 'fs-extra';
|
import { readJsonSync } from 'fs-extra';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
|
@ -601,25 +600,6 @@ class EmbarkController {
|
||||||
await embarkReset({ removePaths });
|
await embarkReset({ removePaths });
|
||||||
}
|
}
|
||||||
|
|
||||||
ejectWebpack() {
|
|
||||||
const embarkConfig = findUp.sync(
|
|
||||||
'node_modules/embark-basic-pipeline/dist/webpack.config.js',
|
|
||||||
{cwd: __dirname}
|
|
||||||
);
|
|
||||||
const dappConfig = dappPath('webpack.config.js');
|
|
||||||
fs.copyPreserve(embarkConfig, dappConfig);
|
|
||||||
console.log(__('webpack config ejected to:').dim.yellow);
|
|
||||||
console.log(`${dappConfig}`.green);
|
|
||||||
const embarkOverrides = findUp.sync(
|
|
||||||
'node_modules/embark-basic-pipeline/dist/babel-loader-overrides.js',
|
|
||||||
{cwd: __dirname}
|
|
||||||
);
|
|
||||||
const dappOverrides = dappPath('babel-loader-overrides.js');
|
|
||||||
fs.copyPreserve(embarkOverrides, dappOverrides);
|
|
||||||
console.log(__('webpack overrides ejected to:').dim.yellow);
|
|
||||||
console.log(`${dappOverrides}`.green);
|
|
||||||
}
|
|
||||||
|
|
||||||
scaffold(options) {
|
scaffold(options) {
|
||||||
this.context = options.context || [constants.contexts.scaffold];
|
this.context = options.context || [constants.contexts.scaffold];
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ class BasicPipeline {
|
||||||
// this.useDashboard = options.useDashboard;
|
// this.useDashboard = options.useDashboard;
|
||||||
this.useDashboard = true;
|
this.useDashboard = true;
|
||||||
this.fs = embark.fs;
|
this.fs = embark.fs;
|
||||||
this.webpackConfigName = embark.config.webpackConfigName;
|
|
||||||
this.env = embark.config.env;
|
this.env = embark.config.env;
|
||||||
this.buildDir = embark.config.buildDir;
|
this.buildDir = embark.config.buildDir;
|
||||||
this.contractsFiles = embark.config.contractsFiles;
|
this.contractsFiles = embark.config.contractsFiles;
|
||||||
|
@ -28,6 +27,10 @@ class BasicPipeline {
|
||||||
this.plugins = embark.pluginsAPI;
|
this.plugins = embark.pluginsAPI;
|
||||||
this.pipelinePlugins = this.plugins.getPluginsFor('pipeline');
|
this.pipelinePlugins = this.plugins.getPluginsFor('pipeline');
|
||||||
this.pipelineConfig = embark.config.pipelineConfig;
|
this.pipelineConfig = embark.config.pipelineConfig;
|
||||||
|
|
||||||
|
const env = embark.config.env;
|
||||||
|
this.webpackConfigName = embark.pluginConfig[env]?.webpackConfigName ?? 'development';
|
||||||
|
|
||||||
let plugin = this.plugins.createPlugin('basic-pipeline', {});
|
let plugin = this.plugins.createPlugin('basic-pipeline', {});
|
||||||
|
|
||||||
plugin.registerActionForEvent("pipeline:generateAll:after", this.webpackAssets.bind(this));
|
plugin.registerActionForEvent("pipeline:generateAll:after", this.webpackAssets.bind(this));
|
||||||
|
|
|
@ -85,14 +85,6 @@ Option | Description
|
||||||
`--no-color` | no colors in case it's needed for compatbility purposes
|
`--no-color` | no colors in case it's needed for compatbility purposes
|
||||||
`--logfile` | `filename` to output logs (default: none)
|
`--logfile` | `filename` to output logs (default: none)
|
||||||
|
|
||||||
## eject-build-config
|
|
||||||
|
|
||||||
```
|
|
||||||
$ embark eject-build-config
|
|
||||||
```
|
|
||||||
|
|
||||||
Copies Embark's default `webpack.config.js` file into your DApp so that you can customize it. If a file named `webpack.config.js` is present in your top-level DApp directory, Embark will use your webpack config file instead of its own.
|
|
||||||
|
|
||||||
## blockchain
|
## blockchain
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
title: Building & Asset Pipeline
|
title: Building with Embark
|
||||||
layout: docs
|
layout: docs
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -13,19 +13,6 @@ By default, `embark build` will use the `production` mode to build our applicati
|
||||||
```
|
```
|
||||||
$ embark build
|
$ embark build
|
||||||
```
|
```
|
||||||
### Specifying a mode using `--pipeline`
|
|
||||||
|
|
||||||
|
|
||||||
Embark comes with two modes for building our application:
|
|
||||||
|
|
||||||
* **development** - This mode is for development purposes and produces sourcemaps as well as unoptimized client-side code. Whenever we use `embark run` or `embark console`, this mode is used by default. Since this mode skips code optimizations, it's also the faster mode.
|
|
||||||
* **production** - Unsurprisingly, this mode is used to create production artifacts of our application. It produces optimized code and therefore, takes longer to build. However, client-side code will be highly optimized, thus smaller in file size. This mode is the default for `embark build` and `embark upload` commands.
|
|
||||||
|
|
||||||
We can specify a mode using the `--pipeline` option. This is available for both, `embark run` and `embark build` commands:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ embark build --pipeline development
|
|
||||||
```
|
|
||||||
|
|
||||||
## Compiling Smart Contracts only
|
## Compiling Smart Contracts only
|
||||||
|
|
||||||
|
@ -35,44 +22,3 @@ If we're building a [Smart Contract only application](http://localhost:4000/docs
|
||||||
$ embark build --contracts
|
$ embark build --contracts
|
||||||
```
|
```
|
||||||
|
|
||||||
## Understanding the build pipeline
|
|
||||||
|
|
||||||
Embark uses [webpack](https://webpack.js.org/) to bundle and postprocess all kinds of assets of our decentralized application. This also includes things like:
|
|
||||||
|
|
||||||
* ES2015+ syntax using Babel
|
|
||||||
* Importing of CSS, SCSS, PNG, SVG & Fonts in JavaScript
|
|
||||||
* Support for React & JSX
|
|
||||||
* Automatic support for older browsers via Babel's preset-env (by default, Embark uses a browser list setting of `['last 1 version', 'not dead', '> 0.2%']`
|
|
||||||
* Sourcemaps generation (when in development mode)
|
|
||||||
* Minification and tree shaking (when in production mode)
|
|
||||||
|
|
||||||
{% notification danger 'Deprecation warning:' %}
|
|
||||||
Since Embark version 4.0.0 it's possible (and recommended) to use Embark in combination with other front-end tooling, such as Angular CLI, Vue CLI or Create React App, making Embark's own build pipeline obsolete.
|
|
||||||
|
|
||||||
When using Embark with any other existing front-end tooling, please turn off Embark's internal build pipeline by setting the following configuration option in `config/pipeline.js`:
|
|
||||||
|
|
||||||
<pre class="highlight">
|
|
||||||
enabled: false
|
|
||||||
</pre>
|
|
||||||
{% endnotification %}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Customizing the build process
|
|
||||||
|
|
||||||
Sometimes we run into scenarios where our setup is so specific that the build process for our application needs further customization. For those cases, where Embark's built-in build pipeline isn't enough, it enables us to "eject" the internally used `webpack.config.js` file, so we can change it to our needs and fully bypass Embark's internal build process.
|
|
||||||
|
|
||||||
Ejecting the internally used config file is as simple as using Embark's `eject-build-config` command like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ embark eject-build-config
|
|
||||||
```
|
|
||||||
|
|
||||||
{% notification info 'On --eject-webpack option' %}
|
|
||||||
In older versions of Embark, the same could be achieved using the `--eject-webpack` option. This option still works, but is now considered deprecated and will be removed in future versions of Embark.
|
|
||||||
{% endnotification %}
|
|
||||||
|
|
||||||
{% notification danger 'Deprecation warning:' %}
|
|
||||||
As mentioned earlier in this guide, we recommend using existing front-end tooling for building and optimizing your application's front-end code. This command will be deprecated in future versions of Embark.
|
|
||||||
{% endnotification %}
|
|
||||||
|
|
||||||
|
|
|
@ -54,19 +54,9 @@ If we aren't interested in Embark starting a web server in the first place, we c
|
||||||
$ embark run --noserver
|
$ embark run --noserver
|
||||||
```
|
```
|
||||||
|
|
||||||
## Running apps in different modes
|
|
||||||
|
|
||||||
Embark comes with different "modes" when building applications. `embark run` uses the `development` mode by default. However, this can be overwritten using the `--pipeline` option. The following command run our application in `production` mode.
|
|
||||||
|
|
||||||
```
|
|
||||||
$ embark run --pipeline production
|
|
||||||
```
|
|
||||||
|
|
||||||
For more information about modes, head over to our guide on [building apps](pipeline_and_webpack.html).
|
|
||||||
|
|
||||||
## Switching environments
|
## Switching environments
|
||||||
|
|
||||||
Embark allows for configuring different environments to run our app against. This can be useful if we want to deploy our app to test networks or even private networks. In order to run our application in a specified environment, we first have to add a dedicated configuration to our project's `blockchain.js` file.
|
Embark allows for configuring different environments to run our app against. This can be useful if we want to deploy our app to test networks or even private networks. In order to run our application in a specified environment, we first have to add a dedicated configuration to our project's `blockchain.js` file.
|
||||||
|
|
||||||
Depending on how you initialized your application, it may have already multiple environments configured. Here's what a sample test network environment could look like:
|
Depending on how you initialized your application, it may have already multiple environments configured. Here's what a sample test network environment could look like:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue