@commercetools-frontend/mc-scripts 21.3.3 → 21.5.0

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/build/bin/cli.js CHANGED
@@ -69,6 +69,10 @@ const applicationDirectory = fs.realpathSync(process.cwd());
69
69
 
70
70
  (async () => {
71
71
  try {
72
+ // Load dotenv files into the process environment.
73
+ // This is essentially what `dotenv-cli` does, but it's now built into this CLI.
74
+ loadDotEnvFiles(flags);
75
+
72
76
  switch (command) {
73
77
  case 'build':
74
78
  {
@@ -76,11 +80,21 @@ const applicationDirectory = fs.realpathSync(process.cwd());
76
80
  process.env.BABEL_ENV = 'production';
77
81
  process.env.NODE_ENV = 'production';
78
82
  const shouldAlsoCompile = !flags['build-only'];
83
+ const shouldUseExperimentalBundler = process.env.ENABLE_EXPERIMENTAL_VITE_BUNDLER === 'true';
84
+
85
+ if (shouldUseExperimentalBundler) {
86
+ console.log('Experimental Vite bundler enabled! 🚀');
87
+ console.warn('NOTE that the "cdnURL" value is not supported at the moment when using Vite.');
88
+ console.log('');
89
+ }
90
+
79
91
  proxyCommand(command, {
80
- noExit: shouldAlsoCompile
92
+ noExit: shouldAlsoCompile,
93
+ fileName: shouldUseExperimentalBundler ? 'build-vite' : 'build'
81
94
  });
82
95
 
83
96
  if (shouldAlsoCompile) {
97
+ console.log('');
84
98
  proxyCommand('compile-html');
85
99
  }
86
100
 
@@ -112,7 +126,16 @@ const applicationDirectory = fs.realpathSync(process.cwd());
112
126
  // Do this as the first thing so that any code reading it knows the right env.
113
127
  process.env.BABEL_ENV = 'development';
114
128
  process.env.NODE_ENV = 'development';
115
- proxyCommand(command);
129
+ const shouldUseExperimentalBundler = process.env.ENABLE_EXPERIMENTAL_VITE_BUNDLER === 'true';
130
+
131
+ if (shouldUseExperimentalBundler) {
132
+ console.log('Experimental Vite bundler enabled');
133
+ console.log('');
134
+ }
135
+
136
+ proxyCommand(command, {
137
+ fileName: shouldUseExperimentalBundler ? 'start-vite' : 'start'
138
+ });
116
139
  break;
117
140
  }
118
141
 
@@ -131,7 +154,10 @@ const applicationDirectory = fs.realpathSync(process.cwd());
131
154
 
132
155
  const commandArgs = getArgsForCommand(['dry-run']);
133
156
  proxyCommand(command, {
134
- commandArgs
157
+ commandArgs,
158
+ // File names with `:` cause issues in Windows, therefore the file name is
159
+ // different from the command name.
160
+ fileName: 'config-sync'
135
161
  });
136
162
  break;
137
163
  }
@@ -158,15 +184,13 @@ function getArgsForCommand(allowedFlags = []) {
158
184
  }, []);
159
185
  }
160
186
 
161
- function proxyCommand(fileName, {
187
+ function proxyCommand(commandName, {
162
188
  commandArgs,
189
+ fileName,
163
190
  noExit
164
191
  } = {}) {
165
- // Load dotenv files into the process environment.
166
- // This is essentially what `dotenv-cli` does, but it's now built into this CLI.
167
- loadDotEnvFiles(flags); // Spawn the actual command.
168
-
169
- const result = spawn.sync('node', [require.resolve(`../commands/${fileName}`)].concat(commandArgs), {
192
+ // Spawn the actual command.
193
+ const result = spawn.sync('node', [require.resolve(`../commands/${fileName || commandName}`)].concat(commandArgs), {
170
194
  stdio: 'inherit'
171
195
  }); // Handle exit signals.
172
196
 
@@ -174,13 +198,13 @@ function proxyCommand(fileName, {
174
198
  switch (result.signal) {
175
199
  case 'SIGKILL':
176
200
  {
177
- console.log(`The command ${fileName} failed because the process exited too early. This probably means the system ran out of memory or someone called "kill -9" on the process.`);
201
+ console.log(`The command ${commandName} failed because the process exited too early. This probably means the system ran out of memory or someone called "kill -9" on the process.`);
178
202
  break;
179
203
  }
180
204
 
181
205
  case 'SIGTERM':
182
206
  {
183
- console.log(`The command ${fileName} failed because the process exited too early. Someone might have called "kill" or "killall", or the system could be shutting down.`);
207
+ console.log(`The command ${commandName} failed because the process exited too early. Someone might have called "kill" or "killall", or the system could be shutting down.`);
184
208
  break;
185
209
  }
186
210
 
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+
3
+ /* eslint-disable react-hooks/rules-of-hooks */
4
+ const fs = require('fs-extra');
5
+
6
+ const path = require('path');
7
+
8
+ const {
9
+ build
10
+ } = require('vite');
11
+
12
+ const pluginGraphql = require('@rollup/plugin-graphql');
13
+
14
+ const pluginReact = require('@vitejs/plugin-react').default;
15
+
16
+ const {
17
+ generateTemplate
18
+ } = require('@commercetools-frontend/mc-html-template');
19
+
20
+ const {
21
+ packageLocation: applicationStaticAssetsPath
22
+ } = require('@commercetools-frontend/assets');
23
+
24
+ const paths = require('../config/paths');
25
+
26
+ const DEFAULT_PORT = parseInt(process.env.HTTP_PORT, 10) || 3001;
27
+
28
+ const execute = async () => {
29
+ // Ensure the `/public` folder exists.
30
+ fs.mkdirSync(paths.appBuild, {
31
+ recursive: true
32
+ }); // Generate `index.html` (template).
33
+
34
+ const appEntryPoint = path.relative(paths.appRoot, paths.entryPoint);
35
+ const html = generateTemplate({
36
+ // Define the module entry point (path relative from the `/public` folder).
37
+ // NOTE: that this is different from the development configuration.
38
+ scriptImports: [`<script type="module" src="/${appEntryPoint}"></script>`]
39
+ }); // Write `index.html` (template) into the `/public` folder.
40
+
41
+ fs.writeFileSync(paths.appIndexHtml, html, {
42
+ encoding: 'utf8'
43
+ }); // TODO: allow to pass additional config options.
44
+ // * `define`
45
+ // * `plugins`
46
+
47
+ await build({
48
+ configFile: false,
49
+ root: paths.appRoot,
50
+ define: {
51
+ 'process.env.DEBUG': JSON.stringify(false),
52
+ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
53
+ },
54
+ build: {
55
+ outDir: 'public',
56
+ assetsDir: '.',
57
+ rollupOptions: {
58
+ // This is necessary to instruct Vite that the `index.html` (template)
59
+ // is located in the `/public` folder.
60
+ // NOTE that after the build, Vite will write the `index.html` (template)
61
+ // at the `/public/public/index.html` location. See `fs.renameSync` below.
62
+ input: paths.appIndexHtml
63
+ }
64
+ },
65
+ server: {
66
+ port: DEFAULT_PORT
67
+ },
68
+ plugins: [pluginGraphql(), pluginReact({
69
+ jsxImportSource: '@emotion/react',
70
+ babel: {
71
+ plugins: ['@emotion/babel-plugin']
72
+ }
73
+ })]
74
+ }); // Rename `/public/public/index.html` to `/public/index.html.template`
75
+
76
+ fs.renameSync( // Because of our custom entry point path (`/public/index.html`),
77
+ // Vite will write the `index.html` to `/public/public/index.html`.
78
+ // We need to move this file to the `/public` folder and rename it
79
+ // to `index.html.template` (as expected by the `compile-html` command).
80
+ path.join(paths.appBuild, 'public/index.html'), paths.appIndexHtmlTemplate); // Clean up nested folder
81
+
82
+ fs.rmdirSync(path.join(paths.appBuild, 'public')); // Copy public assets
83
+
84
+ fs.copySync(path.join(applicationStaticAssetsPath, 'html-page'), paths.appBuild, {
85
+ dereference: true
86
+ });
87
+ };
88
+
89
+ execute().catch(error => {
90
+ if (error && error.message) {
91
+ console.error(error.message);
92
+ }
93
+
94
+ process.exit(1);
95
+ });
@@ -72,7 +72,7 @@ measureFileSizesBeforeBuild(paths.appBuild).then(previousFileSizes => {
72
72
  process.exit(1);
73
73
  }).catch(err => {
74
74
  if (err && err.message) {
75
- console.log(err.message);
75
+ console.error(err.message);
76
76
  }
77
77
 
78
78
  process.exit(1);
@@ -45,6 +45,9 @@ const generateStatic = async () => {
45
45
  };
46
46
 
47
47
  generateStatic().catch(error => {
48
- console.error(error);
48
+ if (error && error.message) {
49
+ console.error(error.message);
50
+ }
51
+
49
52
  process.exit(1);
50
53
  });
@@ -17,7 +17,7 @@ const server = http.createServer((request, response) => {
17
17
  source: '/favicon*',
18
18
  destination: '/favicon.png'
19
19
  }, {
20
- source: '/login',
20
+ source: '/login*',
21
21
  destination: '/login.html'
22
22
  }, {
23
23
  source: '/logout',
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+
3
+ const fs = require('fs-extra');
4
+
5
+ const path = require('path');
6
+
7
+ const {
8
+ createServer
9
+ } = require('vite');
10
+
11
+ const pluginGraphql = require('@rollup/plugin-graphql');
12
+
13
+ const pluginReact = require('@vitejs/plugin-react').default;
14
+
15
+ const {
16
+ processConfig
17
+ } = require('@commercetools-frontend/application-config');
18
+
19
+ const {
20
+ replaceHtmlPlaceholders,
21
+ processHeaders,
22
+ generateTemplate
23
+ } = require('@commercetools-frontend/mc-html-template');
24
+
25
+ const {
26
+ createMcDevAuthenticationMiddleware
27
+ } = require('@commercetools-frontend/mc-dev-authentication');
28
+
29
+ const {
30
+ packageLocation: applicationStaticAssetsPath
31
+ } = require('@commercetools-frontend/assets');
32
+
33
+ const paths = require('../config/paths');
34
+
35
+ const DEFAULT_PORT = parseInt(process.env.HTTP_PORT, 10) || 3001;
36
+
37
+ const pluginCustomApplication = applicationConfig => {
38
+ /**
39
+ * @type {import('vite').Plugin}
40
+ */
41
+ return {
42
+ name: 'custom-application',
43
+
44
+ /**
45
+ * @type {import('vite').ServerHook}
46
+ */
47
+ configureServer(server) {
48
+ return () => {
49
+ // Users do not need to have/maintain the `index.html` (as expected by Vite)
50
+ // as it's generated and maintained by the Custom Application CLI.
51
+ // Therefore, the generated `index.html` (template) is written into the `/public`
52
+ // folder so that it's gitignored.
53
+ // As a result, we need to make sure to point the URI path to the correct location.
54
+ server.middlewares.use((req, res, next) => {
55
+ if (req.url === '/index.html') {
56
+ req.url = '/public/index.html';
57
+ }
58
+
59
+ next();
60
+ }); // Handle auth routes for internal local development.
61
+
62
+ server.middlewares.use(createMcDevAuthenticationMiddleware(applicationConfig));
63
+ };
64
+ },
65
+
66
+ /**
67
+ * @type {import('vite').IndexHtmlTransformHook}
68
+ */
69
+ transformIndexHtml(rawHtml, _ctx) {
70
+ const compiledHeaders = processHeaders(applicationConfig);
71
+ const enhancedLocalEnv = Object.assign({}, applicationConfig.env, // Now that the app config is defined as a `env.json`, when we start the FE app
72
+ // to point to the local backend API by passing the `MC_API_URL` env does not
73
+ // work anymore). To make it work again, we can override the `env.json` config
74
+ // with the env variable before injecting the values into the index.html.
75
+ // NOTE: this is only necessary for development.
76
+ process.env.MC_API_URL ? {
77
+ mcApiUrl: process.env.MC_API_URL
78
+ } : {}); // Resolve the placeholders of the `index.html` (template) file, before serving it.
79
+
80
+ const html = replaceHtmlPlaceholders(rawHtml, {
81
+ env: enhancedLocalEnv,
82
+ headers: compiledHeaders
83
+ });
84
+ return html;
85
+ }
86
+
87
+ };
88
+ };
89
+
90
+ const execute = async () => {
91
+ // Load the Custom Application config file first.
92
+ const applicationConfig = processConfig(); // Ensure the `/public` folder exists.
93
+
94
+ fs.mkdirSync(paths.appBuild, {
95
+ recursive: true
96
+ }); // Generate `index.html` (template).
97
+
98
+ const appEntryPoint = path.relative(paths.appRoot, paths.entryPoint);
99
+ const html = generateTemplate({
100
+ // Define the module entry point (path relative to the `/public` folder).
101
+ // NOTE: that this is different from the production configuration.
102
+ scriptImports: [`<script type="module" src="/../${appEntryPoint}"></script>`]
103
+ }); // Write `index.html` (template) into the `/public` folder.
104
+
105
+ fs.writeFileSync(paths.appIndexHtml, html, {
106
+ encoding: 'utf8'
107
+ }); // TODO: allow to pass additional config options.
108
+ // * `define`
109
+ // * `plugins`
110
+
111
+ const server = await createServer({
112
+ configFile: false,
113
+ root: paths.appRoot,
114
+ define: {
115
+ 'process.env.DEBUG': JSON.stringify(false),
116
+ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
117
+ },
118
+ server: {
119
+ port: DEFAULT_PORT
120
+ },
121
+ plugins: [pluginGraphql(), pluginReact({
122
+ jsxImportSource: '@emotion/react',
123
+ babel: {
124
+ plugins: ['@emotion/babel-plugin']
125
+ }
126
+ }), pluginCustomApplication(applicationConfig)]
127
+ });
128
+ await server.listen(); // Copy public assets to `/public` folder (even in development).
129
+
130
+ fs.copySync(path.join(applicationStaticAssetsPath, 'html-page'), paths.appBuild, {
131
+ dereference: true
132
+ });
133
+ server.printUrls();
134
+ };
135
+
136
+ execute().catch(error => {
137
+ if (error && error.message) {
138
+ console.error(error.message);
139
+ }
140
+
141
+ process.exit(1);
142
+ });
@@ -72,8 +72,6 @@ choosePort(HOST, DEFAULT_PORT).then(port => {
72
72
  }); // Serve webpack assets generated by the compiler over a web sever.
73
73
 
74
74
  const serverConfig = createDevServerConfig({
75
- allowedHost: urls.localUrlForBrowser,
76
- contentBase: paths.appBuild,
77
75
  port,
78
76
  publicPath: config.output.publicPath
79
77
  });
@@ -103,7 +101,7 @@ choosePort(HOST, DEFAULT_PORT).then(port => {
103
101
  }
104
102
  }).catch(err => {
105
103
  if (err && err.message) {
106
- console.log(err.message);
104
+ console.error(err.message);
107
105
  }
108
106
 
109
107
  process.exit(1);
@@ -262,7 +262,7 @@ module.exports = function createWebpackConfigForDevelopment(options = {}) {
262
262
  test: function testForNormalCssFiles(fileName) {
263
263
  return (// Use this only for plain CSS.
264
264
  // For css-modules, see loader above.
265
- fileName.endsWith('.css') && !fileName.endsWith('.mod.css')
265
+ fileName.endsWith('.css') && !(fileName.endsWith('.mod.css') || fileName.endsWith('.module.css'))
266
266
  );
267
267
  },
268
268
  // "postcss" loader applies autoprefixer to our CSS.
@@ -281,7 +281,7 @@ module.exports = function createWebpackConfigForProduction(options = {}) {
281
281
  test: function testForNormalCssFiles(fileName) {
282
282
  return (// Use this only for plain CSS.
283
283
  // For css-modules, see loader above.
284
- fileName.endsWith('.css') && !fileName.endsWith('.mod.css')
284
+ fileName.endsWith('.css') && !(fileName.endsWith('.mod.css') || fileName.endsWith('.module.css'))
285
285
  );
286
286
  },
287
287
  // "postcss" loader applies autoprefixer to our CSS.
@@ -1,7 +1,5 @@
1
1
  "use strict";
2
2
 
3
- const errorOverlayMiddleware = require('react-dev-utils/errorOverlayMiddleware');
4
-
5
3
  const {
6
4
  processConfig
7
5
  } = require('@commercetools-frontend/application-config');
@@ -10,7 +8,9 @@ const {
10
8
  processHeaders
11
9
  } = require('@commercetools-frontend/mc-html-template');
12
10
 
13
- const devAuthentication = require('@commercetools-frontend/mc-dev-authentication');
11
+ const {
12
+ createMcDevAuthenticationMiddleware
13
+ } = require('@commercetools-frontend/mc-dev-authentication');
14
14
 
15
15
  const applicationConfig = processConfig();
16
16
  const compiledHeaders = processHeaders(applicationConfig);
@@ -26,8 +26,6 @@ const sockPath = process.env.WDS_SOCKET_PATH; // default: '/ws'
26
26
  const sockPort = process.env.WDS_SOCKET_PORT;
27
27
 
28
28
  module.exports = ({
29
- allowedHost,
30
- contentBase,
31
29
  port,
32
30
  publicPath
33
31
  }) => ({
@@ -62,37 +60,11 @@ module.exports = ({
62
60
  // Enable HTTPS if the HTTPS environment variable is set to 'true'
63
61
  // `proxy` is run between `before` and `after` `webpack-dev-server` hooks
64
62
  setupMiddlewares(middlewares, devServer) {
65
- var _applicationConfig$en, _applicationConfig$en2;
66
-
67
63
  if (!devServer) {
68
64
  throw new Error('webpack-dev-server is not defined');
69
- } // This lets us open files from the runtime error overlay.
70
-
71
-
72
- middlewares.unshift(errorOverlayMiddleware());
73
- devServer.app.set('views', devAuthentication.views);
74
- devServer.app.set('view engine', devAuthentication.config.viewEngine);
75
- devServer.app.post('/api/graphql', (request, response) => {
76
- response.statusCode = 404;
77
- response.setHeader('Content-Type', 'application/json');
78
- response.end(JSON.stringify({
79
- message: `This GraphQL endpoint is only available in production in the [Merchant Center Proxy Router](https://docs.commercetools.com/custom-applications/concepts/merchant-center-proxy-router). Please check that you are not calling this endpoint in development mode.`
80
- }));
81
- });
82
-
83
- if ((_applicationConfig$en = applicationConfig.env.__DEVELOPMENT__) !== null && _applicationConfig$en !== void 0 && (_applicationConfig$en2 = _applicationConfig$en.oidc) !== null && _applicationConfig$en2 !== void 0 && _applicationConfig$en2.authorizeUrl) {
84
- var _applicationConfig$en3, _applicationConfig$en4;
85
-
86
- // Handle login page for OIDC workflow when developing against a local MC API.
87
- if ((_applicationConfig$en3 = applicationConfig.env.__DEVELOPMENT__) !== null && _applicationConfig$en3 !== void 0 && (_applicationConfig$en4 = _applicationConfig$en3.oidc) !== null && _applicationConfig$en4 !== void 0 && _applicationConfig$en4.authorizeUrl.startsWith('http://localhost')) {
88
- devServer.app.get('/login/authorize', devAuthentication.middlewares.createLoginMiddleware(applicationConfig.env));
89
- }
90
- } else {
91
- devServer.app.get('/login', devAuthentication.middlewares.createLoginMiddleware(applicationConfig.env)); // Intercept the /logout page and "remove" the auth cookie value
92
-
93
- devServer.app.get('/logout', devAuthentication.middlewares.createLogoutMiddleware(applicationConfig.env));
94
65
  }
95
66
 
67
+ middlewares.push(createMcDevAuthenticationMiddleware(applicationConfig));
96
68
  return middlewares;
97
69
  }
98
70
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commercetools-frontend/mc-scripts",
3
- "version": "21.3.3",
3
+ "version": "21.5.0",
4
4
  "description": "Configuration and scripts for developing a MC application",
5
5
  "bugs": "https://github.com/commercetools/merchant-center-application-kit/issues",
6
6
  "repository": {
@@ -26,17 +26,19 @@
26
26
  "build:bundles:watch": "yarn build -w"
27
27
  },
28
28
  "dependencies": {
29
- "@babel/core": "^7.17.8",
30
- "@babel/runtime": "^7.17.8",
31
- "@babel/runtime-corejs3": "^7.17.8",
32
- "@commercetools-frontend/application-config": "21.3.3",
29
+ "@babel/core": "^7.17.9",
30
+ "@babel/runtime": "^7.17.9",
31
+ "@babel/runtime-corejs3": "^7.17.9",
32
+ "@commercetools-frontend/application-config": "21.5.0",
33
33
  "@commercetools-frontend/assets": "21.0.0",
34
- "@commercetools-frontend/babel-preset-mc-app": "21.3.2",
35
- "@commercetools-frontend/constants": "21.3.0",
36
- "@commercetools-frontend/mc-dev-authentication": "21.0.0",
37
- "@commercetools-frontend/mc-html-template": "21.3.3",
34
+ "@commercetools-frontend/babel-preset-mc-app": "21.3.4",
35
+ "@commercetools-frontend/constants": "21.3.4",
36
+ "@commercetools-frontend/mc-dev-authentication": "21.5.0",
37
+ "@commercetools-frontend/mc-html-template": "21.5.0",
38
38
  "@pmmmwh/react-refresh-webpack-plugin": "0.5.4",
39
+ "@rollup/plugin-graphql": "1.1.0",
39
40
  "@svgr/webpack": "6.2.1",
41
+ "@vitejs/plugin-react": "1.3.0",
40
42
  "autoprefixer": "^10.4.4",
41
43
  "babel-loader": "8.2.4",
42
44
  "browserslist": "^4.20.2",
@@ -47,7 +49,7 @@
47
49
  "dotenv": "16.0.0",
48
50
  "dotenv-expand": "8.0.3",
49
51
  "fs-extra": "10.0.1",
50
- "graphql-request": "^4.1.0",
52
+ "graphql-request": "^4.2.0",
51
53
  "graphql-tag": "^2.12.6",
52
54
  "html-webpack-plugin": "5.5.0",
53
55
  "json-loader": "0.5.7",
@@ -60,7 +62,7 @@
60
62
  "postcss-import": "14.1.0",
61
63
  "postcss-loader": "6.2.1",
62
64
  "postcss-reporter": "7.0.5",
63
- "prettier": "2.6.1",
65
+ "prettier": "2.6.2",
64
66
  "prompts": "^2.4.2",
65
67
  "querystring-es3": "^0.2.1",
66
68
  "rcfile": "1.0.3",
@@ -73,9 +75,10 @@
73
75
  "terser-webpack-plugin": "5.3.1",
74
76
  "thread-loader": "3.0.4",
75
77
  "url": "^0.11.0",
76
- "webpack": "5.70.0",
78
+ "vite": "2.9.1",
79
+ "webpack": "5.72.0",
77
80
  "webpack-bundle-analyzer": "4.5.0",
78
- "webpack-dev-server": "4.7.4",
81
+ "webpack-dev-server": "4.8.1",
79
82
  "webpackbar": "5.0.2"
80
83
  },
81
84
  "devDependencies": {