@redhat-cloud-services/frontend-components-config 4.5.8 → 4.5.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,6 +7,7 @@
7
7
  - [Removed features with webpack 5](#removed-features-with-webpack-5)
8
8
  - [useProxy](#useproxy)
9
9
  - [Attributes](#attributes)
10
+ - [useChromeTemplate](#useChromeTemplate)
10
11
  - [localChrome](#localchrome)
11
12
  - [registry](#registry)
12
13
  - [Custom routes](#custom-routes)
@@ -54,6 +55,7 @@ const { config: webpackConfig, plugins } = config({
54
55
  |---------|----|-----------|
55
56
  |[useProxy](#useproxy)|`boolean`|Enables webpack proxy.|
56
57
  |[proxyURL](#proxyURL)|`string`|URL to proxy Akamai environment requests to.|
58
+ |[useChromeTemplate](#useChromeTemplate)|`boolean`|Load chrome HTMl template.|
57
59
  |[localChrome](#localChrome)|`string`|Path to your local chrome build folder.|
58
60
  |[keycloakUri](#keycloakUri)|`string`|Uri to inject into proxied chrome assets.|
59
61
  |[registry](#registry)|`(({ app, server, compiler, standaloneConfig }) => void)[]`|Express middleware to register.|
@@ -64,6 +66,24 @@ const { config: webpackConfig, plugins } = config({
64
66
  |[useCloud](#use-cloud)|`boolean`|Toggle to use old fallback to cloud.redhat.com paths instead of console.redhat.com.|
65
67
  |[target](#target)|`string`|Override `env` and `useCloud` to use a custom URI.|
66
68
 
69
+
70
+ #### useChromeTemplate
71
+
72
+ **This option will become the default. App-specific templates are deprecated**
73
+
74
+ To load chrome HTML template instead of using the APP-specific template add `useChromeTemplate` flag to your config.
75
+
76
+ ```js
77
+ const config = require('@redhat-cloud-services/frontend-components-config');
78
+
79
+ const { config: webpackConfig, plugins } = config({
80
+ rootFolder: resolve(__dirname, '../'),
81
+ useProxy: true,
82
+ useChromeTemplate: true
83
+ ...
84
+ });
85
+ ```
86
+
67
87
  #### localChrome
68
88
 
69
89
  You can also easily run you application with a local build of Chrome by adding `localChrome: <absolute_path_to_chrome_build_folder>`.
@@ -320,6 +340,9 @@ Use binary in your `package.json` scripts section:
320
340
  }
321
341
  ```
322
342
 
343
+ ## Patch etc hosts
344
+ This is a required step for first time setup. It will allow your localhost to map to [env].foo.redhat.com. This is required to run only once on your machine. **Your OS may require running the script as sudo**!
345
+
323
346
  ## Static
324
347
 
325
348
  A script that will run webpack build and serve webpack output through `http-serve` server. **This is not supposed to replace webpack dev server!**
package/bin/fec.js CHANGED
@@ -1,8 +1,23 @@
1
1
  #!/usr/bin/env node
2
-
2
+ const { execSync } = require('child_process');
3
3
  const static = require('@redhat-cloud-services/frontend-components-config-utilities/serve-federated');
4
4
  const yargs = require('yargs');
5
5
 
6
+ function patchHosts() {
7
+ const command = `
8
+ for host in prod.foo.redhat.com stage.foo.redhat.com qa.foo.redhat.com ci.foo.redhat.com
9
+ do
10
+ grep -q $host /etc/hosts 2>/dev/null
11
+ if [ $? -ne 0 ]
12
+ then
13
+ echo "Adding $host to /etc/hosts"
14
+ echo "127.0.0.1 $host" >>/etc/hosts
15
+ fi
16
+ done
17
+ `
18
+ execSync(command)
19
+ }
20
+
6
21
  const cwd = process.cwd();
7
22
 
8
23
  const argv = yargs
@@ -19,11 +34,13 @@ const argv = yargs
19
34
  default: 8003
20
35
  });
21
36
  })
37
+ .command('patch-etc-hosts', 'You may have to run this as \'sudo\'. Setup your etc/hosts allow development hosts in your browser')
22
38
  .help()
23
39
  .argv;
24
40
 
25
41
  const scripts = {
26
- static
42
+ static,
43
+ 'patch-etc-hosts': patchHosts
27
44
  };
28
45
 
29
46
  const args = [ argv, cwd ];
package/index.js CHANGED
@@ -2,81 +2,79 @@ const config = require('./src/config');
2
2
  const plugins = require('./src/plugins');
3
3
  const { sync } = require('glob');
4
4
 
5
- const gitRevisionPlugin = new(require('git-revision-webpack-plugin'))({
6
- branch: true
5
+ const gitRevisionPlugin = new (require('git-revision-webpack-plugin'))({
6
+ branch: true,
7
7
  });
8
- const betaBranches = [ 'master', 'qa-beta', 'ci-beta', 'prod-beta', 'main', 'devel', 'stage-beta' ];
9
- const akamaiBranches = [ 'prod-beta', 'prod-stable' ];
8
+ const betaBranches = ['master', 'qa-beta', 'ci-beta', 'prod-beta', 'main', 'devel', 'stage-beta'];
9
+ const akamaiBranches = ['prod-beta', 'prod-stable'];
10
10
 
11
11
  const getAppEntry = (rootFolder, isProd) => {
12
- // Use entry-dev if it exists
13
- if (!isProd) {
14
- const entries = sync('src/entry-dev.{js,jsx,ts,tsx}', { cwd: rootFolder });
15
- if (entries.length > 1) {
16
- console.warn('Found multiple entry-dev files. Using', entries[0]);
17
- }
18
-
19
- if (entries.length > 0) {
20
- return `${rootFolder}/${entries[0]}`;
21
- }
12
+ // Use entry-dev if it exists
13
+ if (!isProd) {
14
+ const entries = sync('src/entry-dev.{js,jsx,ts,tsx}', { cwd: rootFolder });
15
+ if (entries.length > 1) {
16
+ console.warn('Found multiple entry-dev files. Using', entries[0]);
22
17
  }
23
18
 
24
- const entries = sync('src/entry.{js,jsx,ts,tsx}', { cwd: rootFolder });
25
- if (entries.length > 1) {
26
- console.warn('Found multiple entry files. Using', entries[0]);
19
+ if (entries.length > 0) {
20
+ return `${rootFolder}/${entries[0]}`;
27
21
  }
22
+ }
28
23
 
29
- return `${rootFolder}/${entries[0]}`;
24
+ const entries = sync('src/entry.{js,jsx,ts,tsx}', { cwd: rootFolder });
25
+ if (entries.length > 1) {
26
+ console.warn('Found multiple entry files. Using', entries[0]);
27
+ }
28
+
29
+ return `${rootFolder}/${entries[0]}`;
30
30
  };
31
31
 
32
32
  module.exports = (configurations) => {
33
- configurations.isProd = configurations.isProd || process.env.NODE_ENV === 'production';
34
- const isProd = configurations.isProd;
35
- const { insights } = require(`${configurations.rootFolder}/package.json`);
36
- const gitBranch = process.env.TRAVIS_BRANCH || process.env.BRANCH || gitRevisionPlugin.branch();
37
- const appDeployment = configurations.deployment || ((isProd && betaBranches.includes(gitBranch)) ?
38
- 'beta/apps' :
39
- 'apps');
40
-
41
- const publicPath = `/${appDeployment}/${insights.appname}/`;
42
- const appEntry = configurations.appEntry || getAppEntry(configurations.rootFolder, isProd);
43
- const generateSourceMaps = !akamaiBranches.includes(gitBranch);
33
+ configurations.isProd = configurations.isProd || process.env.NODE_ENV === 'production';
34
+ const isProd = configurations.isProd;
35
+ const { insights } = require(`${configurations.rootFolder}/package.json`);
36
+ const gitBranch = process.env.TRAVIS_BRANCH || process.env.BRANCH || gitRevisionPlugin.branch();
37
+ const appDeployment = configurations.deployment || (isProd && betaBranches.includes(gitBranch) ? 'beta/apps' : 'apps');
44
38
 
45
- if (configurations.debug) {
46
- /* eslint-disable no-console */
47
- console.log('~~~Using variables~~~');
48
- console.log(`Root folder: ${configurations.rootFolder}`);
49
- console.log(`Current branch: ${gitBranch}`);
50
- !generateSourceMaps && console.log(`Source map generation for "${gitBranch}" deployment has been disabled.`);
51
- console.log(`Beta branches: ${betaBranches}`);
52
- console.log(`Using deployments: ${appDeployment}`);
53
- console.log(`Public path: ${publicPath}`);
54
- console.log(`App entry: ${appEntry}`);
55
- console.log(`Use proxy: ${configurations.useProxy ? 'true' : 'false'}`);
56
- if (!(configurations.useProxy || configurations.standalone)) {
57
- console.warn('Insights-proxy is deprecated in favor of "useProxy" or "standalone".');
58
- console.warn('See https://github.com/RedHatInsights/frontend-components/blob/master/packages/config/README.md');
59
- }
39
+ const publicPath = `/${appDeployment}/${insights.appname}/`;
40
+ const appEntry = configurations.appEntry || getAppEntry(configurations.rootFolder, isProd);
41
+ const generateSourceMaps = !akamaiBranches.includes(gitBranch);
60
42
 
61
- console.log('~~~~~~~~~~~~~~~~~~~~~');
62
- /* eslint-enable no-console */
43
+ if (configurations.debug) {
44
+ /* eslint-disable no-console */
45
+ console.log('~~~Using variables~~~');
46
+ console.log(`Root folder: ${configurations.rootFolder}`);
47
+ console.log(`Current branch: ${gitBranch}`);
48
+ !generateSourceMaps && console.log(`Source map generation for "${gitBranch}" deployment has been disabled.`);
49
+ console.log(`Beta branches: ${betaBranches}`);
50
+ console.log(`Using deployments: ${appDeployment}`);
51
+ console.log(`Public path: ${publicPath}`);
52
+ console.log(`App entry: ${appEntry}`);
53
+ console.log(`Use proxy: ${configurations.useProxy ? 'true' : 'false'}`);
54
+ if (!(configurations.useProxy || configurations.standalone)) {
55
+ console.warn('Insights-proxy is deprecated in favor of "useProxy" or "standalone".');
56
+ console.warn('See https://github.com/RedHatInsights/frontend-components/blob/master/packages/config/README.md');
63
57
  }
64
58
 
65
- return {
66
- config: config({
67
- ...configurations,
68
- appDeployment,
69
- insights,
70
- publicPath,
71
- appEntry,
72
- appName: insights.appname
73
- }),
74
- plugins: plugins({
75
- ...configurations,
76
- generateSourceMaps,
77
- appDeployment,
78
- insights,
79
- publicPath
80
- })
81
- };
59
+ console.log('~~~~~~~~~~~~~~~~~~~~~');
60
+ /* eslint-enable no-console */
61
+ }
62
+
63
+ return {
64
+ config: config({
65
+ ...configurations,
66
+ appDeployment,
67
+ insights,
68
+ publicPath,
69
+ appEntry,
70
+ appName: insights.appname,
71
+ }),
72
+ plugins: plugins({
73
+ ...configurations,
74
+ generateSourceMaps,
75
+ appDeployment,
76
+ insights,
77
+ publicPath,
78
+ }),
79
+ };
82
80
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redhat-cloud-services/frontend-components-config",
3
- "version": "4.5.8",
3
+ "version": "4.5.12",
4
4
  "description": "Config plugins and settings for RedHat Cloud Services project.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "homepage": "https://github.com/RedHatInsights/frontend-components/tree/master/packages/config#readme",
22
22
  "dependencies": {
23
- "@redhat-cloud-services/frontend-components-config-utilities": "^1.5.8",
23
+ "@redhat-cloud-services/frontend-components-config-utilities": "^1.5.9",
24
24
  "assert": "^2.0.0",
25
25
  "babel-loader": "^8.2.2",
26
26
  "browserify-zlib": "^0.2.0",
@@ -48,7 +48,7 @@
48
48
  "util": "^0.12.4",
49
49
  "webpack": "^5.55.1",
50
50
  "webpack-cli": "^4.8.0",
51
- "webpack-dev-server": "^4.3.0",
51
+ "webpack-dev-server": "4.3.1",
52
52
  "write-file-webpack-plugin": "^4.5.1",
53
53
  "yargs": "^17.2.1"
54
54
  }
package/src/config.js CHANGED
@@ -1,179 +1,203 @@
1
1
  /* eslint-disable camelcase */
2
2
  const path = require('path');
3
+ const fs = require('fs');
3
4
  const proxy = require('@redhat-cloud-services/frontend-components-config-utilities/proxy');
4
5
  const MiniCssExtractPlugin = require('mini-css-extract-plugin');
5
6
  const searchIgnoredStyles = require('@redhat-cloud-services/frontend-components-config-utilities/search-ignored-styles');
6
7
 
7
8
  module.exports = ({
8
- port,
9
- publicPath,
10
- appEntry,
11
- rootFolder,
12
- https,
13
- mode,
14
- appName,
15
- useFileHash = true,
16
- betaEnv,
17
- env,
18
- sassPrefix,
19
- skipChrome2 = false,
20
- useProxy,
21
- proxyURL,
22
- localChrome,
23
- keycloakUri,
24
- customProxy,
25
- routes,
26
- routesPath,
27
- isProd,
28
- standalone = false,
29
- reposDir,
30
- appUrl = [],
31
- proxyVerbose,
32
- useCloud,
33
- target,
34
- registry,
35
- client = {},
36
- bundlePfModules = false
9
+ port,
10
+ publicPath,
11
+ appEntry,
12
+ rootFolder,
13
+ https,
14
+ mode,
15
+ appName,
16
+ useFileHash = true,
17
+ betaEnv,
18
+ env,
19
+ sassPrefix,
20
+ skipChrome2 = false,
21
+ useProxy,
22
+ proxyURL,
23
+ localChrome,
24
+ keycloakUri,
25
+ customProxy,
26
+ routes,
27
+ routesPath,
28
+ isProd,
29
+ standalone = false,
30
+ reposDir,
31
+ appUrl = [],
32
+ proxyVerbose,
33
+ useCloud,
34
+ target,
35
+ registry,
36
+ client = {},
37
+ bundlePfModules = false,
38
+ useChromeTemplate = false,
37
39
  } = {}) => {
38
- const filenameMask = `js/[name]${useFileHash ? `.${Date.now()}.[fullhash]` : ''}.js`;
39
- if (betaEnv) {
40
- env = `${betaEnv}-beta`;
41
- console.warn('betaEnv is deprecated in favor of env');
40
+ const filenameMask = `js/[name]${useFileHash ? `.${Date.now()}.[fullhash]` : ''}.js`;
41
+ if (betaEnv) {
42
+ env = `${betaEnv}-beta`;
43
+ console.warn('betaEnv is deprecated in favor of env');
44
+ }
45
+
46
+ const outputPath = `${rootFolder || ''}/dist`;
47
+
48
+ const copyTemplate = (chromePath) => {
49
+ const template = fs.readFileSync(`${chromePath}/index.html`, { encoding: 'utf-8' });
50
+ if (!fs.existsSync(outputPath)) {
51
+ fs.mkdirSync(outputPath);
42
52
  }
43
53
 
44
- const devServerPort = typeof port === 'number' ? port : useProxy || standalone ? 1337 : 8002;
45
- return {
46
- mode: mode || (isProd ? 'production' : 'development'),
47
- devtool: false,
48
- entry: {
49
- App: appEntry
54
+ fs.writeFileSync(`${outputPath}/index.html`, template);
55
+ };
56
+
57
+ const devServerPort = typeof port === 'number' ? port : useProxy || standalone ? 1337 : 8002;
58
+ return {
59
+ mode: mode || (isProd ? 'production' : 'development'),
60
+ devtool: false,
61
+ entry: {
62
+ App: appEntry,
63
+ },
64
+ output: {
65
+ filename: filenameMask,
66
+ path: outputPath,
67
+ publicPath,
68
+ chunkFilename: filenameMask,
69
+ },
70
+ module: {
71
+ rules: [
72
+ {
73
+ test: new RegExp(appEntry),
74
+ loader: path.resolve(__dirname, './chrome-render-loader.js'),
75
+ options: {
76
+ appName,
77
+ skipChrome2,
78
+ },
50
79
  },
51
- output: {
52
- filename: filenameMask,
53
- path: `${rootFolder || ''}/dist`,
54
- publicPath,
55
- chunkFilename: filenameMask
80
+ {
81
+ test: /src\/.*\.js$/,
82
+ exclude: /(node_modules|bower_components)/i,
83
+ use: ['babel-loader'],
56
84
  },
57
- module: {
58
- rules: [{
59
- test: new RegExp(appEntry),
60
- loader: path.resolve(__dirname, './chrome-render-loader.js'),
61
- options: {
62
- appName,
63
- skipChrome2
64
- }
65
- }, {
66
- test: /src\/.*\.js$/,
67
- exclude: /(node_modules|bower_components)/i,
68
- use: [ 'babel-loader' ]
69
- }, {
70
- test: /src\/.*\.tsx?$/,
71
- loader: 'ts-loader',
72
- exclude: /(node_modules)/i
73
- }, {
74
- test: /\.s?[ac]ss$/,
75
- use: [
76
- MiniCssExtractPlugin.loader,
77
- 'css-loader',
78
- {
79
- /**
80
- * Second sass loader used for scoping the css with class name.
81
- * Has to be included as second in order to re-scope already compiled sass files.
82
- * Second loader is required to avoid scoping mixins, includes and other sass partials. We want to only scope the CSS output.
83
- */
84
- loader: 'sass-loader',
85
- options: {
86
- additionalData: function(content, loaderContext) {
87
- const { resourcePath, rootContext } = loaderContext;
88
- const relativePath = path.relative(rootContext, resourcePath);
89
- /**
90
- * Add app class context for local style files.
91
- * Context class is equal to app name and that class ass added to root element via the chrome-render-loader.
92
- */
93
- if (relativePath.match(/^src/)) {
94
- return `${sassPrefix || `.${appName}`}{\n${content}\n}`;
95
- }
85
+ {
86
+ test: /src\/.*\.tsx?$/,
87
+ loader: 'ts-loader',
88
+ exclude: /(node_modules)/i,
89
+ },
90
+ {
91
+ test: /\.s?[ac]ss$/,
92
+ use: [
93
+ MiniCssExtractPlugin.loader,
94
+ 'css-loader',
95
+ {
96
+ /**
97
+ * Second sass loader used for scoping the css with class name.
98
+ * Has to be included as second in order to re-scope already compiled sass files.
99
+ * Second loader is required to avoid scoping mixins, includes and other sass partials. We want to only scope the CSS output.
100
+ */
101
+ loader: 'sass-loader',
102
+ options: {
103
+ additionalData: function (content, loaderContext) {
104
+ const { resourcePath, rootContext } = loaderContext;
105
+ const relativePath = path.relative(rootContext, resourcePath);
106
+ /**
107
+ * Add app class context for local style files.
108
+ * Context class is equal to app name and that class ass added to root element via the chrome-render-loader.
109
+ */
110
+ if (relativePath.match(/^src/)) {
111
+ return `${sassPrefix || `.${appName}`}{\n${content}\n}`;
112
+ }
96
113
 
97
- return content;
98
- }
99
- }
100
- },
101
- 'sass-loader'
102
- ]
103
- }, {
104
- test: /\.(woff(2)?|ttf|jpg|png|eot|gif|svg)(\?v=\d+\.\d+\.\d+)?$/,
105
- type: 'asset/resource',
106
- generator: {
107
- filename: 'fonts/[name][ext]'
108
- }
114
+ return content;
115
+ },
116
+ },
109
117
  },
110
- {
111
- test: /\.mjs$/,
112
- include: /node_modules/,
113
- type: 'javascript/auto'
114
- }]
118
+ 'sass-loader',
119
+ ],
115
120
  },
116
- resolve: {
117
- extensions: [ '.ts', '.tsx', '.mjs', '.js', '.scss' ],
118
- alias: {
119
- ...(bundlePfModules ? {} : searchIgnoredStyles(rootFolder))
120
- },
121
- fallback: {
122
- path: require.resolve('path-browserify'),
123
- stream: require.resolve('stream-browserify'),
124
- zlib: require.resolve('browserify-zlib'),
125
- assert: require.resolve('assert/'),
126
- buffer: require.resolve('buffer/'),
127
- url: require.resolve('url/'),
128
- util: require.resolve('util/'),
129
- process: 'process/browser.js'
130
- }
121
+ {
122
+ test: /\.(woff(2)?|ttf|jpg|png|eot|gif|svg)(\?v=\d+\.\d+\.\d+)?$/,
123
+ type: 'asset/resource',
124
+ generator: {
125
+ filename: 'fonts/[name][ext]',
126
+ },
131
127
  },
132
- devServer: {
133
- static: {
134
- directory: `${rootFolder || ''}/dist`
135
- },
136
- port: devServerPort,
137
- https: https || Boolean(useProxy),
138
- host: '0.0.0.0', // This shares on local network. Needed for docker.host.internal
139
- hot: false, // Use livereload instead of HMR which is spotty with federated modules
140
- allowedHosts: 'all',
141
- // https://github.com/bripkens/connect-history-api-fallback
142
- historyApiFallback: {
143
- // We should really implement the same logic as cloud-services-config
144
- // and only redirect (/beta)?/bundle/app-name to /index.html
145
- //
146
- // Until then let known api calls fall through instead of returning /index.html
147
- // for easier `fetch` debugging
148
- rewrites: [
149
- { from: /^\/api/, to: '/404.html' },
150
- { from: /^(\/beta)?\/config/, to: '/404.html' }
151
- ],
152
- verbose: Boolean(proxyVerbose)
153
- },
154
- devMiddleware: {
155
- writeToDisk: true
156
- },
157
- client,
158
- ...proxy({
159
- useCloud,
160
- env,
161
- localChrome,
162
- keycloakUri,
163
- customProxy,
164
- routes,
165
- routesPath,
166
- useProxy,
167
- proxyURL,
168
- standalone,
169
- port: devServerPort,
170
- reposDir,
171
- appUrl,
172
- publicPath,
173
- proxyVerbose,
174
- target,
175
- registry
176
- })
177
- }
178
- };
128
+ {
129
+ test: /\.mjs$/,
130
+ include: /node_modules/,
131
+ type: 'javascript/auto',
132
+ },
133
+ ],
134
+ },
135
+ resolve: {
136
+ extensions: ['.ts', '.tsx', '.mjs', '.js', '.scss'],
137
+ alias: {
138
+ ...(bundlePfModules ? {} : searchIgnoredStyles(rootFolder)),
139
+ },
140
+ fallback: {
141
+ path: require.resolve('path-browserify'),
142
+ stream: require.resolve('stream-browserify'),
143
+ zlib: require.resolve('browserify-zlib'),
144
+ assert: require.resolve('assert/'),
145
+ buffer: require.resolve('buffer/'),
146
+ url: require.resolve('url/'),
147
+ util: require.resolve('util/'),
148
+ process: 'process/browser.js',
149
+ },
150
+ },
151
+ devServer: {
152
+ static: {
153
+ directory: `${rootFolder || ''}/dist`,
154
+ },
155
+ port: devServerPort,
156
+ https: https || Boolean(useProxy),
157
+ host: '0.0.0.0', // This shares on local network. Needed for docker.host.internal
158
+ hot: false, // Use livereload instead of HMR which is spotty with federated modules
159
+ allowedHosts: 'all',
160
+ // https://github.com/bripkens/connect-history-api-fallback
161
+ historyApiFallback: {
162
+ // We should really implement the same logic as cloud-services-config
163
+ // and only redirect (/beta)?/bundle/app-name to /index.html
164
+ //
165
+ // Until then let known api calls fall through instead of returning /index.html
166
+ // for easier `fetch` debugging
167
+ rewrites: [
168
+ { from: /^\/api/, to: '/404.html' },
169
+ { from: /^(\/beta)?\/config/, to: '/404.html' },
170
+ ],
171
+ verbose: Boolean(proxyVerbose),
172
+ },
173
+ devMiddleware: {
174
+ writeToDisk: true,
175
+ },
176
+ client,
177
+ ...proxy({
178
+ useCloud,
179
+ env,
180
+ localChrome,
181
+ keycloakUri,
182
+ customProxy,
183
+ routes,
184
+ routesPath,
185
+ useProxy,
186
+ proxyURL,
187
+ standalone,
188
+ port: devServerPort,
189
+ reposDir,
190
+ appUrl,
191
+ publicPath,
192
+ proxyVerbose,
193
+ target,
194
+ registry,
195
+ onBeforeSetupMiddleware: ({ chromePath }) => {
196
+ if (useChromeTemplate && chromePath) {
197
+ copyTemplate(chromePath);
198
+ }
199
+ },
200
+ }),
201
+ },
202
+ };
179
203
  };
@@ -9,135 +9,112 @@ import config from './config';
9
9
  const configBuilder = (c) => config({ rootFolder: '', ...c });
10
10
 
11
11
  describe('should create dummy config with no options', () => {
12
- const {
13
- mode,
14
- optimization,
15
- entry,
16
- output,
17
- devServer
18
- } = config({ rootFolder: '' });
19
-
20
- const { mode: prodMode } = configBuilder({ mode: 'production' });
21
- test('mode', () => {
22
- expect(mode).toBe('development');
12
+ const { mode, optimization, entry, output, devServer } = config({ rootFolder: '' });
13
+
14
+ const { mode: prodMode } = configBuilder({ mode: 'production' });
15
+ test('mode', () => {
16
+ expect(mode).toBe('development');
17
+ });
18
+
19
+ test('prodMode', () => {
20
+ expect(prodMode).toBe('production');
21
+ });
22
+
23
+ test('optimization', () => {
24
+ expect(optimization).toEqual(undefined);
25
+ });
26
+
27
+ test('entry', () => {
28
+ expect(entry).toEqual({ App: undefined });
29
+ });
30
+
31
+ test('output', () => {
32
+ expect(output).toEqual({
33
+ filename: expect.stringMatching(/js\/\[name\]\.\d+\.\[fullhash\]\.js/),
34
+ path: '/dist',
35
+ publicPath: undefined,
36
+ chunkFilename: expect.stringMatching(/js\/\[name\]\.\d+\.\[fullhash\]\.js/),
23
37
  });
24
-
25
- test('prodMode', () => {
26
- expect(prodMode).toBe('production');
27
- });
28
-
29
- test('optimization', () => {
30
- expect(optimization).toEqual(undefined);
31
- });
32
-
33
- test('entry', () => {
34
- expect(entry).toEqual({ App: undefined });
35
- });
36
-
37
- test('output', () => {
38
- expect(output).toEqual({
39
- filename: expect.stringMatching(/js\/\[name\]\.\d+\.\[fullhash\]\.js/),
40
- path: '/dist',
41
- publicPath: undefined,
42
- chunkFilename: expect.stringMatching(/js\/\[name\]\.\d+\.\[fullhash\]\.js/)
43
- });
44
- });
45
-
46
- test('devServer', () => {
47
- expect(devServer).toEqual({
48
- onBeforeSetupMiddleware: expect.any(Function),
49
- onListening: expect.any(Function),
50
- static: {
51
- directory: '/dist'
52
- },
53
- https: false,
54
- host: '0.0.0.0',
55
- port: 8002,
56
- hot: false,
57
- allowedHosts: 'all',
58
- historyApiFallback: {
59
- rewrites: [
60
- { from: /^\/api/, to: '/404.html' },
61
- { from: /^(\/beta)?\/config/, to: '/404.html' }
62
- ],
63
- verbose: false
64
- },
65
- client: {},
66
- devMiddleware: {
67
- writeToDisk: true
68
- }
69
- });
38
+ });
39
+
40
+ test('devServer', () => {
41
+ expect(devServer).toEqual({
42
+ onBeforeSetupMiddleware: expect.any(Function),
43
+ onListening: expect.any(Function),
44
+ static: {
45
+ directory: '/dist',
46
+ },
47
+ https: false,
48
+ host: '0.0.0.0',
49
+ port: 8002,
50
+ hot: false,
51
+ allowedHosts: 'all',
52
+ historyApiFallback: {
53
+ rewrites: [
54
+ { from: /^\/api/, to: '/404.html' },
55
+ { from: /^(\/beta)?\/config/, to: '/404.html' },
56
+ ],
57
+ verbose: false,
58
+ },
59
+ client: {},
60
+ devMiddleware: {
61
+ writeToDisk: true,
62
+ },
70
63
  });
64
+ });
71
65
  });
72
66
 
73
67
  describe('rootFolder', () => {
74
- const {
75
- output,
76
- devServer
77
- } = configBuilder({ rootFolder: '/some' });
78
- test('output', () => {
79
- expect(output.path).toBe('/some/dist');
80
- });
81
-
82
- test('devServer', () => {
83
- expect(devServer.static.directory).toBe('/some/dist');
84
- });
68
+ const { output, devServer } = configBuilder({ rootFolder: '/some' });
69
+ test('output', () => {
70
+ expect(output.path).toBe('/some/dist');
71
+ });
72
+
73
+ test('devServer', () => {
74
+ expect(devServer.static.directory).toBe('/some/dist');
75
+ });
85
76
  });
86
77
 
87
78
  describe('module rules', () => {
88
- test('length', () => {
89
- const {
90
- module
91
- } = configBuilder({ appEntry: 'testEntry', appName: 'someName' });
92
- expect(module.rules.length).toBe(6);
93
- });
94
-
95
- test('first to be chrome-render-loader', () => {
96
- const {
97
- module
98
- } = configBuilder({ appEntry: 'testEntry', appName: 'someName' });
99
- expect((new RegExp(module.rules[0].rules)).test('testEntry')).toBe(true);
100
- expect(module.rules[0].options.skipChrome2).toBe(false);
101
- });
102
-
103
- test('first to be chrome-render-loader', () => {
104
- const {
105
- module
106
- } = configBuilder({ appEntry: 'testEntry', appName: 'someName', skipChrome2: true });
107
- expect(module.rules[0].options.skipChrome2).toBe(true);
108
- });
79
+ test('length', () => {
80
+ const { module } = configBuilder({ appEntry: 'testEntry', appName: 'someName' });
81
+ expect(module.rules.length).toBe(6);
82
+ });
83
+
84
+ test('first to be chrome-render-loader', () => {
85
+ const { module } = configBuilder({ appEntry: 'testEntry', appName: 'someName' });
86
+ expect(new RegExp(module.rules[0].rules).test('testEntry')).toBe(true);
87
+ expect(module.rules[0].options.skipChrome2).toBe(false);
88
+ });
89
+
90
+ test('first to be chrome-render-loader', () => {
91
+ const { module } = configBuilder({ appEntry: 'testEntry', appName: 'someName', skipChrome2: true });
92
+ expect(module.rules[0].options.skipChrome2).toBe(true);
93
+ });
109
94
  });
110
95
 
111
96
  test('appEntry correctly set', () => {
112
- const {
113
- entry
114
- } = configBuilder({ appEntry: 'testEntry' });
115
- expect(entry).toEqual({ App: 'testEntry' });
97
+ const { entry } = configBuilder({ appEntry: 'testEntry' });
98
+ expect(entry).toEqual({ App: 'testEntry' });
116
99
  });
117
100
 
118
101
  describe('publicPath', () => {
119
- const {
120
- output
121
- } = configBuilder({ publicPath: 'test-value' });
102
+ const { output } = configBuilder({ publicPath: 'test-value' });
122
103
 
123
- test('output', () => {
124
- expect(output.publicPath).toBe('test-value');
125
- });
104
+ test('output', () => {
105
+ expect(output.publicPath).toBe('test-value');
106
+ });
126
107
  });
127
108
 
128
109
  describe('port', () => {
129
- const {
130
- devServer
131
- } = configBuilder({ port: 1000 });
110
+ const { devServer } = configBuilder({ port: 1000 });
132
111
 
133
- test('devServer', () => {
134
- expect(devServer.port).toBe(1000);
135
- });
112
+ test('devServer', () => {
113
+ expect(devServer.port).toBe(1000);
114
+ });
136
115
  });
137
116
 
138
117
  test('https', () => {
139
- const {
140
- devServer
141
- } = configBuilder({ https: true });
142
- expect(devServer.https).toBe(true);
118
+ const { devServer } = configBuilder({ https: true });
119
+ expect(devServer.https).toBe(true);
143
120
  });
package/src/plugins.js CHANGED
@@ -8,51 +8,56 @@ const ChunkMapperPlugin = require('@redhat-cloud-services/frontend-components-co
8
8
  const jsVarName = require('@redhat-cloud-services/frontend-components-config-utilities/jsVarName');
9
9
 
10
10
  module.exports = ({
11
- rootFolder,
12
- appDeployment,
13
- htmlPlugin,
14
- replacePlugin,
15
- insights,
16
- modules,
17
- generateSourceMaps,
18
- plugins
11
+ rootFolder,
12
+ appDeployment,
13
+ htmlPlugin,
14
+ replacePlugin,
15
+ insights,
16
+ modules,
17
+ generateSourceMaps,
18
+ plugins,
19
+ useChromeTemplate = false,
19
20
  } = {}) => [
20
- ...(generateSourceMaps
21
- ? [
22
- new SourceMapDevToolPlugin({
23
- test: 'js',
24
- exclude: /(node_modules|bower_components)/i,
25
- filename: 'sourcemaps/[name].[contenthash].js.map'
26
- })
27
- ]
28
- : []),
29
- new MiniCssExtractPlugin({
30
- chunkFilename: 'css/[name].[contenthash].css',
31
- filename: 'css/[name].[contenthash].css',
32
- ignoreOrder: true
33
- }),
34
- new CleanWebpackPlugin({ cleanStaleWebpackAssets: false }),
35
- new HtmlWebpackPlugin({
36
- title: 'My App',
37
- filename: 'index.html',
38
- template: `${rootFolder || ''}/src/index.html`,
39
- inject: false,
40
- ...htmlPlugin || {}
41
- }),
42
- new HtmlReplaceWebpackPlugin([
43
- {
21
+ ...(generateSourceMaps
22
+ ? [
23
+ new SourceMapDevToolPlugin({
24
+ test: 'js',
25
+ exclude: /(node_modules|bower_components)/i,
26
+ filename: 'sourcemaps/[name].[contenthash].js.map',
27
+ }),
28
+ ]
29
+ : []),
30
+ new MiniCssExtractPlugin({
31
+ chunkFilename: 'css/[name].[contenthash].css',
32
+ filename: 'css/[name].[contenthash].css',
33
+ ignoreOrder: true,
34
+ }),
35
+ new CleanWebpackPlugin({
36
+ cleanStaleWebpackAssets: false,
37
+ cleanOnceBeforeBuildPatterns: useChromeTemplate ? ['**/*', '!index.html'] : ['**/*'],
38
+ }),
39
+ ...(useChromeTemplate
40
+ ? []
41
+ : [
42
+ new HtmlWebpackPlugin({
43
+ title: 'My App',
44
+ filename: 'index.html',
45
+ template: `${rootFolder || ''}/src/index.html`,
46
+ inject: false,
47
+ ...(htmlPlugin || {}),
48
+ }),
49
+ new HtmlReplaceWebpackPlugin([
50
+ {
44
51
  pattern: '@@env',
45
- replacement: appDeployment || ''
46
- },
47
- ...replacePlugin || []
48
- ]),
49
- new ProvidePlugin({
50
- process: 'process/browser.js',
51
- Buffer: [ 'buffer', 'Buffer' ]
52
- }),
53
- new ChunkMapperPlugin({ modules: [
54
- ...insights ? [ jsVarName(insights.appname) ] : [],
55
- ...modules || []
56
- ] }),
57
- ...(plugins || [])
52
+ replacement: appDeployment || '',
53
+ },
54
+ ...(replacePlugin || []),
55
+ ]),
56
+ ]),
57
+ new ProvidePlugin({
58
+ process: 'process/browser.js',
59
+ Buffer: ['buffer', 'Buffer'],
60
+ }),
61
+ new ChunkMapperPlugin({ modules: [...(insights ? [jsVarName(insights.appname)] : []), ...(modules || [])] }),
62
+ ...(plugins || []),
58
63
  ];
@@ -4,55 +4,51 @@ const HTML_WEBPACK = 2;
4
4
  const REPLACE = 3;
5
5
 
6
6
  describe('plugins generations, no option', () => {
7
- const enabledPlugins = plugins();
7
+ const enabledPlugins = plugins();
8
8
 
9
- it('should generate plugins', () => {
10
- expect(enabledPlugins.length).toBe(6);
11
- });
9
+ it('should generate plugins', () => {
10
+ expect(enabledPlugins.length).toBe(6);
11
+ });
12
12
 
13
- it('should generate plugins with sourceMaps', () => {
14
- const enabledPlugins = plugins({ generateSourceMaps: true });
15
- expect(enabledPlugins.length).toBe(7);
16
- });
13
+ it('should generate plugins with sourceMaps', () => {
14
+ const enabledPlugins = plugins({ generateSourceMaps: true });
15
+ expect(enabledPlugins.length).toBe(7);
16
+ });
17
17
 
18
- it('should generate correct template path for HtmlWebpackPlugin', () => {
19
- expect(enabledPlugins[HTML_WEBPACK].userOptions.template).toBe('/src/index.html');
20
- });
18
+ it('should generate correct template path for HtmlWebpackPlugin', () => {
19
+ expect(enabledPlugins[HTML_WEBPACK].userOptions.template).toBe('/src/index.html');
20
+ });
21
21
  });
22
22
 
23
23
  describe('rootFolder', () => {
24
- const enabledPlugins = plugins({ rootFolder: '/test/folder' });
24
+ const enabledPlugins = plugins({ rootFolder: '/test/folder' });
25
25
 
26
- it('should generate correct template path for HtmlWebpackPlugin', () => {
27
- expect(enabledPlugins[HTML_WEBPACK].userOptions.template).toBe('/test/folder/src/index.html');
28
- });
26
+ it('should generate correct template path for HtmlWebpackPlugin', () => {
27
+ expect(enabledPlugins[HTML_WEBPACK].userOptions.template).toBe('/test/folder/src/index.html');
28
+ });
29
29
  });
30
30
 
31
31
  describe('appDeployment', () => {
32
- const enabledPlugins = plugins({ appDeployment: '/test/folder' });
33
-
34
- it('should replace correct string', () => {
35
- enabledPlugins[REPLACE].replace(
36
- { html: 'string @@env' },
37
- (_, { html }) => expect(html).toBe('string /test/folder')
38
- );
39
- });
32
+ const enabledPlugins = plugins({ appDeployment: '/test/folder' });
33
+
34
+ it('should replace correct string', () => {
35
+ enabledPlugins[REPLACE].replace({ html: 'string @@env' }, (_, { html }) => expect(html).toBe('string /test/folder'));
36
+ });
40
37
  });
41
38
 
42
39
  it('htmlPlugin should update', () => {
43
- const enabledPlugins = plugins({ htmlPlugin: { title: 'myTitle' } });
44
- expect(enabledPlugins[HTML_WEBPACK].userOptions.title).toBe('myTitle');
40
+ const enabledPlugins = plugins({ htmlPlugin: { title: 'myTitle' } });
41
+ expect(enabledPlugins[HTML_WEBPACK].userOptions.title).toBe('myTitle');
45
42
  });
46
43
 
47
44
  it('replacePlugin should update', () => {
48
- const enabledPlugins = plugins({ replacePlugin: [
49
- {
50
- pattern: '@@another',
51
- replacement: 'test-string'
52
- }
53
- ] });
54
- enabledPlugins[REPLACE].replace(
55
- { html: '@@another string @@env' },
56
- (_, { html }) => expect(html).toBe('test-string string ')
57
- );
45
+ const enabledPlugins = plugins({
46
+ replacePlugin: [
47
+ {
48
+ pattern: '@@another',
49
+ replacement: 'test-string',
50
+ },
51
+ ],
52
+ });
53
+ enabledPlugins[REPLACE].replace({ html: '@@another string @@env' }, (_, { html }) => expect(html).toBe('test-string string '));
58
54
  });