2023-04-25 16:32:51 +02:00
|
|
|
// TODO(ritave): Remove switches on hardcoded build types
|
|
|
|
|
2021-07-15 19:59:34 +02:00
|
|
|
const { callbackify } = require('util');
|
|
|
|
const path = require('path');
|
|
|
|
const { writeFileSync, readFileSync } = require('fs');
|
2021-03-26 05:26:19 +01:00
|
|
|
const EventEmitter = require('events');
|
2023-04-25 16:32:51 +02:00
|
|
|
const assert = require('assert');
|
2021-02-04 19:15:23 +01:00
|
|
|
const gulp = require('gulp');
|
|
|
|
const watch = require('gulp-watch');
|
2021-10-06 00:06:31 +02:00
|
|
|
const Vinyl = require('vinyl');
|
2021-02-04 19:15:23 +01:00
|
|
|
const source = require('vinyl-source-stream');
|
|
|
|
const buffer = require('vinyl-buffer');
|
|
|
|
const log = require('fancy-log');
|
|
|
|
const browserify = require('browserify');
|
2021-07-15 19:59:34 +02:00
|
|
|
const watchify = require('watchify');
|
2021-02-22 15:43:29 +01:00
|
|
|
const babelify = require('babelify');
|
|
|
|
const brfs = require('brfs');
|
2021-07-15 19:59:34 +02:00
|
|
|
const envify = require('loose-envify/custom');
|
|
|
|
const sourcemaps = require('gulp-sourcemaps');
|
|
|
|
const applySourceMap = require('vinyl-sourcemaps-apply');
|
2021-03-26 05:26:19 +01:00
|
|
|
const pify = require('pify');
|
2021-07-15 19:59:34 +02:00
|
|
|
const through = require('through2');
|
2021-03-26 05:26:19 +01:00
|
|
|
const endOfStream = pify(require('end-of-stream'));
|
|
|
|
const labeledStreamSplicer = require('labeled-stream-splicer').obj;
|
2021-07-15 19:59:34 +02:00
|
|
|
const wrapInStream = require('pumpify').obj;
|
|
|
|
const Sqrl = require('squirrelly');
|
2021-10-06 00:06:31 +02:00
|
|
|
const lavapack = require('@lavamoat/lavapack');
|
|
|
|
const lavamoatBrowserify = require('lavamoat-browserify');
|
2021-07-15 19:59:34 +02:00
|
|
|
const terser = require('terser');
|
2023-05-03 15:16:43 +02:00
|
|
|
const moduleResolver = require('babel-plugin-module-resolver');
|
2021-07-15 19:59:34 +02:00
|
|
|
|
|
|
|
const bifyModuleGroups = require('bify-module-groups');
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2022-11-30 16:19:45 +01:00
|
|
|
const phishingWarningManifest = require('@metamask/phishing-warning/package.json');
|
2022-07-27 21:32:17 +02:00
|
|
|
const { streamFlatMap } = require('../stream-flat-map');
|
2022-09-20 19:15:14 +02:00
|
|
|
const { generateIconNames } = require('../generate-icon-names');
|
Add validation to production build script (#15468)
Validation has been added to the build script when the "prod" target is
selected. We now ensure that all expected environment variables are
set, and that no extra environment variables are present (which might
indicate that the wrong configuration file is being used).
The `prod` target uses a new `.metamaskprodrc` configuration file. Each
required variable can be specified either via environment variable or
via this config file. CI will continue set these via environment
variable, but for local manual builds we can use the config file to
simplify the build process and ensure consistency.
A new "dist" target has been added to preserve the ability to build a
"production-like" build without this validation.
The config validation is invoked early in the script, in the CLI
argument parsing step, so that it would fail more quickly. Otherwise
we'd have to wait a few minutes longer for the validation to run.
This required some refactoring, moving functions to the utility module
and moving the config to a dedicated module.
Additionally, support has been added for all environment variables to
be set via the config file. Previously the values `PUBNUB_PUB_KEY`,
`PUBNUB_SUB_KEY`, `SENTRY_DSN`, and `SWAPS_USE_DEV_APIS` could only be
set via environment variable. Now, all of these variables can be set
either way.
Closes #15003
2022-08-19 20:16:18 +02:00
|
|
|
const { BUILD_TARGETS, ENVIRONMENT } = require('./constants');
|
2023-04-25 16:32:51 +02:00
|
|
|
const { getConfig } = require('./config');
|
Add validation to production build script (#15468)
Validation has been added to the build script when the "prod" target is
selected. We now ensure that all expected environment variables are
set, and that no extra environment variables are present (which might
indicate that the wrong configuration file is being used).
The `prod` target uses a new `.metamaskprodrc` configuration file. Each
required variable can be specified either via environment variable or
via this config file. CI will continue set these via environment
variable, but for local manual builds we can use the config file to
simplify the build process and ensure consistency.
A new "dist" target has been added to preserve the ability to build a
"production-like" build without this validation.
The config validation is invoked early in the script, in the CLI
argument parsing step, so that it would fail more quickly. Otherwise
we'd have to wait a few minutes longer for the validation to run.
This required some refactoring, moving functions to the utility module
and moving the config to a dedicated module.
Additionally, support has been added for all environment variables to
be set via the config file. Previously the values `PUBNUB_PUB_KEY`,
`PUBNUB_SUB_KEY`, `SENTRY_DSN`, and `SWAPS_USE_DEV_APIS` could only be
set via environment variable. Now, all of these variables can be set
either way.
Closes #15003
2022-08-19 20:16:18 +02:00
|
|
|
const {
|
|
|
|
isDevBuild,
|
|
|
|
isTestBuild,
|
|
|
|
getEnvironment,
|
|
|
|
logError,
|
2023-01-24 18:00:35 +01:00
|
|
|
wrapAgainstScuttling,
|
Add validation to production build script (#15468)
Validation has been added to the build script when the "prod" target is
selected. We now ensure that all expected environment variables are
set, and that no extra environment variables are present (which might
indicate that the wrong configuration file is being used).
The `prod` target uses a new `.metamaskprodrc` configuration file. Each
required variable can be specified either via environment variable or
via this config file. CI will continue set these via environment
variable, but for local manual builds we can use the config file to
simplify the build process and ensure consistency.
A new "dist" target has been added to preserve the ability to build a
"production-like" build without this validation.
The config validation is invoked early in the script, in the CLI
argument parsing step, so that it would fail more quickly. Otherwise
we'd have to wait a few minutes longer for the validation to run.
This required some refactoring, moving functions to the utility module
and moving the config to a dedicated module.
Additionally, support has been added for all environment variables to
be set via the config file. Previously the values `PUBNUB_PUB_KEY`,
`PUBNUB_SUB_KEY`, `SENTRY_DSN`, and `SWAPS_USE_DEV_APIS` could only be
set via environment variable. Now, all of these variables can be set
either way.
Closes #15003
2022-08-19 20:16:18 +02:00
|
|
|
} = require('./utils');
|
2021-09-08 22:08:23 +02:00
|
|
|
|
2020-11-03 00:41:28 +01:00
|
|
|
const {
|
|
|
|
createTask,
|
|
|
|
composeParallel,
|
|
|
|
composeSeries,
|
|
|
|
runInChildProcess,
|
2021-02-04 19:15:23 +01:00
|
|
|
} = require('./task');
|
Add build-time code exclusion using code fencing (#12060)
This PR adds build-time code exclusion by means of code fencing. For details, please see the README in `./development/build/transforms`. Note that linting of transformed files as a form of validation is added in a follow-up, #12075.
Hopefully exhaustive tests are added to ensure that the transform works according to its specification. Since these tests are Node-only, they required their own Jest config. The recommended way to work with multiple Jest configs is using the `projects` field in the Jest config, however [that feature breaks coverage collection](https://github.com/facebook/jest/issues/9628). That being the case, I had to set up two separate Jest configs. In order to get both test suites to run in parallel, Jest is now invoked via a script, `./test/run-jest.sh`.
By way of example, this build system feature allows us to add fences like this:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
///: BEGIN:ONLY_INCLUDE_IN(beta)
PluginController: this.pluginController,
///: END:ONLY_INCLUDE_IN
});
```
Which at build time are transformed to the following if the build type is not `beta`:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
});
```
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
2021-09-14 19:00:04 +02:00
|
|
|
const {
|
|
|
|
createRemoveFencedCodeTransform,
|
|
|
|
} = require('./transforms/remove-fenced-code');
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2023-01-24 18:00:35 +01:00
|
|
|
// map dist files to bag of needed native APIs against LM scuttling
|
2023-04-04 17:15:50 +02:00
|
|
|
const scuttlingConfigBase = {
|
2023-01-24 18:00:35 +01:00
|
|
|
'sentry-install.js': {
|
|
|
|
// globals sentry need to function
|
|
|
|
window: '',
|
|
|
|
navigator: '',
|
|
|
|
location: '',
|
|
|
|
Uint16Array: '',
|
|
|
|
fetch: '',
|
|
|
|
String: '',
|
|
|
|
Math: '',
|
|
|
|
Object: '',
|
|
|
|
Symbol: '',
|
|
|
|
Function: '',
|
|
|
|
Array: '',
|
|
|
|
Boolean: '',
|
|
|
|
Number: '',
|
|
|
|
Request: '',
|
|
|
|
Date: '',
|
|
|
|
JSON: '',
|
|
|
|
encodeURIComponent: '',
|
2023-04-19 18:57:02 +02:00
|
|
|
console: '',
|
2023-01-24 18:00:35 +01:00
|
|
|
crypto: '',
|
|
|
|
// {clear/set}Timeout are "this sensitive"
|
|
|
|
clearTimeout: 'window',
|
|
|
|
setTimeout: 'window',
|
|
|
|
// sentry special props
|
|
|
|
__SENTRY__: '',
|
|
|
|
sentryHooks: '',
|
|
|
|
sentry: '',
|
|
|
|
appState: '',
|
|
|
|
extra: '',
|
|
|
|
stateHooks: '',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2023-04-04 17:15:50 +02:00
|
|
|
const mv3ScuttlingConfig = { ...scuttlingConfigBase };
|
|
|
|
|
|
|
|
const standardScuttlingConfig = {
|
|
|
|
...scuttlingConfigBase,
|
|
|
|
'sentry-install.js': {
|
|
|
|
...scuttlingConfigBase['sentry-install.js'],
|
|
|
|
document: '',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2021-10-25 17:34:02 +02:00
|
|
|
/**
|
|
|
|
* Get the appropriate Infura project ID.
|
|
|
|
*
|
|
|
|
* @param {object} options - The Infura project ID options.
|
2023-04-25 16:32:51 +02:00
|
|
|
* @param {string} options.buildType - The current build type.
|
2021-10-25 17:34:02 +02:00
|
|
|
* @param {ENVIRONMENT[keyof ENVIRONMENT]} options.environment - The build environment.
|
2022-08-04 20:12:06 +02:00
|
|
|
* @param {boolean} options.testing - Whether this is a test build or not.
|
2023-04-25 16:32:51 +02:00
|
|
|
* @param options.variables
|
2021-10-25 17:34:02 +02:00
|
|
|
* @returns {string} The Infura project ID.
|
|
|
|
*/
|
2023-04-25 16:32:51 +02:00
|
|
|
function getInfuraProjectId({ buildType, variables, environment, testing }) {
|
2023-04-26 13:14:33 +02:00
|
|
|
const EMPTY_PROJECT_ID = '00000000000000000000000000000000';
|
2021-10-25 17:34:02 +02:00
|
|
|
if (testing) {
|
2023-04-26 13:14:33 +02:00
|
|
|
return EMPTY_PROJECT_ID;
|
2021-10-26 19:32:20 +02:00
|
|
|
} else if (environment !== ENVIRONMENT.PRODUCTION) {
|
|
|
|
// Skip validation because this is unset on PRs from forks.
|
2023-04-26 13:14:33 +02:00
|
|
|
// For forks, return empty project ID if we don't have one.
|
|
|
|
if (
|
|
|
|
!variables.isDefined('INFURA_PROJECT_ID') &&
|
|
|
|
environment === ENVIRONMENT.PULL_REQUEST
|
|
|
|
) {
|
|
|
|
return EMPTY_PROJECT_ID;
|
|
|
|
}
|
2023-04-25 16:32:51 +02:00
|
|
|
return variables.get('INFURA_PROJECT_ID');
|
2021-10-25 17:34:02 +02:00
|
|
|
}
|
2023-04-25 16:32:51 +02:00
|
|
|
/** @type {string|undefined} */
|
|
|
|
const infuraKeyReference = process.env.INFURA_ENV_KEY_REF;
|
|
|
|
assert(
|
|
|
|
typeof infuraKeyReference === 'string' && infuraKeyReference.length > 0,
|
|
|
|
`Build type "${buildType}" has improperly set INFURA_ENV_KEY_REF in builds.yml. Current value: "${infuraKeyReference}"`,
|
|
|
|
);
|
|
|
|
/** @type {string|undefined} */
|
|
|
|
const infuraProjectId = variables.get(infuraKeyReference);
|
|
|
|
assert(
|
|
|
|
typeof infuraProjectId === 'string' && infuraProjectId.length > 0,
|
|
|
|
`Infura Project ID environmental variable "${infuraKeyReference}" is set improperly.`,
|
|
|
|
);
|
|
|
|
return infuraProjectId;
|
2021-10-26 19:32:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the appropriate Segment write key.
|
|
|
|
*
|
|
|
|
* @param {object} options - The Segment write key options.
|
2023-04-25 16:32:51 +02:00
|
|
|
* @param {string} options.buildType - The current build type.
|
2022-01-07 16:57:33 +01:00
|
|
|
* @param {keyof ENVIRONMENT} options.environment - The current build environment.
|
2023-04-25 16:32:51 +02:00
|
|
|
* @param {import('../lib/variables').Variables} options.variables - Object containing all variables that modify the build pipeline
|
2021-10-26 19:32:20 +02:00
|
|
|
* @returns {string} The Segment write key.
|
|
|
|
*/
|
2023-04-25 16:32:51 +02:00
|
|
|
function getSegmentWriteKey({ buildType, variables, environment }) {
|
2021-10-26 19:32:20 +02:00
|
|
|
if (environment !== ENVIRONMENT.PRODUCTION) {
|
|
|
|
// Skip validation because this is unset on PRs from forks, and isn't necessary for development builds.
|
2023-04-25 16:32:51 +02:00
|
|
|
return variables.get('SEGMENT_WRITE_KEY');
|
2021-10-26 19:32:20 +02:00
|
|
|
}
|
2023-04-25 16:32:51 +02:00
|
|
|
|
|
|
|
const segmentKeyReference = process.env.SEGMENT_WRITE_KEY_REF;
|
|
|
|
assert(
|
|
|
|
typeof segmentKeyReference === 'string' && segmentKeyReference.length > 0,
|
|
|
|
`Build type "${buildType}" has improperly set SEGMENT_WRITE_KEY_REF in builds.yml. Current value: "${segmentKeyReference}"`,
|
|
|
|
);
|
|
|
|
|
|
|
|
const segmentWriteKey = variables.get(segmentKeyReference);
|
|
|
|
assert(
|
|
|
|
typeof segmentWriteKey === 'string' && segmentWriteKey.length > 0,
|
|
|
|
`Segment Write Key environmental variable "${segmentKeyReference}" is set improperly.`,
|
|
|
|
);
|
|
|
|
return segmentWriteKey;
|
2021-10-25 17:34:02 +02:00
|
|
|
}
|
|
|
|
|
2022-05-06 00:28:48 +02:00
|
|
|
/**
|
|
|
|
* Get the URL for the phishing warning page, if it has been set.
|
|
|
|
*
|
2022-05-16 22:55:48 +02:00
|
|
|
* @param {object} options - The phishing warning page options.
|
|
|
|
* @param {boolean} options.testing - Whether this is a test build or not.
|
2023-04-25 16:32:51 +02:00
|
|
|
* @param {import('../lib/variables').Variables} options.variables - Object containing all variables that modify the build pipeline
|
2022-05-06 00:28:48 +02:00
|
|
|
* @returns {string} The URL for the phishing warning page, or `undefined` if no URL is set.
|
|
|
|
*/
|
2023-04-25 16:32:51 +02:00
|
|
|
function getPhishingWarningPageUrl({ variables, testing }) {
|
|
|
|
let phishingWarningPageUrl = variables.get('PHISHING_WARNING_PAGE_URL');
|
2022-05-06 00:28:48 +02:00
|
|
|
|
2023-04-25 16:32:51 +02:00
|
|
|
assert(
|
|
|
|
phishingWarningPageUrl === null ||
|
|
|
|
typeof phishingWarningPageUrl === 'string',
|
|
|
|
);
|
|
|
|
if (phishingWarningPageUrl === null) {
|
2022-05-06 00:28:48 +02:00
|
|
|
phishingWarningPageUrl = testing
|
|
|
|
? 'http://localhost:9999/'
|
2022-10-07 18:49:20 +02:00
|
|
|
: `https://metamask.github.io/phishing-warning/v${phishingWarningManifest.version}/`;
|
2022-05-06 00:28:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// We add a hash/fragment to the URL dynamically, so we need to ensure it
|
|
|
|
// has a valid pathname to append a hash to.
|
|
|
|
const normalizedUrl = phishingWarningPageUrl.endsWith('/')
|
|
|
|
? phishingWarningPageUrl
|
|
|
|
: `${phishingWarningPageUrl}/`;
|
|
|
|
|
|
|
|
let phishingWarningPageUrlObject;
|
|
|
|
try {
|
|
|
|
// eslint-disable-next-line no-new
|
|
|
|
phishingWarningPageUrlObject = new URL(normalizedUrl);
|
|
|
|
} catch (error) {
|
|
|
|
throw new Error(
|
|
|
|
`Invalid phishing warning page URL: '${normalizedUrl}'`,
|
|
|
|
error,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (phishingWarningPageUrlObject.hash) {
|
|
|
|
// The URL fragment must be set dynamically
|
|
|
|
throw new Error(
|
|
|
|
`URL fragment not allowed in phishing warning page URL: '${normalizedUrl}'`,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return normalizedUrl;
|
|
|
|
}
|
|
|
|
|
2021-11-26 21:08:23 +01:00
|
|
|
const noopWriteStream = through.obj((_file, _fileEncoding, callback) =>
|
|
|
|
callback(),
|
|
|
|
);
|
|
|
|
|
2021-02-04 19:15:23 +01:00
|
|
|
module.exports = createScriptTasks;
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2022-07-27 17:34:02 +02:00
|
|
|
/**
|
|
|
|
* Create tasks for building JavaScript bundles and templates. One
|
|
|
|
* task is returned for each build target. These build target tasks are
|
|
|
|
* each composed of smaller tasks.
|
|
|
|
*
|
|
|
|
* @param {object} options - Build options.
|
|
|
|
* @param {boolean} options.applyLavaMoat - Whether the build should use
|
|
|
|
* LavaMoat at runtime or not.
|
|
|
|
* @param {string[]} options.browserPlatforms - A list of browser platforms to
|
|
|
|
* build bundles for.
|
2023-04-25 16:32:51 +02:00
|
|
|
* @param {string} options.buildType - The current build type (e.g. "main",
|
2022-07-27 17:34:02 +02:00
|
|
|
* "flask", etc.).
|
|
|
|
* @param {string[] | null} options.ignoredFiles - A list of files to exclude
|
|
|
|
* from the current build.
|
|
|
|
* @param {boolean} options.isLavaMoat - Whether this build script is being run
|
|
|
|
* using LavaMoat or not.
|
|
|
|
* @param {object} options.livereload - The "gulp-livereload" server instance.
|
|
|
|
* @param {boolean} options.policyOnly - Whether to stop the build after
|
|
|
|
* generating the LavaMoat policy, skipping any writes to disk other than the
|
|
|
|
* LavaMoat policy itself.
|
|
|
|
* @param {boolean} options.shouldLintFenceFiles - Whether files with code
|
|
|
|
* fences should be linted after fences have been removed.
|
|
|
|
* @param {string} options.version - The current version of the extension.
|
|
|
|
* @returns {object} A set of tasks, one for each build target.
|
|
|
|
*/
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
function createScriptTasks({
|
2022-04-30 00:56:30 +02:00
|
|
|
applyLavaMoat,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
browserPlatforms,
|
|
|
|
buildType,
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
ignoredFiles,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
isLavaMoat,
|
|
|
|
livereload,
|
2021-11-26 21:08:23 +01:00
|
|
|
policyOnly,
|
2022-07-27 17:34:02 +02:00
|
|
|
shouldLintFenceFiles,
|
2022-03-10 17:01:50 +01:00
|
|
|
version,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
}) {
|
Add validation to production build script (#15468)
Validation has been added to the build script when the "prod" target is
selected. We now ensure that all expected environment variables are
set, and that no extra environment variables are present (which might
indicate that the wrong configuration file is being used).
The `prod` target uses a new `.metamaskprodrc` configuration file. Each
required variable can be specified either via environment variable or
via this config file. CI will continue set these via environment
variable, but for local manual builds we can use the config file to
simplify the build process and ensure consistency.
A new "dist" target has been added to preserve the ability to build a
"production-like" build without this validation.
The config validation is invoked early in the script, in the CLI
argument parsing step, so that it would fail more quickly. Otherwise
we'd have to wait a few minutes longer for the validation to run.
This required some refactoring, moving functions to the utility module
and moving the config to a dedicated module.
Additionally, support has been added for all environment variables to
be set via the config file. Previously the values `PUBNUB_PUB_KEY`,
`PUBNUB_SUB_KEY`, `SENTRY_DSN`, and `SWAPS_USE_DEV_APIS` could only be
set via environment variable. Now, all of these variables can be set
either way.
Closes #15003
2022-08-19 20:16:18 +02:00
|
|
|
// high level tasks
|
|
|
|
return {
|
2020-03-09 01:55:02 +01:00
|
|
|
// dev tasks (live reload)
|
2022-07-22 01:33:28 +02:00
|
|
|
dev: createTasksForScriptBundles({
|
Add validation to production build script (#15468)
Validation has been added to the build script when the "prod" target is
selected. We now ensure that all expected environment variables are
set, and that no extra environment variables are present (which might
indicate that the wrong configuration file is being used).
The `prod` target uses a new `.metamaskprodrc` configuration file. Each
required variable can be specified either via environment variable or
via this config file. CI will continue set these via environment
variable, but for local manual builds we can use the config file to
simplify the build process and ensure consistency.
A new "dist" target has been added to preserve the ability to build a
"production-like" build without this validation.
The config validation is invoked early in the script, in the CLI
argument parsing step, so that it would fail more quickly. Otherwise
we'd have to wait a few minutes longer for the validation to run.
This required some refactoring, moving functions to the utility module
and moving the config to a dedicated module.
Additionally, support has been added for all environment variables to
be set via the config file. Previously the values `PUBNUB_PUB_KEY`,
`PUBNUB_SUB_KEY`, `SENTRY_DSN`, and `SWAPS_USE_DEV_APIS` could only be
set via environment variable. Now, all of these variables can be set
either way.
Closes #15003
2022-08-19 20:16:18 +02:00
|
|
|
buildTarget: BUILD_TARGETS.DEV,
|
2020-11-03 00:41:28 +01:00
|
|
|
taskPrefix: 'scripts:core:dev',
|
|
|
|
}),
|
Add validation to production build script (#15468)
Validation has been added to the build script when the "prod" target is
selected. We now ensure that all expected environment variables are
set, and that no extra environment variables are present (which might
indicate that the wrong configuration file is being used).
The `prod` target uses a new `.metamaskprodrc` configuration file. Each
required variable can be specified either via environment variable or
via this config file. CI will continue set these via environment
variable, but for local manual builds we can use the config file to
simplify the build process and ensure consistency.
A new "dist" target has been added to preserve the ability to build a
"production-like" build without this validation.
The config validation is invoked early in the script, in the CLI
argument parsing step, so that it would fail more quickly. Otherwise
we'd have to wait a few minutes longer for the validation to run.
This required some refactoring, moving functions to the utility module
and moving the config to a dedicated module.
Additionally, support has been added for all environment variables to
be set via the config file. Previously the values `PUBNUB_PUB_KEY`,
`PUBNUB_SUB_KEY`, `SENTRY_DSN`, and `SWAPS_USE_DEV_APIS` could only be
set via environment variable. Now, all of these variables can be set
either way.
Closes #15003
2022-08-19 20:16:18 +02:00
|
|
|
// production-like distributable build
|
|
|
|
dist: createTasksForScriptBundles({
|
|
|
|
buildTarget: BUILD_TARGETS.DIST,
|
|
|
|
taskPrefix: 'scripts:core:dist',
|
|
|
|
}),
|
2022-08-04 20:12:06 +02:00
|
|
|
// production
|
|
|
|
prod: createTasksForScriptBundles({
|
Add validation to production build script (#15468)
Validation has been added to the build script when the "prod" target is
selected. We now ensure that all expected environment variables are
set, and that no extra environment variables are present (which might
indicate that the wrong configuration file is being used).
The `prod` target uses a new `.metamaskprodrc` configuration file. Each
required variable can be specified either via environment variable or
via this config file. CI will continue set these via environment
variable, but for local manual builds we can use the config file to
simplify the build process and ensure consistency.
A new "dist" target has been added to preserve the ability to build a
"production-like" build without this validation.
The config validation is invoked early in the script, in the CLI
argument parsing step, so that it would fail more quickly. Otherwise
we'd have to wait a few minutes longer for the validation to run.
This required some refactoring, moving functions to the utility module
and moving the config to a dedicated module.
Additionally, support has been added for all environment variables to
be set via the config file. Previously the values `PUBNUB_PUB_KEY`,
`PUBNUB_SUB_KEY`, `SENTRY_DSN`, and `SWAPS_USE_DEV_APIS` could only be
set via environment variable. Now, all of these variables can be set
either way.
Closes #15003
2022-08-19 20:16:18 +02:00
|
|
|
buildTarget: BUILD_TARGETS.PROD,
|
2022-08-04 20:12:06 +02:00
|
|
|
taskPrefix: 'scripts:core:prod',
|
2020-11-03 00:41:28 +01:00
|
|
|
}),
|
2020-03-09 01:55:02 +01:00
|
|
|
// built for CI tests
|
2022-07-22 01:33:28 +02:00
|
|
|
test: createTasksForScriptBundles({
|
Add validation to production build script (#15468)
Validation has been added to the build script when the "prod" target is
selected. We now ensure that all expected environment variables are
set, and that no extra environment variables are present (which might
indicate that the wrong configuration file is being used).
The `prod` target uses a new `.metamaskprodrc` configuration file. Each
required variable can be specified either via environment variable or
via this config file. CI will continue set these via environment
variable, but for local manual builds we can use the config file to
simplify the build process and ensure consistency.
A new "dist" target has been added to preserve the ability to build a
"production-like" build without this validation.
The config validation is invoked early in the script, in the CLI
argument parsing step, so that it would fail more quickly. Otherwise
we'd have to wait a few minutes longer for the validation to run.
This required some refactoring, moving functions to the utility module
and moving the config to a dedicated module.
Additionally, support has been added for all environment variables to
be set via the config file. Previously the values `PUBNUB_PUB_KEY`,
`PUBNUB_SUB_KEY`, `SENTRY_DSN`, and `SWAPS_USE_DEV_APIS` could only be
set via environment variable. Now, all of these variables can be set
either way.
Closes #15003
2022-08-19 20:16:18 +02:00
|
|
|
buildTarget: BUILD_TARGETS.TEST,
|
2020-11-03 00:41:28 +01:00
|
|
|
taskPrefix: 'scripts:core:test',
|
|
|
|
}),
|
2022-08-04 20:12:06 +02:00
|
|
|
// built for CI test debugging
|
|
|
|
testDev: createTasksForScriptBundles({
|
Add validation to production build script (#15468)
Validation has been added to the build script when the "prod" target is
selected. We now ensure that all expected environment variables are
set, and that no extra environment variables are present (which might
indicate that the wrong configuration file is being used).
The `prod` target uses a new `.metamaskprodrc` configuration file. Each
required variable can be specified either via environment variable or
via this config file. CI will continue set these via environment
variable, but for local manual builds we can use the config file to
simplify the build process and ensure consistency.
A new "dist" target has been added to preserve the ability to build a
"production-like" build without this validation.
The config validation is invoked early in the script, in the CLI
argument parsing step, so that it would fail more quickly. Otherwise
we'd have to wait a few minutes longer for the validation to run.
This required some refactoring, moving functions to the utility module
and moving the config to a dedicated module.
Additionally, support has been added for all environment variables to
be set via the config file. Previously the values `PUBNUB_PUB_KEY`,
`PUBNUB_SUB_KEY`, `SENTRY_DSN`, and `SWAPS_USE_DEV_APIS` could only be
set via environment variable. Now, all of these variables can be set
either way.
Closes #15003
2022-08-19 20:16:18 +02:00
|
|
|
buildTarget: BUILD_TARGETS.TEST_DEV,
|
2022-08-04 20:12:06 +02:00
|
|
|
taskPrefix: 'scripts:core:test-live',
|
|
|
|
}),
|
2021-02-04 19:15:23 +01:00
|
|
|
};
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2022-07-27 17:34:02 +02:00
|
|
|
/**
|
|
|
|
* Define tasks for building the JavaScript modules used by the extension.
|
|
|
|
* This function returns a single task that builds JavaScript modules in
|
|
|
|
* parallel for a single type of build (e.g. dev, testing, production).
|
|
|
|
*
|
|
|
|
* @param {object} options - The build options.
|
2022-08-04 20:12:06 +02:00
|
|
|
* @param {BUILD_TARGETS} options.buildTarget - The build target that these
|
|
|
|
* JavaScript modules are intended for.
|
2022-07-27 17:34:02 +02:00
|
|
|
* @param {string} options.taskPrefix - The prefix to use for the name of
|
|
|
|
* each defined task.
|
|
|
|
*/
|
2022-08-04 20:12:06 +02:00
|
|
|
function createTasksForScriptBundles({ buildTarget, taskPrefix }) {
|
2021-08-31 05:58:50 +02:00
|
|
|
const standardEntryPoints = ['background', 'ui', 'content-script'];
|
2021-07-15 19:59:34 +02:00
|
|
|
const standardSubtask = createTask(
|
|
|
|
`${taskPrefix}:standardEntryPoints`,
|
|
|
|
createFactoredBuild({
|
2022-04-30 00:56:30 +02:00
|
|
|
applyLavaMoat,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
browserPlatforms,
|
2022-08-04 20:12:06 +02:00
|
|
|
buildTarget,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
buildType,
|
2021-08-18 13:26:44 +02:00
|
|
|
entryFiles: standardEntryPoints.map((label) => {
|
|
|
|
if (label === 'content-script') {
|
|
|
|
return './app/vendor/trezor/content-script.js';
|
|
|
|
}
|
|
|
|
return `./app/scripts/${label}.js`;
|
|
|
|
}),
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
ignoredFiles,
|
2021-11-26 21:08:23 +01:00
|
|
|
policyOnly,
|
2021-09-16 05:18:28 +02:00
|
|
|
shouldLintFenceFiles,
|
2022-03-10 17:01:50 +01:00
|
|
|
version,
|
2020-11-03 00:41:28 +01:00
|
|
|
}),
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2020-12-14 20:17:13 +01:00
|
|
|
|
2020-03-09 01:55:02 +01:00
|
|
|
// inpage must be built before contentscript
|
|
|
|
// because inpage bundle result is included inside contentscript
|
2020-11-03 00:41:28 +01:00
|
|
|
const contentscriptSubtask = createTask(
|
|
|
|
`${taskPrefix}:contentscript`,
|
2022-08-04 20:12:06 +02:00
|
|
|
createContentscriptBundle({ buildTarget }),
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2020-12-14 20:17:13 +01:00
|
|
|
// this can run whenever
|
|
|
|
const disableConsoleSubtask = createTask(
|
|
|
|
`${taskPrefix}:disable-console`,
|
2022-08-04 20:12:06 +02:00
|
|
|
createDisableConsoleBundle({ buildTarget }),
|
2021-07-15 19:59:34 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
// this can run whenever
|
|
|
|
const installSentrySubtask = createTask(
|
|
|
|
`${taskPrefix}:sentry`,
|
2022-08-04 20:12:06 +02:00
|
|
|
createSentryBundle({ buildTarget }),
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2020-12-14 20:17:13 +01:00
|
|
|
|
2021-03-26 05:26:19 +01:00
|
|
|
// task for initiating browser livereload
|
2020-03-09 01:55:02 +01:00
|
|
|
const initiateLiveReload = async () => {
|
2022-08-04 20:12:06 +02:00
|
|
|
if (isDevBuild(buildTarget)) {
|
2020-03-09 01:55:02 +01:00
|
|
|
// trigger live reload when the bundles are updated
|
|
|
|
// this is not ideal, but overcomes the limitations:
|
|
|
|
// - run from the main process (not child process tasks)
|
|
|
|
// - after the first build has completed (thus the timeout)
|
|
|
|
// - build tasks never "complete" when run with livereload + child process
|
|
|
|
setTimeout(() => {
|
|
|
|
watch('./dist/*/*.js', (event) => {
|
2021-02-04 19:15:23 +01:00
|
|
|
livereload.changed(event.path);
|
|
|
|
});
|
|
|
|
}, 75e3);
|
2020-03-09 01:55:02 +01:00
|
|
|
}
|
2021-02-04 19:15:23 +01:00
|
|
|
};
|
2020-03-09 01:55:02 +01:00
|
|
|
|
|
|
|
// make each bundle run in a separate process
|
2020-11-03 00:41:28 +01:00
|
|
|
const allSubtasks = [
|
2021-07-15 19:59:34 +02:00
|
|
|
standardSubtask,
|
2020-11-03 00:41:28 +01:00
|
|
|
contentscriptSubtask,
|
2020-12-14 20:17:13 +01:00
|
|
|
disableConsoleSubtask,
|
2021-07-15 19:59:34 +02:00
|
|
|
installSentrySubtask,
|
Add build-time code exclusion using code fencing (#12060)
This PR adds build-time code exclusion by means of code fencing. For details, please see the README in `./development/build/transforms`. Note that linting of transformed files as a form of validation is added in a follow-up, #12075.
Hopefully exhaustive tests are added to ensure that the transform works according to its specification. Since these tests are Node-only, they required their own Jest config. The recommended way to work with multiple Jest configs is using the `projects` field in the Jest config, however [that feature breaks coverage collection](https://github.com/facebook/jest/issues/9628). That being the case, I had to set up two separate Jest configs. In order to get both test suites to run in parallel, Jest is now invoked via a script, `./test/run-jest.sh`.
By way of example, this build system feature allows us to add fences like this:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
///: BEGIN:ONLY_INCLUDE_IN(beta)
PluginController: this.pluginController,
///: END:ONLY_INCLUDE_IN
});
```
Which at build time are transformed to the following if the build type is not `beta`:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
});
```
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
2021-09-14 19:00:04 +02:00
|
|
|
].map((subtask) =>
|
|
|
|
runInChildProcess(subtask, {
|
2022-05-03 00:35:52 +02:00
|
|
|
applyLavaMoat,
|
Add build-time code exclusion using code fencing (#12060)
This PR adds build-time code exclusion by means of code fencing. For details, please see the README in `./development/build/transforms`. Note that linting of transformed files as a form of validation is added in a follow-up, #12075.
Hopefully exhaustive tests are added to ensure that the transform works according to its specification. Since these tests are Node-only, they required their own Jest config. The recommended way to work with multiple Jest configs is using the `projects` field in the Jest config, however [that feature breaks coverage collection](https://github.com/facebook/jest/issues/9628). That being the case, I had to set up two separate Jest configs. In order to get both test suites to run in parallel, Jest is now invoked via a script, `./test/run-jest.sh`.
By way of example, this build system feature allows us to add fences like this:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
///: BEGIN:ONLY_INCLUDE_IN(beta)
PluginController: this.pluginController,
///: END:ONLY_INCLUDE_IN
});
```
Which at build time are transformed to the following if the build type is not `beta`:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
});
```
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
2021-09-14 19:00:04 +02:00
|
|
|
buildType,
|
|
|
|
isLavaMoat,
|
2021-11-26 21:08:23 +01:00
|
|
|
policyOnly,
|
2021-09-16 05:18:28 +02:00
|
|
|
shouldLintFenceFiles,
|
Add build-time code exclusion using code fencing (#12060)
This PR adds build-time code exclusion by means of code fencing. For details, please see the README in `./development/build/transforms`. Note that linting of transformed files as a form of validation is added in a follow-up, #12075.
Hopefully exhaustive tests are added to ensure that the transform works according to its specification. Since these tests are Node-only, they required their own Jest config. The recommended way to work with multiple Jest configs is using the `projects` field in the Jest config, however [that feature breaks coverage collection](https://github.com/facebook/jest/issues/9628). That being the case, I had to set up two separate Jest configs. In order to get both test suites to run in parallel, Jest is now invoked via a script, `./test/run-jest.sh`.
By way of example, this build system feature allows us to add fences like this:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
///: BEGIN:ONLY_INCLUDE_IN(beta)
PluginController: this.pluginController,
///: END:ONLY_INCLUDE_IN
});
```
Which at build time are transformed to the following if the build type is not `beta`:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
});
```
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
2021-09-14 19:00:04 +02:00
|
|
|
}),
|
|
|
|
);
|
2020-03-09 01:55:02 +01:00
|
|
|
// make a parent task that runs each task in a child thread
|
2021-02-04 19:15:23 +01:00
|
|
|
return composeParallel(initiateLiveReload, ...allSubtasks);
|
2020-03-09 01:55:02 +01:00
|
|
|
}
|
|
|
|
|
2022-07-27 17:34:02 +02:00
|
|
|
/**
|
|
|
|
* Create a bundle for the "disable-console" module.
|
|
|
|
*
|
|
|
|
* @param {object} options - The build options.
|
2022-08-04 20:12:06 +02:00
|
|
|
* @param {BUILD_TARGETS} options.buildTarget - The current build target.
|
2022-07-27 17:34:02 +02:00
|
|
|
* @returns {Function} A function that creates the bundle.
|
|
|
|
*/
|
2022-08-04 20:12:06 +02:00
|
|
|
function createDisableConsoleBundle({ buildTarget }) {
|
2021-07-15 19:59:34 +02:00
|
|
|
const label = 'disable-console';
|
2021-03-26 05:26:19 +01:00
|
|
|
return createNormalBundle({
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
browserPlatforms,
|
2022-08-04 20:12:06 +02:00
|
|
|
buildTarget,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
buildType,
|
2021-03-26 05:26:19 +01:00
|
|
|
destFilepath: `${label}.js`,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
entryFilepath: `./app/scripts/${label}.js`,
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
ignoredFiles,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
label,
|
2021-11-26 21:08:23 +01:00
|
|
|
policyOnly,
|
2021-09-16 05:18:28 +02:00
|
|
|
shouldLintFenceFiles,
|
2022-04-04 21:14:32 +02:00
|
|
|
version,
|
2023-01-24 18:00:35 +01:00
|
|
|
applyLavaMoat,
|
2021-02-04 19:15:23 +01:00
|
|
|
});
|
2020-03-09 01:55:02 +01:00
|
|
|
}
|
|
|
|
|
2022-07-27 17:34:02 +02:00
|
|
|
/**
|
|
|
|
* Create a bundle for the "sentry-install" module.
|
|
|
|
*
|
|
|
|
* @param {object} options - The build options.
|
2022-08-04 20:12:06 +02:00
|
|
|
* @param {BUILD_TARGETS} options.buildTarget - The current build target.
|
2022-07-27 17:34:02 +02:00
|
|
|
* @returns {Function} A function that creates the bundle.
|
|
|
|
*/
|
2022-08-04 20:12:06 +02:00
|
|
|
function createSentryBundle({ buildTarget }) {
|
2021-07-15 19:59:34 +02:00
|
|
|
const label = 'sentry-install';
|
2021-03-26 05:26:19 +01:00
|
|
|
return createNormalBundle({
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
browserPlatforms,
|
2022-08-04 20:12:06 +02:00
|
|
|
buildTarget,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
buildType,
|
2021-03-26 05:26:19 +01:00
|
|
|
destFilepath: `${label}.js`,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
entryFilepath: `./app/scripts/${label}.js`,
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
ignoredFiles,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
label,
|
2021-11-26 21:08:23 +01:00
|
|
|
policyOnly,
|
2021-09-16 05:18:28 +02:00
|
|
|
shouldLintFenceFiles,
|
2022-04-04 21:14:32 +02:00
|
|
|
version,
|
2023-01-24 18:00:35 +01:00
|
|
|
applyLavaMoat,
|
2021-02-04 19:15:23 +01:00
|
|
|
});
|
2020-12-14 20:17:13 +01:00
|
|
|
}
|
|
|
|
|
2022-07-27 17:34:02 +02:00
|
|
|
/**
|
|
|
|
* Create bundles for the "contentscript" and "inpage" modules. The inpage
|
|
|
|
* module is created first because it gets embedded in the contentscript
|
|
|
|
* module.
|
|
|
|
*
|
|
|
|
* @param {object} options - The build options.
|
2022-08-04 20:12:06 +02:00
|
|
|
* @param {BUILD_TARGETS} options.buildTarget - The current build target.
|
2022-07-27 17:34:02 +02:00
|
|
|
* @returns {Function} A function that creates the bundles.
|
|
|
|
*/
|
2022-08-04 20:12:06 +02:00
|
|
|
function createContentscriptBundle({ buildTarget }) {
|
2021-02-04 19:15:23 +01:00
|
|
|
const inpage = 'inpage';
|
|
|
|
const contentscript = 'contentscript';
|
2020-03-09 01:55:02 +01:00
|
|
|
return composeSeries(
|
2021-03-26 05:26:19 +01:00
|
|
|
createNormalBundle({
|
2022-08-04 20:12:06 +02:00
|
|
|
buildTarget,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
buildType,
|
|
|
|
browserPlatforms,
|
2021-03-26 05:26:19 +01:00
|
|
|
destFilepath: `${inpage}.js`,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
entryFilepath: `./app/scripts/${inpage}.js`,
|
|
|
|
label: inpage,
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
ignoredFiles,
|
2021-11-26 21:08:23 +01:00
|
|
|
policyOnly,
|
2021-09-16 05:18:28 +02:00
|
|
|
shouldLintFenceFiles,
|
2022-04-04 21:14:32 +02:00
|
|
|
version,
|
2023-01-24 18:00:35 +01:00
|
|
|
applyLavaMoat,
|
2020-03-09 01:55:02 +01:00
|
|
|
}),
|
2021-03-26 05:26:19 +01:00
|
|
|
createNormalBundle({
|
2022-08-04 20:12:06 +02:00
|
|
|
buildTarget,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
buildType,
|
|
|
|
browserPlatforms,
|
2021-03-26 05:26:19 +01:00
|
|
|
destFilepath: `${contentscript}.js`,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
entryFilepath: `./app/scripts/${contentscript}.js`,
|
|
|
|
label: contentscript,
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
ignoredFiles,
|
2021-11-26 21:08:23 +01:00
|
|
|
policyOnly,
|
2021-09-16 05:18:28 +02:00
|
|
|
shouldLintFenceFiles,
|
2022-04-04 21:14:32 +02:00
|
|
|
version,
|
2023-01-24 18:00:35 +01:00
|
|
|
applyLavaMoat,
|
2020-07-14 17:20:41 +02:00
|
|
|
}),
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2020-03-09 01:55:02 +01:00
|
|
|
}
|
2021-03-26 05:26:19 +01:00
|
|
|
}
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2022-07-27 17:34:02 +02:00
|
|
|
/**
|
|
|
|
* Create the bundle for the app initialization module used in manifest v3
|
|
|
|
* builds.
|
|
|
|
*
|
|
|
|
* This must be called after the "background" bundles have been created, so
|
|
|
|
* that the list of all background bundles can be injected into this bundle.
|
|
|
|
*
|
|
|
|
* @param {object} options - Build options.
|
|
|
|
* @param {boolean} options.applyLavaMoat - Whether the build should use
|
|
|
|
* LavaMoat at runtime or not.
|
|
|
|
* @param {string[]} options.browserPlatforms - A list of browser platforms to
|
|
|
|
* build bundles for.
|
2022-08-04 20:12:06 +02:00
|
|
|
* @param {BUILD_TARGETS} options.buildTarget - The current build target.
|
2023-04-25 16:32:51 +02:00
|
|
|
* @param {string} options.buildType - The current build type (e.g. "main",
|
2022-07-27 17:34:02 +02:00
|
|
|
* "flask", etc.).
|
|
|
|
* @param {string[] | null} options.ignoredFiles - A list of files to exclude
|
|
|
|
* from the current build.
|
|
|
|
* @param {string[]} options.jsBundles - A list of JavaScript bundles to be
|
|
|
|
* injected into this bundle.
|
|
|
|
* @param {boolean} options.policyOnly - Whether to stop the build after
|
|
|
|
* generating the LavaMoat policy, skipping any writes to disk other than the
|
|
|
|
* LavaMoat policy itself.
|
|
|
|
* @param {boolean} options.shouldLintFenceFiles - Whether files with code
|
|
|
|
* fences should be linted after fences have been removed.
|
|
|
|
* @param {string} options.version - The current version of the extension.
|
|
|
|
* @returns {Function} A function that creates the set of bundles.
|
|
|
|
*/
|
2022-07-22 01:33:28 +02:00
|
|
|
async function createManifestV3AppInitializationBundle({
|
2022-07-27 17:34:02 +02:00
|
|
|
applyLavaMoat,
|
2022-05-26 06:48:23 +02:00
|
|
|
browserPlatforms,
|
2022-08-04 20:12:06 +02:00
|
|
|
buildTarget,
|
2022-05-26 06:48:23 +02:00
|
|
|
buildType,
|
|
|
|
ignoredFiles,
|
2022-07-27 17:34:02 +02:00
|
|
|
jsBundles,
|
2022-05-26 06:48:23 +02:00
|
|
|
policyOnly,
|
|
|
|
shouldLintFenceFiles,
|
2022-07-22 17:07:39 +02:00
|
|
|
version,
|
2022-05-26 06:48:23 +02:00
|
|
|
}) {
|
|
|
|
const label = 'app-init';
|
|
|
|
// TODO: remove this filter for firefox once MV3 is supported in it
|
|
|
|
const mv3BrowserPlatforms = browserPlatforms.filter(
|
|
|
|
(platform) => platform !== 'firefox',
|
|
|
|
);
|
2022-08-03 17:21:10 +02:00
|
|
|
|
|
|
|
for (const filename of jsBundles) {
|
|
|
|
if (filename.includes(',')) {
|
|
|
|
throw new Error(
|
|
|
|
`Invalid filename "${filename}", not allowed to contain comma.`,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const extraEnvironmentVariables = {
|
|
|
|
APPLY_LAVAMOAT: applyLavaMoat,
|
|
|
|
FILE_NAMES: jsBundles.join(','),
|
|
|
|
};
|
2022-05-26 06:48:23 +02:00
|
|
|
|
|
|
|
await createNormalBundle({
|
|
|
|
browserPlatforms: mv3BrowserPlatforms,
|
2022-08-04 20:12:06 +02:00
|
|
|
buildTarget,
|
2022-05-26 06:48:23 +02:00
|
|
|
buildType,
|
|
|
|
destFilepath: 'app-init.js',
|
|
|
|
entryFilepath: './app/scripts/app-init.js',
|
2022-08-03 17:21:10 +02:00
|
|
|
extraEnvironmentVariables,
|
2022-05-26 06:48:23 +02:00
|
|
|
ignoredFiles,
|
|
|
|
label,
|
|
|
|
policyOnly,
|
|
|
|
shouldLintFenceFiles,
|
2022-07-22 17:07:39 +02:00
|
|
|
version,
|
2023-01-24 18:00:35 +01:00
|
|
|
applyLavaMoat,
|
2022-05-26 06:48:23 +02:00
|
|
|
})();
|
|
|
|
|
2022-07-20 09:40:31 +02:00
|
|
|
// Code below is used to set statsMode to true when testing in MV3
|
|
|
|
// This is used to capture module initialisation stats using lavamoat.
|
2022-08-04 20:12:06 +02:00
|
|
|
if (isTestBuild(buildTarget)) {
|
2022-07-14 01:34:33 +02:00
|
|
|
const content = readFileSync('./dist/chrome/runtime-lavamoat.js', 'utf8');
|
|
|
|
const fileOutput = content.replace('statsMode = false', 'statsMode = true');
|
|
|
|
writeFileSync('./dist/chrome/runtime-lavamoat.js', fileOutput);
|
|
|
|
}
|
2022-06-15 16:57:51 +02:00
|
|
|
|
2022-05-26 06:48:23 +02:00
|
|
|
console.log(`Bundle end: service worker app-init.js`);
|
|
|
|
}
|
|
|
|
|
2022-07-27 17:34:02 +02:00
|
|
|
/**
|
|
|
|
* Return a function that creates a set of factored bundles.
|
|
|
|
*
|
|
|
|
* For each entry point, a series of one or more bundles is created. These are
|
|
|
|
* split up roughly by size, to ensure no single bundle exceeds the maximum
|
|
|
|
* JavaScript file size imposed by Firefox.
|
|
|
|
*
|
|
|
|
* Modules that are common between all entry points are bundled separately, as
|
|
|
|
* a set of one or more "common" bundles.
|
|
|
|
*
|
|
|
|
* @param {object} options - Build options.
|
|
|
|
* @param {boolean} options.applyLavaMoat - Whether the build should use
|
|
|
|
* LavaMoat at runtime or not.
|
|
|
|
* @param {string[]} options.browserPlatforms - A list of browser platforms to
|
|
|
|
* build bundles for.
|
2022-08-04 20:12:06 +02:00
|
|
|
* @param {BUILD_TARGETS} options.buildTarget - The current build target.
|
2023-04-25 16:32:51 +02:00
|
|
|
* @param {string} options.buildType - The current build type (e.g. "main",
|
2022-07-27 17:34:02 +02:00
|
|
|
* "flask", etc.).
|
|
|
|
* @param {string[]} options.entryFiles - A list of entry point file paths,
|
|
|
|
* relative to the repository root directory.
|
|
|
|
* @param {string[] | null} options.ignoredFiles - A list of files to exclude
|
|
|
|
* from the current build.
|
|
|
|
* @param {boolean} options.policyOnly - Whether to stop the build after
|
|
|
|
* generating the LavaMoat policy, skipping any writes to disk other than the
|
|
|
|
* LavaMoat policy itself.
|
|
|
|
* @param {boolean} options.shouldLintFenceFiles - Whether files with code
|
|
|
|
* fences should be linted after fences have been removed.
|
|
|
|
* @param {string} options.version - The current version of the extension.
|
|
|
|
* @returns {Function} A function that creates the set of bundles.
|
|
|
|
*/
|
2021-07-15 19:59:34 +02:00
|
|
|
function createFactoredBuild({
|
2022-04-30 00:56:30 +02:00
|
|
|
applyLavaMoat,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
browserPlatforms,
|
2022-08-04 20:12:06 +02:00
|
|
|
buildTarget,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
buildType,
|
|
|
|
entryFiles,
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
ignoredFiles,
|
2021-11-26 21:08:23 +01:00
|
|
|
policyOnly,
|
2021-09-16 05:18:28 +02:00
|
|
|
shouldLintFenceFiles,
|
2022-03-10 17:01:50 +01:00
|
|
|
version,
|
2021-07-15 19:59:34 +02:00
|
|
|
}) {
|
|
|
|
return async function () {
|
|
|
|
// create bundler setup and apply defaults
|
|
|
|
const buildConfiguration = createBuildConfiguration();
|
2021-07-20 18:23:39 +02:00
|
|
|
buildConfiguration.label = 'primary';
|
2021-07-15 19:59:34 +02:00
|
|
|
const { bundlerOpts, events } = buildConfiguration;
|
|
|
|
|
|
|
|
// devMode options
|
2022-08-04 20:12:06 +02:00
|
|
|
const reloadOnChange = isDevBuild(buildTarget);
|
|
|
|
const minify = !isDevBuild(buildTarget);
|
2021-07-15 19:59:34 +02:00
|
|
|
|
2023-04-25 16:32:51 +02:00
|
|
|
const environment = getEnvironment({ buildTarget });
|
|
|
|
const config = await getConfig(buildType, environment);
|
|
|
|
const { variables, activeBuild } = config;
|
|
|
|
await setEnvironmentVariables({
|
2022-08-04 20:12:06 +02:00
|
|
|
buildTarget,
|
2022-03-10 17:01:50 +01:00
|
|
|
buildType,
|
2023-04-25 16:32:51 +02:00
|
|
|
environment,
|
|
|
|
variables,
|
|
|
|
activeBuild,
|
2022-03-10 17:01:50 +01:00
|
|
|
version,
|
|
|
|
});
|
2023-04-25 16:32:51 +02:00
|
|
|
const features = {
|
|
|
|
active: new Set(activeBuild.features ?? []),
|
|
|
|
all: new Set(Object.keys(config.buildsYml.features)),
|
|
|
|
};
|
2021-07-15 19:59:34 +02:00
|
|
|
setupBundlerDefaults(buildConfiguration, {
|
2022-08-04 20:12:06 +02:00
|
|
|
buildTarget,
|
2023-04-25 16:32:51 +02:00
|
|
|
variables,
|
|
|
|
envVars: buildSafeVariableObject(variables),
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
ignoredFiles,
|
2021-11-26 21:08:23 +01:00
|
|
|
policyOnly,
|
2021-07-15 19:59:34 +02:00
|
|
|
minify,
|
2023-04-25 16:32:51 +02:00
|
|
|
features,
|
Add build-time code exclusion using code fencing (#12060)
This PR adds build-time code exclusion by means of code fencing. For details, please see the README in `./development/build/transforms`. Note that linting of transformed files as a form of validation is added in a follow-up, #12075.
Hopefully exhaustive tests are added to ensure that the transform works according to its specification. Since these tests are Node-only, they required their own Jest config. The recommended way to work with multiple Jest configs is using the `projects` field in the Jest config, however [that feature breaks coverage collection](https://github.com/facebook/jest/issues/9628). That being the case, I had to set up two separate Jest configs. In order to get both test suites to run in parallel, Jest is now invoked via a script, `./test/run-jest.sh`.
By way of example, this build system feature allows us to add fences like this:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
///: BEGIN:ONLY_INCLUDE_IN(beta)
PluginController: this.pluginController,
///: END:ONLY_INCLUDE_IN
});
```
Which at build time are transformed to the following if the build type is not `beta`:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
});
```
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
2021-09-14 19:00:04 +02:00
|
|
|
reloadOnChange,
|
2021-09-16 05:18:28 +02:00
|
|
|
shouldLintFenceFiles,
|
2021-07-15 19:59:34 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
// set bundle entries
|
|
|
|
bundlerOpts.entries = [...entryFiles];
|
|
|
|
|
2021-10-06 00:06:31 +02:00
|
|
|
// setup lavamoat
|
|
|
|
// lavamoat will add lavapack but it will be removed by bify-module-groups
|
|
|
|
// we will re-add it later by installing a lavapack runtime
|
|
|
|
const lavamoatOpts = {
|
2021-11-15 23:23:46 +01:00
|
|
|
policy: path.resolve(
|
|
|
|
__dirname,
|
|
|
|
`../../lavamoat/browserify/${buildType}/policy.json`,
|
|
|
|
),
|
|
|
|
policyName: buildType,
|
2021-10-06 00:06:31 +02:00
|
|
|
policyOverride: path.resolve(
|
|
|
|
__dirname,
|
2022-05-06 00:47:51 +02:00
|
|
|
`../../lavamoat/browserify/policy-override.json`,
|
2021-10-06 00:06:31 +02:00
|
|
|
),
|
|
|
|
writeAutoPolicy: process.env.WRITE_AUTO_POLICY,
|
|
|
|
};
|
|
|
|
Object.assign(bundlerOpts, lavamoatBrowserify.args);
|
|
|
|
bundlerOpts.plugin.push([lavamoatBrowserify, lavamoatOpts]);
|
|
|
|
|
2021-07-15 19:59:34 +02:00
|
|
|
// setup bundle factoring with bify-module-groups plugin
|
2021-10-06 00:06:31 +02:00
|
|
|
// note: this will remove lavapack, but its ok bc we manually readd it later
|
2021-07-15 19:59:34 +02:00
|
|
|
Object.assign(bundlerOpts, bifyModuleGroups.plugin.args);
|
|
|
|
bundlerOpts.plugin = [...bundlerOpts.plugin, [bifyModuleGroups.plugin]];
|
|
|
|
|
|
|
|
// instrument pipeline
|
|
|
|
let sizeGroupMap;
|
|
|
|
events.on('configurePipeline', ({ pipeline }) => {
|
|
|
|
// to be populated by the group-by-size transform
|
|
|
|
sizeGroupMap = new Map();
|
|
|
|
pipeline.get('groups').unshift(
|
|
|
|
// factor modules
|
|
|
|
bifyModuleGroups.groupByFactor({
|
|
|
|
entryFileToLabel(filepath) {
|
|
|
|
return path.parse(filepath).name;
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
// cap files at 2 mb
|
|
|
|
bifyModuleGroups.groupBySize({
|
|
|
|
sizeLimit: 2e6,
|
|
|
|
groupingMap: sizeGroupMap,
|
|
|
|
}),
|
|
|
|
);
|
2021-10-06 00:06:31 +02:00
|
|
|
// converts each module group into a single vinyl file containing its bundle
|
|
|
|
const moduleGroupPackerStream = streamFlatMap((moduleGroup) => {
|
|
|
|
const filename = `${moduleGroup.label}.js`;
|
|
|
|
const childStream = wrapInStream(
|
|
|
|
moduleGroup.stream,
|
|
|
|
// we manually readd lavapack here bc bify-module-groups removes it
|
|
|
|
lavapack({ raw: true, hasExports: true, includePrelude: false }),
|
|
|
|
source(filename),
|
|
|
|
);
|
|
|
|
return childStream;
|
|
|
|
});
|
|
|
|
pipeline.get('vinyl').unshift(moduleGroupPackerStream, buffer());
|
|
|
|
// add lavamoat policy loader file to packer output
|
|
|
|
moduleGroupPackerStream.push(
|
|
|
|
new Vinyl({
|
|
|
|
path: 'policy-load.js',
|
|
|
|
contents: lavapack.makePolicyLoaderStream(lavamoatOpts),
|
2021-07-15 19:59:34 +02:00
|
|
|
}),
|
|
|
|
);
|
|
|
|
// setup bundle destination
|
|
|
|
browserPlatforms.forEach((platform) => {
|
|
|
|
const dest = `./dist/${platform}/`;
|
2021-11-26 21:08:23 +01:00
|
|
|
const destination = policyOnly ? noopWriteStream : gulp.dest(dest);
|
|
|
|
pipeline.get('dest').push(destination);
|
2021-07-15 19:59:34 +02:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
// wait for bundle completion for postprocessing
|
2022-05-26 06:48:23 +02:00
|
|
|
events.on('bundleDone', async () => {
|
2021-11-26 21:08:23 +01:00
|
|
|
// Skip HTML generation if nothing is to be written to disk
|
|
|
|
if (policyOnly) {
|
|
|
|
return;
|
|
|
|
}
|
2021-07-15 19:59:34 +02:00
|
|
|
const commonSet = sizeGroupMap.get('common');
|
|
|
|
// create entry points for each file
|
|
|
|
for (const [groupLabel, groupSet] of sizeGroupMap.entries()) {
|
2021-10-06 00:06:31 +02:00
|
|
|
// skip "common" group, they are added to all other groups
|
2022-01-06 23:56:51 +01:00
|
|
|
if (groupSet === commonSet) {
|
|
|
|
continue;
|
|
|
|
}
|
2021-07-15 19:59:34 +02:00
|
|
|
|
|
|
|
switch (groupLabel) {
|
|
|
|
case 'ui': {
|
2021-10-06 00:06:31 +02:00
|
|
|
renderHtmlFile({
|
|
|
|
htmlName: 'popup',
|
2021-07-15 19:59:34 +02:00
|
|
|
groupSet,
|
|
|
|
commonSet,
|
|
|
|
browserPlatforms,
|
2022-04-30 00:56:30 +02:00
|
|
|
applyLavaMoat,
|
2021-10-06 00:06:31 +02:00
|
|
|
});
|
|
|
|
renderHtmlFile({
|
|
|
|
htmlName: 'notification',
|
|
|
|
groupSet,
|
|
|
|
commonSet,
|
|
|
|
browserPlatforms,
|
2022-04-30 00:56:30 +02:00
|
|
|
applyLavaMoat,
|
2021-10-06 00:06:31 +02:00
|
|
|
});
|
|
|
|
renderHtmlFile({
|
|
|
|
htmlName: 'home',
|
|
|
|
groupSet,
|
|
|
|
commonSet,
|
|
|
|
browserPlatforms,
|
2022-04-30 00:56:30 +02:00
|
|
|
applyLavaMoat,
|
2023-03-02 17:18:46 +01:00
|
|
|
isMMI: buildType === 'mmi',
|
2021-10-06 00:06:31 +02:00
|
|
|
});
|
2021-07-15 19:59:34 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'background': {
|
2021-10-06 00:06:31 +02:00
|
|
|
renderHtmlFile({
|
|
|
|
htmlName: 'background',
|
|
|
|
groupSet,
|
|
|
|
commonSet,
|
|
|
|
browserPlatforms,
|
2022-04-30 00:56:30 +02:00
|
|
|
applyLavaMoat,
|
2021-10-06 00:06:31 +02:00
|
|
|
});
|
2022-05-26 06:48:23 +02:00
|
|
|
if (process.env.ENABLE_MV3) {
|
|
|
|
const jsBundles = [
|
|
|
|
...commonSet.values(),
|
|
|
|
...groupSet.values(),
|
|
|
|
].map((label) => `./${label}.js`);
|
2022-07-22 01:33:28 +02:00
|
|
|
await createManifestV3AppInitializationBundle({
|
2022-07-27 17:34:02 +02:00
|
|
|
applyLavaMoat,
|
2022-05-26 06:48:23 +02:00
|
|
|
browserPlatforms,
|
2022-08-04 20:12:06 +02:00
|
|
|
buildTarget,
|
2022-05-26 06:48:23 +02:00
|
|
|
buildType,
|
|
|
|
ignoredFiles,
|
2022-07-27 17:34:02 +02:00
|
|
|
jsBundles,
|
2022-05-26 06:48:23 +02:00
|
|
|
policyOnly,
|
|
|
|
shouldLintFenceFiles,
|
2022-07-22 17:07:39 +02:00
|
|
|
version,
|
2022-05-26 06:48:23 +02:00
|
|
|
});
|
|
|
|
}
|
2021-07-15 19:59:34 +02:00
|
|
|
break;
|
|
|
|
}
|
2021-08-18 13:26:44 +02:00
|
|
|
case 'content-script': {
|
2021-10-06 00:06:31 +02:00
|
|
|
renderHtmlFile({
|
|
|
|
htmlName: 'trezor-usb-permissions',
|
2021-08-18 13:26:44 +02:00
|
|
|
groupSet,
|
|
|
|
commonSet,
|
|
|
|
browserPlatforms,
|
2022-04-30 00:56:30 +02:00
|
|
|
applyLavaMoat: false,
|
2021-10-06 00:06:31 +02:00
|
|
|
});
|
2021-08-18 13:26:44 +02:00
|
|
|
break;
|
|
|
|
}
|
2021-07-15 19:59:34 +02:00
|
|
|
default: {
|
2021-10-06 00:06:31 +02:00
|
|
|
throw new Error(
|
|
|
|
`build/scripts - unknown groupLabel "${groupLabel}"`,
|
|
|
|
);
|
2021-07-15 19:59:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2022-07-22 01:33:28 +02:00
|
|
|
await createBundle(buildConfiguration, { reloadOnChange });
|
2021-07-15 19:59:34 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-07-27 17:34:02 +02:00
|
|
|
/**
|
|
|
|
* Return a function that creates a single JavaScript bundle.
|
|
|
|
*
|
|
|
|
* @param {object} options - Build options.
|
|
|
|
* @param {string[]} options.browserPlatforms - A list of browser platforms to
|
|
|
|
* build the bundle for.
|
2022-08-04 20:12:06 +02:00
|
|
|
* @param {BUILD_TARGETS} options.buildTarget - The current build target.
|
2023-04-25 16:32:51 +02:00
|
|
|
* @param {string} options.buildType - The current build type (e.g. "main",
|
2022-07-27 17:34:02 +02:00
|
|
|
* "flask", etc.).
|
|
|
|
* @param {string} options.destFilepath - The file path the bundle should be
|
|
|
|
* written to.
|
|
|
|
* @param {string[]} options.entryFilepath - The entry point file path,
|
|
|
|
* relative to the repository root directory.
|
2022-08-03 17:21:10 +02:00
|
|
|
* @param {Record<string, unknown>} options.extraEnvironmentVariables - Extra
|
|
|
|
* environment variables to inject just into this bundle.
|
2022-07-27 17:34:02 +02:00
|
|
|
* @param {string[] | null} options.ignoredFiles - A list of files to exclude
|
|
|
|
* from the current build.
|
|
|
|
* @param {string} options.label - A label used to describe this bundle in any
|
|
|
|
* diagnostic messages.
|
|
|
|
* @param {boolean} options.policyOnly - Whether to stop the build after
|
|
|
|
* generating the LavaMoat policy, skipping any writes to disk other than the
|
|
|
|
* LavaMoat policy itself.
|
|
|
|
* @param {boolean} options.shouldLintFenceFiles - Whether files with code
|
|
|
|
* fences should be linted after fences have been removed.
|
|
|
|
* @param {string} options.version - The current version of the extension.
|
2023-01-24 18:00:35 +01:00
|
|
|
* @param {boolean} options.applyLavaMoat - Whether to apply LavaMoat or not
|
2022-07-27 17:34:02 +02:00
|
|
|
* @returns {Function} A function that creates the bundle.
|
|
|
|
*/
|
2021-03-26 05:26:19 +01:00
|
|
|
function createNormalBundle({
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
browserPlatforms,
|
2022-08-04 20:12:06 +02:00
|
|
|
buildTarget,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
buildType,
|
2021-03-26 05:26:19 +01:00
|
|
|
destFilepath,
|
|
|
|
entryFilepath,
|
2022-08-03 17:21:10 +02:00
|
|
|
extraEnvironmentVariables,
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
ignoredFiles,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
label,
|
2021-11-26 21:08:23 +01:00
|
|
|
policyOnly,
|
2021-09-16 05:18:28 +02:00
|
|
|
shouldLintFenceFiles,
|
2022-04-04 21:14:32 +02:00
|
|
|
version,
|
2023-01-24 18:00:35 +01:00
|
|
|
applyLavaMoat,
|
2021-03-26 05:26:19 +01:00
|
|
|
}) {
|
|
|
|
return async function () {
|
|
|
|
// create bundler setup and apply defaults
|
|
|
|
const buildConfiguration = createBuildConfiguration();
|
2021-07-20 18:23:39 +02:00
|
|
|
buildConfiguration.label = label;
|
2021-03-26 05:26:19 +01:00
|
|
|
const { bundlerOpts, events } = buildConfiguration;
|
|
|
|
|
2021-07-15 19:59:34 +02:00
|
|
|
// devMode options
|
2022-08-04 20:12:06 +02:00
|
|
|
const devMode = isDevBuild(buildTarget);
|
2021-07-15 19:59:34 +02:00
|
|
|
const reloadOnChange = Boolean(devMode);
|
|
|
|
const minify = Boolean(devMode) === false;
|
|
|
|
|
2023-04-25 16:32:51 +02:00
|
|
|
const environment = getEnvironment({ buildTarget });
|
|
|
|
const config = await getConfig(buildType, environment);
|
|
|
|
const { activeBuild, variables } = config;
|
|
|
|
await setEnvironmentVariables({
|
|
|
|
buildTarget,
|
|
|
|
buildType,
|
|
|
|
variables,
|
|
|
|
environment,
|
|
|
|
activeBuild,
|
|
|
|
version,
|
|
|
|
});
|
|
|
|
Object.entries(extraEnvironmentVariables ?? {}).forEach(([key, value]) =>
|
|
|
|
variables.set(key, value),
|
|
|
|
);
|
|
|
|
|
|
|
|
const features = {
|
|
|
|
active: new Set(activeBuild.features ?? []),
|
|
|
|
all: new Set(Object.keys(config.buildsYml.features)),
|
2022-08-03 17:21:10 +02:00
|
|
|
};
|
2021-03-26 05:26:19 +01:00
|
|
|
setupBundlerDefaults(buildConfiguration, {
|
2023-04-25 16:32:51 +02:00
|
|
|
envVars: buildSafeVariableObject(variables),
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
ignoredFiles,
|
2021-11-26 21:08:23 +01:00
|
|
|
policyOnly,
|
2021-07-15 19:59:34 +02:00
|
|
|
minify,
|
2023-04-25 16:32:51 +02:00
|
|
|
features,
|
Add build-time code exclusion using code fencing (#12060)
This PR adds build-time code exclusion by means of code fencing. For details, please see the README in `./development/build/transforms`. Note that linting of transformed files as a form of validation is added in a follow-up, #12075.
Hopefully exhaustive tests are added to ensure that the transform works according to its specification. Since these tests are Node-only, they required their own Jest config. The recommended way to work with multiple Jest configs is using the `projects` field in the Jest config, however [that feature breaks coverage collection](https://github.com/facebook/jest/issues/9628). That being the case, I had to set up two separate Jest configs. In order to get both test suites to run in parallel, Jest is now invoked via a script, `./test/run-jest.sh`.
By way of example, this build system feature allows us to add fences like this:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
///: BEGIN:ONLY_INCLUDE_IN(beta)
PluginController: this.pluginController,
///: END:ONLY_INCLUDE_IN
});
```
Which at build time are transformed to the following if the build type is not `beta`:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
});
```
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
2021-09-14 19:00:04 +02:00
|
|
|
reloadOnChange,
|
2021-09-16 05:18:28 +02:00
|
|
|
shouldLintFenceFiles,
|
2023-01-24 18:00:35 +01:00
|
|
|
applyLavaMoat,
|
2021-03-26 05:26:19 +01:00
|
|
|
});
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2021-03-26 05:26:19 +01:00
|
|
|
// set bundle entries
|
2022-07-22 01:33:06 +02:00
|
|
|
bundlerOpts.entries = [entryFilepath];
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2021-03-26 05:26:19 +01:00
|
|
|
// instrument pipeline
|
|
|
|
events.on('configurePipeline', ({ pipeline }) => {
|
|
|
|
// convert bundle stream to gulp vinyl stream
|
|
|
|
// and ensure file contents are buffered
|
|
|
|
pipeline.get('vinyl').push(source(destFilepath));
|
|
|
|
pipeline.get('vinyl').push(buffer());
|
|
|
|
// setup bundle destination
|
2020-03-09 01:55:02 +01:00
|
|
|
browserPlatforms.forEach((platform) => {
|
2021-03-26 05:26:19 +01:00
|
|
|
const dest = `./dist/${platform}/`;
|
2021-11-26 21:08:23 +01:00
|
|
|
const destination = policyOnly ? noopWriteStream : gulp.dest(dest);
|
|
|
|
pipeline.get('dest').push(destination);
|
2021-02-04 19:15:23 +01:00
|
|
|
});
|
2021-03-26 05:26:19 +01:00
|
|
|
});
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2022-07-22 01:33:28 +02:00
|
|
|
await createBundle(buildConfiguration, { reloadOnChange });
|
2021-03-26 05:26:19 +01:00
|
|
|
};
|
|
|
|
}
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2021-03-26 05:26:19 +01:00
|
|
|
function createBuildConfiguration() {
|
2021-07-20 18:23:39 +02:00
|
|
|
const label = '(unnamed bundle)';
|
2021-03-26 05:26:19 +01:00
|
|
|
const events = new EventEmitter();
|
|
|
|
const bundlerOpts = {
|
|
|
|
entries: [],
|
|
|
|
transform: [],
|
|
|
|
plugin: [],
|
|
|
|
require: [],
|
2021-07-15 19:59:34 +02:00
|
|
|
// non-standard bify options
|
2021-03-26 05:26:19 +01:00
|
|
|
manualExternal: [],
|
2021-07-15 19:59:34 +02:00
|
|
|
manualIgnore: [],
|
2021-03-26 05:26:19 +01:00
|
|
|
};
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
return { bundlerOpts, events, label };
|
2021-03-26 05:26:19 +01:00
|
|
|
}
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2021-07-15 19:59:34 +02:00
|
|
|
function setupBundlerDefaults(
|
|
|
|
buildConfiguration,
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
{
|
2022-08-04 20:12:06 +02:00
|
|
|
buildTarget,
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
envVars,
|
|
|
|
ignoredFiles,
|
2021-11-26 21:08:23 +01:00
|
|
|
policyOnly,
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
minify,
|
2023-04-25 16:32:51 +02:00
|
|
|
features,
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
reloadOnChange,
|
|
|
|
shouldLintFenceFiles,
|
2023-01-24 18:00:35 +01:00
|
|
|
applyLavaMoat,
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
},
|
2021-07-15 19:59:34 +02:00
|
|
|
) {
|
2021-03-26 05:26:19 +01:00
|
|
|
const { bundlerOpts } = buildConfiguration;
|
Add TypeScript to the build system (#13489)
This commit modifies the build system so that TypeScript files can be
transpiled into ES5 just like JavaScript files.
Note that this commit does NOT change the build system to run TypeScript
files through the TypeScript compiler. In other words, no files will be
type-checked at the build stage, as we expect type-checking to be
handled elsewhere (live, via your editor integration with `tsserver`,
and before a PR is merged, via `yarn lint`). Rather, we merely instruct
Babel to strip TypeScript-specific syntax from any files that have it,
as if those files had been written using JavaScript syntax alone.
Why take this approach? Because it prevents the build process from being
negatively impacted with respect to performance (as TypeScript takes a
significant amount of time to run).
It's worth noting the downside of this approach: because we aren't
running files through TypeScript, but relying on Babel's [TypeScript
transform][1] to identify TypeScript syntax, this transform has to keep
up with any syntax changes that TypeScript adds in the future. In fact
there are a few syntactical forms that Babel already does not recognize.
These forms are rare or are deprecated by TypeScript, so I don't
consider them to be a blocker, but it's worth noting just in case it
comes up later. Also, any settings we place in `tsconfig.json` will be
completely ignored by Babel. Again, this isn't a blocker because there
are some analogs for the most important settings reflected in the
options we can pass to the transform. These and other caveats are
detailed in the [documentation for the transform][2].
[1]: https://babeljs.io/docs/en/babel-plugin-transform-typescript
[2]: https://babeljs.io/docs/en/babel-plugin-transform-typescript#caveats
2022-03-29 00:33:40 +02:00
|
|
|
const extensions = ['.js', '.ts', '.tsx'];
|
2021-03-26 05:26:19 +01:00
|
|
|
|
2023-05-03 15:16:43 +02:00
|
|
|
const isSnapsFlask =
|
|
|
|
features.active.has('snaps') && features.active.has('build-flask');
|
|
|
|
|
2021-03-26 05:26:19 +01:00
|
|
|
Object.assign(bundlerOpts, {
|
Add build-time code exclusion using code fencing (#12060)
This PR adds build-time code exclusion by means of code fencing. For details, please see the README in `./development/build/transforms`. Note that linting of transformed files as a form of validation is added in a follow-up, #12075.
Hopefully exhaustive tests are added to ensure that the transform works according to its specification. Since these tests are Node-only, they required their own Jest config. The recommended way to work with multiple Jest configs is using the `projects` field in the Jest config, however [that feature breaks coverage collection](https://github.com/facebook/jest/issues/9628). That being the case, I had to set up two separate Jest configs. In order to get both test suites to run in parallel, Jest is now invoked via a script, `./test/run-jest.sh`.
By way of example, this build system feature allows us to add fences like this:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
///: BEGIN:ONLY_INCLUDE_IN(beta)
PluginController: this.pluginController,
///: END:ONLY_INCLUDE_IN
});
```
Which at build time are transformed to the following if the build type is not `beta`:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
});
```
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
2021-09-14 19:00:04 +02:00
|
|
|
// Source transforms
|
2021-03-26 05:26:19 +01:00
|
|
|
transform: [
|
2022-07-26 20:10:51 +02:00
|
|
|
// // Remove code that should be excluded from builds of the current type
|
2023-04-25 16:32:51 +02:00
|
|
|
createRemoveFencedCodeTransform(features, shouldLintFenceFiles),
|
Add build-time code exclusion using code fencing (#12060)
This PR adds build-time code exclusion by means of code fencing. For details, please see the README in `./development/build/transforms`. Note that linting of transformed files as a form of validation is added in a follow-up, #12075.
Hopefully exhaustive tests are added to ensure that the transform works according to its specification. Since these tests are Node-only, they required their own Jest config. The recommended way to work with multiple Jest configs is using the `projects` field in the Jest config, however [that feature breaks coverage collection](https://github.com/facebook/jest/issues/9628). That being the case, I had to set up two separate Jest configs. In order to get both test suites to run in parallel, Jest is now invoked via a script, `./test/run-jest.sh`.
By way of example, this build system feature allows us to add fences like this:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
///: BEGIN:ONLY_INCLUDE_IN(beta)
PluginController: this.pluginController,
///: END:ONLY_INCLUDE_IN
});
```
Which at build time are transformed to the following if the build type is not `beta`:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
});
```
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
2021-09-14 19:00:04 +02:00
|
|
|
// Transpile top-level code
|
Add TypeScript to the build system (#13489)
This commit modifies the build system so that TypeScript files can be
transpiled into ES5 just like JavaScript files.
Note that this commit does NOT change the build system to run TypeScript
files through the TypeScript compiler. In other words, no files will be
type-checked at the build stage, as we expect type-checking to be
handled elsewhere (live, via your editor integration with `tsserver`,
and before a PR is merged, via `yarn lint`). Rather, we merely instruct
Babel to strip TypeScript-specific syntax from any files that have it,
as if those files had been written using JavaScript syntax alone.
Why take this approach? Because it prevents the build process from being
negatively impacted with respect to performance (as TypeScript takes a
significant amount of time to run).
It's worth noting the downside of this approach: because we aren't
running files through TypeScript, but relying on Babel's [TypeScript
transform][1] to identify TypeScript syntax, this transform has to keep
up with any syntax changes that TypeScript adds in the future. In fact
there are a few syntactical forms that Babel already does not recognize.
These forms are rare or are deprecated by TypeScript, so I don't
consider them to be a blocker, but it's worth noting just in case it
comes up later. Also, any settings we place in `tsconfig.json` will be
completely ignored by Babel. Again, this isn't a blocker because there
are some analogs for the most important settings reflected in the
options we can pass to the transform. These and other caveats are
detailed in the [documentation for the transform][2].
[1]: https://babeljs.io/docs/en/babel-plugin-transform-typescript
[2]: https://babeljs.io/docs/en/babel-plugin-transform-typescript#caveats
2022-03-29 00:33:40 +02:00
|
|
|
[
|
|
|
|
babelify,
|
|
|
|
// Run TypeScript files through Babel
|
2023-05-03 15:16:43 +02:00
|
|
|
{
|
|
|
|
extensions,
|
|
|
|
plugins: isSnapsFlask
|
|
|
|
? [
|
|
|
|
[
|
|
|
|
moduleResolver,
|
|
|
|
{
|
|
|
|
alias: {
|
|
|
|
'@metamask/snaps-controllers':
|
|
|
|
'@metamask/snaps-controllers-flask',
|
|
|
|
'@metamask/snaps-ui': '@metamask/snaps-ui-flask',
|
|
|
|
'@metamask/snaps-utils': '@metamask/snaps-utils-flask',
|
|
|
|
'@metamask/rpc-methods': '@metamask/rpc-methods-flask',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
],
|
|
|
|
]
|
|
|
|
: [],
|
|
|
|
},
|
Add TypeScript to the build system (#13489)
This commit modifies the build system so that TypeScript files can be
transpiled into ES5 just like JavaScript files.
Note that this commit does NOT change the build system to run TypeScript
files through the TypeScript compiler. In other words, no files will be
type-checked at the build stage, as we expect type-checking to be
handled elsewhere (live, via your editor integration with `tsserver`,
and before a PR is merged, via `yarn lint`). Rather, we merely instruct
Babel to strip TypeScript-specific syntax from any files that have it,
as if those files had been written using JavaScript syntax alone.
Why take this approach? Because it prevents the build process from being
negatively impacted with respect to performance (as TypeScript takes a
significant amount of time to run).
It's worth noting the downside of this approach: because we aren't
running files through TypeScript, but relying on Babel's [TypeScript
transform][1] to identify TypeScript syntax, this transform has to keep
up with any syntax changes that TypeScript adds in the future. In fact
there are a few syntactical forms that Babel already does not recognize.
These forms are rare or are deprecated by TypeScript, so I don't
consider them to be a blocker, but it's worth noting just in case it
comes up later. Also, any settings we place in `tsconfig.json` will be
completely ignored by Babel. Again, this isn't a blocker because there
are some analogs for the most important settings reflected in the
options we can pass to the transform. These and other caveats are
detailed in the [documentation for the transform][2].
[1]: https://babeljs.io/docs/en/babel-plugin-transform-typescript
[2]: https://babeljs.io/docs/en/babel-plugin-transform-typescript#caveats
2022-03-29 00:33:40 +02:00
|
|
|
],
|
Add build-time code exclusion using code fencing (#12060)
This PR adds build-time code exclusion by means of code fencing. For details, please see the README in `./development/build/transforms`. Note that linting of transformed files as a form of validation is added in a follow-up, #12075.
Hopefully exhaustive tests are added to ensure that the transform works according to its specification. Since these tests are Node-only, they required their own Jest config. The recommended way to work with multiple Jest configs is using the `projects` field in the Jest config, however [that feature breaks coverage collection](https://github.com/facebook/jest/issues/9628). That being the case, I had to set up two separate Jest configs. In order to get both test suites to run in parallel, Jest is now invoked via a script, `./test/run-jest.sh`.
By way of example, this build system feature allows us to add fences like this:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
///: BEGIN:ONLY_INCLUDE_IN(beta)
PluginController: this.pluginController,
///: END:ONLY_INCLUDE_IN
});
```
Which at build time are transformed to the following if the build type is not `beta`:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
});
```
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
2021-09-14 19:00:04 +02:00
|
|
|
// Inline `fs.readFileSync` files
|
2021-03-26 05:26:19 +01:00
|
|
|
brfs,
|
|
|
|
],
|
Add TypeScript to the build system (#13489)
This commit modifies the build system so that TypeScript files can be
transpiled into ES5 just like JavaScript files.
Note that this commit does NOT change the build system to run TypeScript
files through the TypeScript compiler. In other words, no files will be
type-checked at the build stage, as we expect type-checking to be
handled elsewhere (live, via your editor integration with `tsserver`,
and before a PR is merged, via `yarn lint`). Rather, we merely instruct
Babel to strip TypeScript-specific syntax from any files that have it,
as if those files had been written using JavaScript syntax alone.
Why take this approach? Because it prevents the build process from being
negatively impacted with respect to performance (as TypeScript takes a
significant amount of time to run).
It's worth noting the downside of this approach: because we aren't
running files through TypeScript, but relying on Babel's [TypeScript
transform][1] to identify TypeScript syntax, this transform has to keep
up with any syntax changes that TypeScript adds in the future. In fact
there are a few syntactical forms that Babel already does not recognize.
These forms are rare or are deprecated by TypeScript, so I don't
consider them to be a blocker, but it's worth noting just in case it
comes up later. Also, any settings we place in `tsconfig.json` will be
completely ignored by Babel. Again, this isn't a blocker because there
are some analogs for the most important settings reflected in the
options we can pass to the transform. These and other caveats are
detailed in the [documentation for the transform][2].
[1]: https://babeljs.io/docs/en/babel-plugin-transform-typescript
[2]: https://babeljs.io/docs/en/babel-plugin-transform-typescript#caveats
2022-03-29 00:33:40 +02:00
|
|
|
// Look for TypeScript files when walking the dependency tree
|
|
|
|
extensions,
|
Add build-time code exclusion using code fencing (#12060)
This PR adds build-time code exclusion by means of code fencing. For details, please see the README in `./development/build/transforms`. Note that linting of transformed files as a form of validation is added in a follow-up, #12075.
Hopefully exhaustive tests are added to ensure that the transform works according to its specification. Since these tests are Node-only, they required their own Jest config. The recommended way to work with multiple Jest configs is using the `projects` field in the Jest config, however [that feature breaks coverage collection](https://github.com/facebook/jest/issues/9628). That being the case, I had to set up two separate Jest configs. In order to get both test suites to run in parallel, Jest is now invoked via a script, `./test/run-jest.sh`.
By way of example, this build system feature allows us to add fences like this:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
///: BEGIN:ONLY_INCLUDE_IN(beta)
PluginController: this.pluginController,
///: END:ONLY_INCLUDE_IN
});
```
Which at build time are transformed to the following if the build type is not `beta`:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
});
```
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
2021-09-14 19:00:04 +02:00
|
|
|
// Use entryFilepath for moduleIds, easier to determine origin file
|
2022-08-04 20:12:06 +02:00
|
|
|
fullPaths: isDevBuild(buildTarget) || isTestBuild(buildTarget),
|
Add build-time code exclusion using code fencing (#12060)
This PR adds build-time code exclusion by means of code fencing. For details, please see the README in `./development/build/transforms`. Note that linting of transformed files as a form of validation is added in a follow-up, #12075.
Hopefully exhaustive tests are added to ensure that the transform works according to its specification. Since these tests are Node-only, they required their own Jest config. The recommended way to work with multiple Jest configs is using the `projects` field in the Jest config, however [that feature breaks coverage collection](https://github.com/facebook/jest/issues/9628). That being the case, I had to set up two separate Jest configs. In order to get both test suites to run in parallel, Jest is now invoked via a script, `./test/run-jest.sh`.
By way of example, this build system feature allows us to add fences like this:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
///: BEGIN:ONLY_INCLUDE_IN(beta)
PluginController: this.pluginController,
///: END:ONLY_INCLUDE_IN
});
```
Which at build time are transformed to the following if the build type is not `beta`:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
});
```
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
2021-09-14 19:00:04 +02:00
|
|
|
// For sourcemaps
|
2021-03-26 05:26:19 +01:00
|
|
|
debug: true,
|
|
|
|
});
|
|
|
|
|
2022-08-04 20:12:06 +02:00
|
|
|
// Ensure react-devtools is only included in dev builds
|
Add validation to production build script (#15468)
Validation has been added to the build script when the "prod" target is
selected. We now ensure that all expected environment variables are
set, and that no extra environment variables are present (which might
indicate that the wrong configuration file is being used).
The `prod` target uses a new `.metamaskprodrc` configuration file. Each
required variable can be specified either via environment variable or
via this config file. CI will continue set these via environment
variable, but for local manual builds we can use the config file to
simplify the build process and ensure consistency.
A new "dist" target has been added to preserve the ability to build a
"production-like" build without this validation.
The config validation is invoked early in the script, in the CLI
argument parsing step, so that it would fail more quickly. Otherwise
we'd have to wait a few minutes longer for the validation to run.
This required some refactoring, moving functions to the utility module
and moving the config to a dedicated module.
Additionally, support has been added for all environment variables to
be set via the config file. Previously the values `PUBNUB_PUB_KEY`,
`PUBNUB_SUB_KEY`, `SENTRY_DSN`, and `SWAPS_USE_DEV_APIS` could only be
set via environment variable. Now, all of these variables can be set
either way.
Closes #15003
2022-08-19 20:16:18 +02:00
|
|
|
if (buildTarget !== BUILD_TARGETS.DEV) {
|
2021-07-15 19:59:34 +02:00
|
|
|
bundlerOpts.manualIgnore.push('react-devtools');
|
2021-12-06 16:25:40 +01:00
|
|
|
bundlerOpts.manualIgnore.push('remote-redux-devtools');
|
2021-07-15 19:59:34 +02:00
|
|
|
}
|
|
|
|
|
2023-03-16 11:33:40 +01:00
|
|
|
// This dependency uses WASM which we cannot execute in accordance with our CSP
|
|
|
|
bundlerOpts.manualIgnore.push('@chainsafe/as-sha256');
|
|
|
|
|
Add build-time code exclusion using code fencing (#12060)
This PR adds build-time code exclusion by means of code fencing. For details, please see the README in `./development/build/transforms`. Note that linting of transformed files as a form of validation is added in a follow-up, #12075.
Hopefully exhaustive tests are added to ensure that the transform works according to its specification. Since these tests are Node-only, they required their own Jest config. The recommended way to work with multiple Jest configs is using the `projects` field in the Jest config, however [that feature breaks coverage collection](https://github.com/facebook/jest/issues/9628). That being the case, I had to set up two separate Jest configs. In order to get both test suites to run in parallel, Jest is now invoked via a script, `./test/run-jest.sh`.
By way of example, this build system feature allows us to add fences like this:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
///: BEGIN:ONLY_INCLUDE_IN(beta)
PluginController: this.pluginController,
///: END:ONLY_INCLUDE_IN
});
```
Which at build time are transformed to the following if the build type is not `beta`:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
});
```
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
2021-09-14 19:00:04 +02:00
|
|
|
// Inject environment variables via node-style `process.env`
|
2021-03-26 05:26:19 +01:00
|
|
|
if (envVars) {
|
|
|
|
bundlerOpts.transform.push([envify(envVars), { global: true }]);
|
|
|
|
}
|
2020-03-09 01:55:02 +01:00
|
|
|
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
// Ensure that any files that should be ignored are excluded from the build
|
|
|
|
if (ignoredFiles) {
|
|
|
|
bundlerOpts.manualExclude = ignoredFiles;
|
|
|
|
}
|
|
|
|
|
Add build-time code exclusion using code fencing (#12060)
This PR adds build-time code exclusion by means of code fencing. For details, please see the README in `./development/build/transforms`. Note that linting of transformed files as a form of validation is added in a follow-up, #12075.
Hopefully exhaustive tests are added to ensure that the transform works according to its specification. Since these tests are Node-only, they required their own Jest config. The recommended way to work with multiple Jest configs is using the `projects` field in the Jest config, however [that feature breaks coverage collection](https://github.com/facebook/jest/issues/9628). That being the case, I had to set up two separate Jest configs. In order to get both test suites to run in parallel, Jest is now invoked via a script, `./test/run-jest.sh`.
By way of example, this build system feature allows us to add fences like this:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
///: BEGIN:ONLY_INCLUDE_IN(beta)
PluginController: this.pluginController,
///: END:ONLY_INCLUDE_IN
});
```
Which at build time are transformed to the following if the build type is not `beta`:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
});
```
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
2021-09-14 19:00:04 +02:00
|
|
|
// Setup reload on change
|
2021-03-26 05:26:19 +01:00
|
|
|
if (reloadOnChange) {
|
|
|
|
setupReloadOnChange(buildConfiguration);
|
|
|
|
}
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2021-11-26 21:08:23 +01:00
|
|
|
if (!policyOnly) {
|
|
|
|
if (minify) {
|
|
|
|
setupMinification(buildConfiguration);
|
|
|
|
}
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2021-11-26 21:08:23 +01:00
|
|
|
// Setup source maps
|
2022-08-04 20:12:06 +02:00
|
|
|
setupSourcemaps(buildConfiguration, { buildTarget });
|
2023-01-24 18:00:35 +01:00
|
|
|
// Setup wrapping of code against scuttling (before sourcemaps generation)
|
2023-04-04 17:15:50 +02:00
|
|
|
setupScuttlingWrapping(buildConfiguration, applyLavaMoat, envVars);
|
2021-11-26 21:08:23 +01:00
|
|
|
}
|
2021-03-26 05:26:19 +01:00
|
|
|
}
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2021-03-26 05:26:19 +01:00
|
|
|
function setupReloadOnChange({ bundlerOpts, events }) {
|
Add build-time code exclusion using code fencing (#12060)
This PR adds build-time code exclusion by means of code fencing. For details, please see the README in `./development/build/transforms`. Note that linting of transformed files as a form of validation is added in a follow-up, #12075.
Hopefully exhaustive tests are added to ensure that the transform works according to its specification. Since these tests are Node-only, they required their own Jest config. The recommended way to work with multiple Jest configs is using the `projects` field in the Jest config, however [that feature breaks coverage collection](https://github.com/facebook/jest/issues/9628). That being the case, I had to set up two separate Jest configs. In order to get both test suites to run in parallel, Jest is now invoked via a script, `./test/run-jest.sh`.
By way of example, this build system feature allows us to add fences like this:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
///: BEGIN:ONLY_INCLUDE_IN(beta)
PluginController: this.pluginController,
///: END:ONLY_INCLUDE_IN
});
```
Which at build time are transformed to the following if the build type is not `beta`:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
});
```
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
2021-09-14 19:00:04 +02:00
|
|
|
// Add plugin to options
|
2021-03-26 05:26:19 +01:00
|
|
|
Object.assign(bundlerOpts, {
|
|
|
|
plugin: [...bundlerOpts.plugin, watchify],
|
Add build-time code exclusion using code fencing (#12060)
This PR adds build-time code exclusion by means of code fencing. For details, please see the README in `./development/build/transforms`. Note that linting of transformed files as a form of validation is added in a follow-up, #12075.
Hopefully exhaustive tests are added to ensure that the transform works according to its specification. Since these tests are Node-only, they required their own Jest config. The recommended way to work with multiple Jest configs is using the `projects` field in the Jest config, however [that feature breaks coverage collection](https://github.com/facebook/jest/issues/9628). That being the case, I had to set up two separate Jest configs. In order to get both test suites to run in parallel, Jest is now invoked via a script, `./test/run-jest.sh`.
By way of example, this build system feature allows us to add fences like this:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
///: BEGIN:ONLY_INCLUDE_IN(beta)
PluginController: this.pluginController,
///: END:ONLY_INCLUDE_IN
});
```
Which at build time are transformed to the following if the build type is not `beta`:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
});
```
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
2021-09-14 19:00:04 +02:00
|
|
|
// Required by watchify
|
2021-03-26 05:26:19 +01:00
|
|
|
cache: {},
|
|
|
|
packageCache: {},
|
|
|
|
});
|
Add build-time code exclusion using code fencing (#12060)
This PR adds build-time code exclusion by means of code fencing. For details, please see the README in `./development/build/transforms`. Note that linting of transformed files as a form of validation is added in a follow-up, #12075.
Hopefully exhaustive tests are added to ensure that the transform works according to its specification. Since these tests are Node-only, they required their own Jest config. The recommended way to work with multiple Jest configs is using the `projects` field in the Jest config, however [that feature breaks coverage collection](https://github.com/facebook/jest/issues/9628). That being the case, I had to set up two separate Jest configs. In order to get both test suites to run in parallel, Jest is now invoked via a script, `./test/run-jest.sh`.
By way of example, this build system feature allows us to add fences like this:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
///: BEGIN:ONLY_INCLUDE_IN(beta)
PluginController: this.pluginController,
///: END:ONLY_INCLUDE_IN
});
```
Which at build time are transformed to the following if the build type is not `beta`:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
});
```
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
2021-09-14 19:00:04 +02:00
|
|
|
// Instrument pipeline
|
2021-03-26 05:26:19 +01:00
|
|
|
events.on('configurePipeline', ({ bundleStream }) => {
|
Add build-time code exclusion using code fencing (#12060)
This PR adds build-time code exclusion by means of code fencing. For details, please see the README in `./development/build/transforms`. Note that linting of transformed files as a form of validation is added in a follow-up, #12075.
Hopefully exhaustive tests are added to ensure that the transform works according to its specification. Since these tests are Node-only, they required their own Jest config. The recommended way to work with multiple Jest configs is using the `projects` field in the Jest config, however [that feature breaks coverage collection](https://github.com/facebook/jest/issues/9628). That being the case, I had to set up two separate Jest configs. In order to get both test suites to run in parallel, Jest is now invoked via a script, `./test/run-jest.sh`.
By way of example, this build system feature allows us to add fences like this:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
///: BEGIN:ONLY_INCLUDE_IN(beta)
PluginController: this.pluginController,
///: END:ONLY_INCLUDE_IN
});
```
Which at build time are transformed to the following if the build type is not `beta`:
```javascript
this.store.updateStructure({
...,
GasFeeController: this.gasFeeController,
TokenListController: this.tokenListController,
});
```
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
2021-09-14 19:00:04 +02:00
|
|
|
// Handle build error to avoid breaking build process
|
2021-03-26 05:26:19 +01:00
|
|
|
// (eg on syntax error)
|
|
|
|
bundleStream.on('error', (err) => {
|
|
|
|
gracefulError(err);
|
2021-02-04 19:15:23 +01:00
|
|
|
});
|
2021-03-26 05:26:19 +01:00
|
|
|
});
|
|
|
|
}
|
2020-07-29 18:14:08 +02:00
|
|
|
|
2021-03-26 05:26:19 +01:00
|
|
|
function setupMinification(buildConfiguration) {
|
2021-07-15 19:59:34 +02:00
|
|
|
const minifyOpts = {
|
|
|
|
mangle: {
|
|
|
|
reserved: ['MetamaskInpageProvider'],
|
|
|
|
},
|
|
|
|
};
|
2021-03-26 05:26:19 +01:00
|
|
|
const { events } = buildConfiguration;
|
|
|
|
events.on('configurePipeline', ({ pipeline }) => {
|
|
|
|
pipeline.get('minify').push(
|
2021-07-15 19:59:34 +02:00
|
|
|
// this is the "gulp-terser-js" wrapper around the latest version of terser
|
|
|
|
through.obj(
|
|
|
|
callbackify(async (file, _enc) => {
|
|
|
|
const input = {
|
|
|
|
[file.sourceMap.file]: file.contents.toString(),
|
|
|
|
};
|
|
|
|
const opts = {
|
|
|
|
sourceMap: {
|
|
|
|
filename: file.sourceMap.file,
|
|
|
|
content: file.sourceMap,
|
|
|
|
},
|
|
|
|
...minifyOpts,
|
|
|
|
};
|
|
|
|
const res = await terser.minify(input, opts);
|
|
|
|
file.contents = Buffer.from(res.code);
|
|
|
|
applySourceMap(file, res.map);
|
|
|
|
return file;
|
|
|
|
}),
|
|
|
|
),
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2021-03-26 05:26:19 +01:00
|
|
|
});
|
|
|
|
}
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2023-04-04 17:15:50 +02:00
|
|
|
function setupScuttlingWrapping(buildConfiguration, applyLavaMoat, envVars) {
|
|
|
|
const scuttlingConfig =
|
|
|
|
envVars.ENABLE_MV3 === 'true'
|
|
|
|
? mv3ScuttlingConfig
|
|
|
|
: standardScuttlingConfig;
|
2023-01-24 18:00:35 +01:00
|
|
|
const { events } = buildConfiguration;
|
|
|
|
events.on('configurePipeline', ({ pipeline }) => {
|
|
|
|
pipeline.get('scuttle').push(
|
|
|
|
through.obj(
|
|
|
|
callbackify(async (file, _enc) => {
|
|
|
|
const configForFile = scuttlingConfig[file.relative];
|
|
|
|
if (applyLavaMoat && configForFile) {
|
|
|
|
const wrapped = wrapAgainstScuttling(
|
|
|
|
file.contents.toString(),
|
|
|
|
configForFile,
|
|
|
|
);
|
|
|
|
file.contents = Buffer.from(wrapped, 'utf8');
|
|
|
|
}
|
|
|
|
return file;
|
|
|
|
}),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-08-04 20:12:06 +02:00
|
|
|
function setupSourcemaps(buildConfiguration, { buildTarget }) {
|
2021-03-26 05:26:19 +01:00
|
|
|
const { events } = buildConfiguration;
|
|
|
|
events.on('configurePipeline', ({ pipeline }) => {
|
|
|
|
pipeline.get('sourcemaps:init').push(sourcemaps.init({ loadMaps: true }));
|
|
|
|
pipeline
|
|
|
|
.get('sourcemaps:write')
|
|
|
|
// Use inline source maps for development due to Chrome DevTools bug
|
|
|
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=931675
|
|
|
|
.push(
|
2022-08-04 20:12:06 +02:00
|
|
|
isDevBuild(buildTarget)
|
2021-03-26 05:26:19 +01:00
|
|
|
? sourcemaps.write()
|
|
|
|
: sourcemaps.write('../sourcemaps', { addComment: false }),
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2022-07-22 01:33:28 +02:00
|
|
|
async function createBundle(buildConfiguration, { reloadOnChange }) {
|
2021-07-20 18:23:39 +02:00
|
|
|
const { label, bundlerOpts, events } = buildConfiguration;
|
2021-03-26 05:26:19 +01:00
|
|
|
const bundler = browserify(bundlerOpts);
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
|
2021-07-15 19:59:34 +02:00
|
|
|
// manually apply non-standard options
|
2021-03-26 05:26:19 +01:00
|
|
|
bundler.external(bundlerOpts.manualExternal);
|
2021-07-15 19:59:34 +02:00
|
|
|
bundler.ignore(bundlerOpts.manualIgnore);
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
if (Array.isArray(bundlerOpts.manualExclude)) {
|
|
|
|
bundler.exclude(bundlerOpts.manualExclude);
|
|
|
|
}
|
|
|
|
|
2021-03-26 05:26:19 +01:00
|
|
|
// output build logs to terminal
|
|
|
|
bundler.on('log', log);
|
Exclude files from builds by build type (#12521)
This PR enables the exclusion of JavaScript and JSON source by `buildType`, and enables the running of `eslint` under LavaMoat. 80-90% of the changes in this PR are `.patch` files and LavaMoat policy additions.
The file exclusion is designed to work in conjunction with our code fencing. If you forget to fence an import statement of an excluded file, the application will now error on boot. **This PR commits us to a particular naming convention for files intended only for certain builds.** Continue reading for details.
### Code Fencing and ESLint
When a file is modified by the code fencing transform, we run ESLint on it to ensure that we fail early for syntax-related issues. This PR adds the first code fences that will be actually be removed in production builds. As a consequence, this was also the first time we attempted to run ESLint under LavaMoat. Making that work required a lot of manual labor because of ESLint's use of dynamic imports, but the manual changes necessary were ultimately quite minor.
### File Exclusion
For all builds, any file in `app/`, `shared/` or `ui/` in a sub-directory matching `**/${otherBuildType}/**` (where `otherBuildType` is any build type except `main`) will be added to the list of excluded files, regardless of its file extension. For example, if we want to add one or more pages to the UI settings in Flask, we'd create the folder `ui/pages/settings/flask`, add any necessary files or sub-folders there, and fence the import statements for anything in that folder. If we wanted the same thing for Beta, we would name the directory `ui/pages/settings/beta`.
As it happens, we already organize some of our source files in this way, namely the logo JSON for Beta and Flask builds. See `ui/helpers/utils/build-types.js` to see how this works in practice.
Because the list of ignored filed is only passed to `browserify.exclude()`, any files not bundled by `browserify` will be ignored. For our purposes, this is mostly relevant for `.scss`. Since we don't have anything like code fencing for SCSS, we'll have to consider how to handle our styles separately.
2021-11-02 04:20:31 +01:00
|
|
|
|
2021-03-26 05:26:19 +01:00
|
|
|
// forward update event (used by watchify)
|
|
|
|
bundler.on('update', () => performBundle());
|
2021-07-15 19:59:34 +02:00
|
|
|
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
console.log(`Bundle start: "${label}"`);
|
2021-03-26 05:26:19 +01:00
|
|
|
await performBundle();
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
console.log(`Bundle end: "${label}"`);
|
2021-03-26 05:26:19 +01:00
|
|
|
|
|
|
|
async function performBundle() {
|
|
|
|
// this pipeline is created for every bundle
|
|
|
|
// the labels are all the steps you can hook into
|
|
|
|
const pipeline = labeledStreamSplicer([
|
2021-07-15 19:59:34 +02:00
|
|
|
'groups',
|
|
|
|
[],
|
2021-03-26 05:26:19 +01:00
|
|
|
'vinyl',
|
|
|
|
[],
|
2023-01-24 18:00:35 +01:00
|
|
|
'scuttle',
|
|
|
|
[],
|
2021-03-26 05:26:19 +01:00
|
|
|
'sourcemaps:init',
|
|
|
|
[],
|
|
|
|
'minify',
|
|
|
|
[],
|
|
|
|
'sourcemaps:write',
|
|
|
|
[],
|
|
|
|
'dest',
|
|
|
|
[],
|
|
|
|
]);
|
|
|
|
const bundleStream = bundler.bundle();
|
2022-02-17 21:47:50 +01:00
|
|
|
if (!reloadOnChange) {
|
|
|
|
bundleStream.on('error', (error) => {
|
|
|
|
console.error('Bundling failed! See details below.');
|
2022-08-06 09:33:35 +02:00
|
|
|
logError(error);
|
2022-02-17 21:47:50 +01:00
|
|
|
process.exit(1);
|
|
|
|
});
|
2023-04-26 08:33:36 +02:00
|
|
|
pipeline.on('error', (error) => {
|
|
|
|
console.error('Pipeline failed! See details below.');
|
|
|
|
logError(error);
|
|
|
|
process.exit(1);
|
|
|
|
});
|
2022-02-17 21:47:50 +01:00
|
|
|
}
|
2021-03-26 05:26:19 +01:00
|
|
|
// trigger build pipeline instrumentations
|
|
|
|
events.emit('configurePipeline', { pipeline, bundleStream });
|
|
|
|
// start bundle, send into pipeline
|
|
|
|
bundleStream.pipe(pipeline);
|
|
|
|
// nothing will consume pipeline, so let it flow
|
|
|
|
pipeline.resume();
|
2021-07-15 19:59:34 +02:00
|
|
|
|
2021-03-26 05:26:19 +01:00
|
|
|
await endOfStream(pipeline);
|
2021-07-15 19:59:34 +02:00
|
|
|
|
|
|
|
// call the completion event to handle any post-processing
|
|
|
|
events.emit('bundleDone');
|
2020-03-09 01:55:02 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-27 17:34:02 +02:00
|
|
|
/**
|
2023-04-25 16:32:51 +02:00
|
|
|
* Sets environment variables to inject in the current build.
|
2022-07-27 17:34:02 +02:00
|
|
|
*
|
|
|
|
* @param {object} options - Build options.
|
2022-08-04 20:12:06 +02:00
|
|
|
* @param {BUILD_TARGETS} options.buildTarget - The current build target.
|
2023-04-25 16:32:51 +02:00
|
|
|
* @param {string} options.buildType - The current build type (e.g. "main",
|
2022-07-27 17:34:02 +02:00
|
|
|
* "flask", etc.).
|
|
|
|
* @param {string} options.version - The current version of the extension.
|
2023-04-25 16:32:51 +02:00
|
|
|
* @param options.activeBuild
|
|
|
|
* @param options.variables
|
|
|
|
* @param options.environment
|
2022-07-27 17:34:02 +02:00
|
|
|
*/
|
2023-04-25 16:32:51 +02:00
|
|
|
async function setEnvironmentVariables({
|
|
|
|
buildTarget,
|
|
|
|
buildType,
|
|
|
|
activeBuild,
|
|
|
|
environment,
|
|
|
|
variables,
|
|
|
|
version,
|
|
|
|
}) {
|
2022-08-04 20:12:06 +02:00
|
|
|
const devMode = isDevBuild(buildTarget);
|
|
|
|
const testing = isTestBuild(buildTarget);
|
2022-09-20 19:15:14 +02:00
|
|
|
const iconNames = await generateIconNames();
|
2023-04-25 16:32:51 +02:00
|
|
|
|
|
|
|
variables.set({
|
2022-09-20 19:15:14 +02:00
|
|
|
ICON_NAMES: iconNames,
|
2022-08-04 20:12:06 +02:00
|
|
|
IN_TEST: testing,
|
|
|
|
INFURA_PROJECT_ID: getInfuraProjectId({
|
|
|
|
buildType,
|
2023-04-25 16:32:51 +02:00
|
|
|
activeBuild,
|
|
|
|
variables,
|
2022-08-04 20:12:06 +02:00
|
|
|
environment,
|
|
|
|
testing,
|
|
|
|
}),
|
2023-04-25 16:32:51 +02:00
|
|
|
METAMASK_DEBUG: devMode || variables.getMaybe('METAMASK_DEBUG') === true,
|
2021-03-26 05:26:19 +01:00
|
|
|
METAMASK_ENVIRONMENT: environment,
|
2021-08-11 19:13:02 +02:00
|
|
|
METAMASK_VERSION: version,
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
METAMASK_BUILD_TYPE: buildType,
|
2021-10-25 17:34:02 +02:00
|
|
|
NODE_ENV: devMode ? ENVIRONMENT.DEVELOPMENT : ENVIRONMENT.PRODUCTION,
|
2023-04-25 16:32:51 +02:00
|
|
|
PHISHING_WARNING_PAGE_URL: getPhishingWarningPageUrl({
|
|
|
|
variables,
|
|
|
|
testing,
|
|
|
|
}),
|
|
|
|
SEGMENT_WRITE_KEY: getSegmentWriteKey({
|
|
|
|
buildType,
|
|
|
|
activeBuild,
|
|
|
|
variables,
|
|
|
|
environment,
|
|
|
|
}),
|
|
|
|
});
|
2021-03-26 05:26:19 +01:00
|
|
|
}
|
|
|
|
|
2021-10-06 00:06:31 +02:00
|
|
|
function renderHtmlFile({
|
|
|
|
htmlName,
|
|
|
|
groupSet,
|
|
|
|
commonSet,
|
|
|
|
browserPlatforms,
|
2022-04-30 00:56:30 +02:00
|
|
|
applyLavaMoat,
|
2023-03-02 17:18:46 +01:00
|
|
|
isMMI,
|
2021-10-06 00:06:31 +02:00
|
|
|
}) {
|
2022-04-30 00:56:30 +02:00
|
|
|
if (applyLavaMoat === undefined) {
|
2021-10-06 00:06:31 +02:00
|
|
|
throw new Error(
|
2022-04-30 00:56:30 +02:00
|
|
|
'build/scripts/renderHtmlFile - must specify "applyLavaMoat" option',
|
2021-10-06 00:06:31 +02:00
|
|
|
);
|
|
|
|
}
|
2021-07-15 19:59:34 +02:00
|
|
|
const htmlFilePath = `./app/${htmlName}.html`;
|
|
|
|
const htmlTemplate = readFileSync(htmlFilePath, 'utf8');
|
|
|
|
const jsBundles = [...commonSet.values(), ...groupSet.values()].map(
|
|
|
|
(label) => `./${label}.js`,
|
|
|
|
);
|
2023-03-02 17:18:46 +01:00
|
|
|
const htmlOutput = Sqrl.render(htmlTemplate, {
|
|
|
|
jsBundles,
|
|
|
|
applyLavaMoat,
|
|
|
|
isMMI,
|
|
|
|
});
|
2021-07-15 19:59:34 +02:00
|
|
|
browserPlatforms.forEach((platform) => {
|
|
|
|
const dest = `./dist/${platform}/${htmlName}.html`;
|
|
|
|
// we dont have a way of creating async events atm
|
|
|
|
writeFileSync(dest, htmlOutput);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-04-25 16:32:51 +02:00
|
|
|
/**
|
|
|
|
* Builds a javascript object that throws an error when trying to access a property that wasn't defined properly
|
|
|
|
*
|
|
|
|
* @param {Variables} variables
|
|
|
|
* @returns {{[key: string]: unknown }} Variable definitions
|
|
|
|
*/
|
|
|
|
function buildSafeVariableObject(variables) {
|
|
|
|
return new Proxy(
|
|
|
|
{},
|
|
|
|
{
|
|
|
|
has(_, key) {
|
|
|
|
return key !== '_'; // loose-envify uses "_" for settings
|
|
|
|
},
|
|
|
|
get(_, key) {
|
|
|
|
if (key === '_') {
|
|
|
|
return undefined; // loose-envify uses "_" for settings
|
|
|
|
}
|
|
|
|
return variables.get(key);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-11-20 16:26:40 +01:00
|
|
|
function beep() {
|
2021-02-04 19:15:23 +01:00
|
|
|
process.stdout.write('\x07');
|
2020-11-20 16:26:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function gracefulError(err) {
|
2021-02-04 19:15:23 +01:00
|
|
|
console.warn(err);
|
|
|
|
beep();
|
2020-11-20 16:26:40 +01:00
|
|
|
}
|