@s-ui/bundler 8.0.0-beta.0 → 8.0.0-beta.1

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
@@ -1,4 +1,4 @@
1
- # sui-bunder
1
+ # sui-bundler
2
2
 
3
3
  > Config-free bundler for ES6 React apps.
4
4
 
@@ -81,6 +81,12 @@ To link more than one package at time, use as many times as desired the argument
81
81
  $ sui-bundler dev --link-package=/absolute_path/to/npm_package --link-package=/absolute_path2/to/npm_package
82
82
  ```
83
83
 
84
+ You can also use `-l` as a shorthand to link a package.
85
+
86
+ ```
87
+ $ sui-bundler dev -l /absolute_path/to/npm_package -l /absolute_path2/to/npm_package
88
+ ```
89
+
84
90
  If you want to link all the packages inside a monorepo-multipackage. Use the flag `--link-all` pointing to the folder where each package lives.
85
91
  For example, if you want to link all the components in a Studio, the command should be:
86
92
 
@@ -88,6 +94,12 @@ For example, if you want to link all the components in a Studio, the command sho
88
94
  $ sui-bundler dev --link-all ../frontend-ma--uilib-components/components
89
95
  ```
90
96
 
97
+ You can use `-L` as a shorthand to link all packages.
98
+
99
+ ```
100
+ $ sui-bundler dev -L ../frontend-ma--uilib-components/components
101
+ ```
102
+
91
103
  And of course you can combine `link-all` and `link-package` flags
92
104
 
93
105
  ### Production
@@ -124,6 +136,7 @@ sui-bundler lib umd/index.js -o lib/fancy -p http://my-cdn.com/fancy
124
136
  ```
125
137
 
126
138
  `sui-bundler lib` will add your package version as subfolder:
139
+
127
140
  - `-o lib/fancy` outputs to `./lib/fancy/0.0.0/`
128
141
  - `-p http://my-cdn.com/fancy` sets `http://my-cdn.com/fancy/0.0.0` as public path for chunks loading.
129
142
  - `-r http://my-cdn.com/fancy` sets `http://my-cdn.com/fancy` as public path for chunks loading, discarded the version subdirectory.
@@ -155,7 +168,10 @@ This tool works with zero configuration out the box but you could use some confi
155
168
  "vendor": ["react", "react-dom"],
156
169
  "cdn": "https://url_to_me_cdn.com/",
157
170
  "externals-manifest": "https://url_to_me_cdn/manifest.json",
158
- "alias": {"react": "preact"},
171
+ "alias": {
172
+ "react": "preact"
173
+ },
174
+ "measure": true,
159
175
  "offline": true,
160
176
  "targets": {
161
177
  "chrome": "41",
@@ -169,7 +185,8 @@ This tool works with zero configuration out the box but you could use some confi
169
185
  "prod": "hidden-source-map"
170
186
  },
171
187
  "optimizations": {
172
- "splitFrameworkOnChunk": true
188
+ "splitFrameworkOnChunk": true,
189
+ "useExperimentalMinifier": true
173
190
  }
174
191
  }
175
192
  }
@@ -193,20 +210,24 @@ import {register, unregister} from '@s-ui/bundler/registerServiceWorker'
193
210
  register({
194
211
  first: () => window.alert('Content is cached for offline use.'),
195
212
  renovate: () => window.alert('New content is available; please refresh.')
196
- });
213
+ })
197
214
  ```
198
215
 
199
216
  You should pass a handler in order to handle when content gets cached for the first time the content and another when you get new content and want to handle how to show a notification to the user in order to let him decide if he wants to refresh the page.
200
217
 
201
218
  If you want to remove your ServiceWorker, you need to use the method `unregister`, the same way you used the `register` method before.
202
219
 
220
+ ### Build time measurement
221
+
222
+ Set `measure` to `true` if you want to check step by step build times.
223
+
203
224
  ### Only Caching
204
225
 
205
226
  It's possible to create a service worker that caches all static resources
206
227
 
207
228
  There are two ways to activate the statics cache option:
208
229
 
209
- 1. Create a `src/offline.html` page as mentioned in the [offline]( #Offline) section
230
+ 1. Create a `src/offline.html` page as mentioned in the [offline](#Offline) section
210
231
  2. Add the `staticsCacheOnly` option within the package.json like this:
211
232
 
212
233
  ```json
@@ -218,9 +239,11 @@ There are two ways to activate the statics cache option:
218
239
  }
219
240
  }
220
241
  ```
242
+
221
243
  > Statics will be cached but no offline page will be activated
222
244
 
223
245
  ## Externals Manifest
246
+
224
247
  If your are using an external CDN to store statics assets that are now managed by Webpack, like SVG or IMGs, you can create a manifest.json file in the root of your CDN (likehttps://spa-mock-statics.surge.sh/manifest.json`).
225
248
 
226
249
  If you define the `externals-manifest` key in the config pointing to this link, sui-bundler will replace any ocurrence of each key for the value
@@ -230,14 +253,19 @@ If in your CSS you have:
230
253
  ```css
231
254
  #app {
232
255
  color: blue;
233
- background: url('https://spa-mock-statics.surge.sh/images/common/sprite-sheet/sprite-ma.png') no-repeat scroll;
256
+ background: url('https://spa-mock-statics.surge.sh/images/common/sprite-sheet/sprite-ma.png')
257
+ no-repeat scroll;
234
258
  }
235
259
  ```
236
260
 
237
261
  After compile you will get:
238
262
 
239
263
  ```css
240
- #app{color:#00f;background:url(https://spa-mock-statics.surge.sh/images/common/sprite-sheet/sprite-ma.72d1edb214.png) no-repeat scroll}
264
+ #app {
265
+ color: #00f;
266
+ background: url(https://spa-mock-statics.surge.sh/images/common/sprite-sheet/sprite-ma.72d1edb214.png)
267
+ no-repeat scroll;
268
+ }
241
269
  ```
242
270
 
243
271
  Or if in your JS you have:
@@ -284,7 +312,6 @@ Different values can be configured for development (`dev`) and production (`prod
284
312
  }
285
313
  ```
286
314
 
287
-
288
315
  Check all possible values accepted by webpack in the [devtool webpack docs](https://webpack.js.org/configuration/devtool/#devtool)
289
316
 
290
317
  ## Optimizations
@@ -293,8 +320,14 @@ You could tweak the performance of your bundle generation by using some flags pr
293
320
 
294
321
  `splitFrameworkOnChunk` (default: `false`): Separate in a chunk all the packages related to React. This gives you a separated static hashed file, as the version of React doesn't get often upgraded, and a benefit over HTTP2 connections are you're serving smaller files.
295
322
 
323
+ `useExperimentalMinifier` (default: `false`): Use `esbuild-loader` to minify JavaScript and CSS instead using `terser` and `css-minimizer-webpack-plugin` in order to boost build time and memory usage.
324
+
296
325
  ## Migrations
297
326
 
327
+ ### Migrate from v7 to v8
328
+
329
+ `useExperimentalSCSSLoader` is not used anymore and it will be ignored.
330
+
298
331
  ### Migrate from v6 to v7
299
332
 
300
333
  - In order to keep same config object across all `sui` tools, `sui-bundler` config has been moved from package.json root to the `config` property.
@@ -10,7 +10,7 @@ const logUpdate = require('@s-ui/helpers/log-update')
10
10
  const installNeededDependencies = async () => {
11
11
  try {
12
12
  require('webpack-bundle-analyzer')
13
- require('duplicate-package-checker-webpack-plugin')
13
+ return true
14
14
  } catch (e) {
15
15
  logUpdate('Installing needed dependencies...')
16
16
  return getSpawnPromise('npm', [
@@ -19,14 +19,20 @@ const installNeededDependencies = async () => {
19
19
  '--no-optional',
20
20
  '--no-audit',
21
21
  '--no-fund',
22
- 'webpack-bundle-analyzer@4.2.0 duplicate-package-checker-webpack-plugin@3.0.0'
22
+ 'webpack-bundle-analyzer@4.3.0 duplicate-package-checker-webpack-plugin@3.0.0'
23
23
  ]).then(() => {
24
24
  logUpdate.done('Installed needed dependencies')
25
+ getSpawnPromise('./node_modules/.bin/sui-bundler', ['analyzer']).then(
26
+ () => false
27
+ )
25
28
  })
26
29
  }
27
30
  }
31
+
28
32
  ;(async () => {
29
- await installNeededDependencies()
33
+ const keepExecution = await installNeededDependencies()
34
+ if (!keepExecution) return
35
+
30
36
  const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer')
31
37
  const DuplicatePackageCheckerPlugin = require('duplicate-package-checker-webpack-plugin')
32
38
 
@@ -19,7 +19,7 @@ process.env.NODE_ENV = process.env.NODE_ENV || 'production'
19
19
  program
20
20
  .option('-C, --clean', 'Remove public folder before create a new one')
21
21
  .option(
22
- '--link-package [package]',
22
+ '-l, --link-package [package]',
23
23
  'Replace each occurrence of this package with an absolute path to this folder',
24
24
  (v, m) => {
25
25
  m.push(v)
@@ -1,46 +1,60 @@
1
1
  #!/usr/bin/env node
2
2
  /* eslint-disable no-console */
3
3
 
4
+ process.on('unhandledRejection', err => {
5
+ throw err
6
+ })
7
+
4
8
  const program = require('commander')
5
9
  const path = require('path')
6
- const clearConsole = require('react-dev-utils/clearConsole')
7
- const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles')
10
+ const WebpackDevServer = require('webpack-dev-server')
11
+
12
+ const clearConsole = require('../utils/clearConsole')
13
+ const checkRequiredFiles = require('../utils/checkRequiredFiles')
14
+ const {
15
+ choosePort,
16
+ prepareUrls
17
+ } = require('react-dev-utils/WebpackDevServerUtils')
8
18
 
9
19
  const webpackConfig = require('../webpack.config.dev')
20
+
21
+ const createDevServerConfig = require('../factories/createDevServerConfig')
10
22
  const createCompiler = require('../factories/createCompiler')
11
23
 
12
24
  const linkLoaderConfigBuilder = require('../loaders/linkLoaderConfigBuilder')
13
25
  const log = require('../shared/log')
14
26
 
15
- program
16
- .option('-c, --context [folder]', 'Context folder (cwd by default)')
17
- .option(
18
- '--link-all [monorepo]',
19
- 'Link all packages inside of monorepo multipackage'
20
- )
21
- .option(
22
- '--link-package [package]',
23
- 'Replace each occurrence of this package with an absolute path to this folder',
24
- (v, m) => {
25
- m.push(v)
26
- return m
27
- },
28
- []
29
- )
30
- .on('--help', () => {
31
- console.log(' Examples:')
32
- console.log('')
33
- console.log(' $ sui-bundler dev')
34
- console.log(' $ sui-bundler dev --context /my/app/folder')
35
- console.log(' $ sui-bundler dev --link-package /my/domain/folder')
36
- console.log('')
37
- })
38
- .parse(process.argv)
39
- const {context} = program
40
- webpackConfig.context = context || webpackConfig.context
27
+ const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000
28
+ const HOST = process.env.HOST || '0.0.0.0'
41
29
 
42
- // Don't show ugly deprecation warnings that mess with the logging
43
- process.noDeprecation = true
30
+ if (!module.parent) {
31
+ program
32
+ .option('-c, --context [folder]', 'Context folder (cwd by default)')
33
+ .option(
34
+ '-L, --link-all [monorepo]',
35
+ 'Link all packages inside of monorepo multipackage'
36
+ )
37
+ .option(
38
+ '-l, --link-package [package]',
39
+ 'Replace each occurrence of this package with an absolute path to this folder',
40
+ (v, m) => {
41
+ m.push(v)
42
+ return m
43
+ },
44
+ []
45
+ )
46
+ .on('--help', () => {
47
+ console.log(' Examples:')
48
+ console.log('')
49
+ console.log(' $ sui-bundler dev')
50
+ console.log(' $ sui-bundler dev --context /my/app/folder')
51
+ console.log(' $ sui-bundler dev --link-package /my/domain/folder')
52
+ console.log('')
53
+ })
54
+ .parse(process.argv)
55
+ const {context} = program
56
+ webpackConfig.context = context || webpackConfig.context
57
+ }
44
58
 
45
59
  const start = async ({
46
60
  config = webpackConfig,
@@ -59,15 +73,38 @@ const start = async ({
59
73
  )
60
74
  process.exit(1)
61
75
  }
76
+ const protocol = process.env.HTTPS === 'true' ? 'https' : 'http'
77
+ const port = await choosePort(HOST, DEFAULT_PORT)
78
+ const urls = prepareUrls(protocol, HOST, port)
62
79
  const nextConfig = linkLoaderConfigBuilder({
63
80
  config,
64
81
  linkAll: program.linkAll,
65
82
  packagesToLink
66
83
  })
67
- const compiler = createCompiler(nextConfig)
68
- compiler.watch({}, () => {})
84
+ const compiler = createCompiler(nextConfig, urls)
85
+ const serverConfig = createDevServerConfig(nextConfig, urls.lanUrlForConfig)
86
+ const devServer = new WebpackDevServer(
87
+ {
88
+ ...serverConfig,
89
+ port,
90
+ host: HOST
91
+ },
92
+ compiler
93
+ )
94
+ log.processing('❯ Starting the development server...\n')
95
+ devServer.startCallback(err => {
96
+ if (err) return log.error(err)
97
+ ;['SIGINT', 'SIGTERM'].forEach(sig => {
98
+ process.on(sig, () => {
99
+ devServer.stop()
100
+ process.exit()
101
+ })
102
+ })
103
+ })
69
104
  }
70
105
 
71
- start()
106
+ if (!module.parent) {
107
+ start()
108
+ }
72
109
 
73
110
  module.exports = start
@@ -1,10 +1,19 @@
1
1
  const webpack = require('webpack')
2
+ const formatWebpackMessages = require('../utils/formatWebpackMessages')
3
+ const clearConsole = require('../utils/clearConsole')
2
4
  const log = require('../shared/log')
3
5
 
4
- module.exports = config => {
6
+ const isInteractive = process.stdout.isTTY
7
+
8
+ const printInstructions = ({urls}) =>
9
+ log.info(`
10
+ Local: ${urls.localUrlForTerminal}
11
+ Network: ${urls.lanUrlForTerminal}
12
+ `)
13
+
14
+ module.exports = (config, urls) => {
5
15
  let compiler
6
16
  try {
7
- log.processing('❯ Compiling...')
8
17
  compiler = webpack(config)
9
18
  } catch (err) {
10
19
  log.error(`✖ Failed to compile:\n ${err.message || err}`)
@@ -12,23 +21,28 @@ module.exports = config => {
12
21
  }
13
22
 
14
23
  compiler.hooks.invalid.tap('invalid', () => {
24
+ if (isInteractive) clearConsole()
15
25
  log.processing('❯ Compiling...')
16
26
  })
17
27
 
18
28
  compiler.hooks.done.tap('done', stats => {
29
+ if (isInteractive) clearConsole()
30
+
19
31
  const isSuccessful = !stats.hasErrors()
20
32
 
21
33
  // Log the correct message of compilation depending if we have warnings
22
34
  if (isSuccessful) {
23
- const {time} = stats.toJson('minimal')
24
35
  stats.hasWarnings()
25
- ? log.warn(`⚠ Compiled with warnings in ${time}ms`)
26
- : log.success(`✔ Compiled successfully in ${time}ms`)
36
+ ? log.warn('⚠ Compiled with warnings')
37
+ : log.success('✔ Compiled successfully')
27
38
  }
28
39
 
40
+ // Even with warnings, we show instructions to access localhost if we have a compilation
41
+ if (isSuccessful && isInteractive) printInstructions({urls})
42
+
29
43
  // If we have errors, we must show them
30
44
  if (!isSuccessful) {
31
- const messages = console.error(stats.toJson('errors-only', true))
45
+ const messages = formatWebpackMessages(stats.toJson('errors-only', true))
32
46
  // Only keep the first error. Others are often indicative
33
47
  // of the same problem, but confuse the reader with noise.
34
48
  if (messages.errors.length > 1) messages.errors.length = 1
@@ -38,7 +52,9 @@ module.exports = config => {
38
52
 
39
53
  // With warnings, even after showing the instructions we must list the warnings we have
40
54
  if (stats.hasWarnings()) {
41
- const messages = console.warn(stats.toJson('errors-warnings', true))
55
+ const messages = formatWebpackMessages(
56
+ stats.toJson('errors-warnings', true)
57
+ )
42
58
  log.warn(messages.warnings.join('\n\n'))
43
59
  }
44
60
  })
@@ -0,0 +1,37 @@
1
+ // @ts-check
2
+
3
+ const noopServiceWorkerMiddleware = require('react-dev-utils/noopServiceWorkerMiddleware')
4
+ const ignoredFiles = require('react-dev-utils/ignoredFiles')
5
+
6
+ const {HOST, HTTPS} = process.env
7
+ const protocol = HTTPS === 'true' ? 'https' : 'http'
8
+ const host = HOST || '0.0.0.0'
9
+
10
+ module.exports = config => ({
11
+ allowedHosts: 'all',
12
+ client: {
13
+ logging: 'none',
14
+ overlay: {
15
+ errors: true,
16
+ warnings: false
17
+ },
18
+ progress: true
19
+ },
20
+ static: {
21
+ directory: 'public',
22
+ watch: {
23
+ ignored: ignoredFiles(config.context)
24
+ }
25
+ },
26
+ hot: true,
27
+ https: protocol === 'https',
28
+ host,
29
+ historyApiFallback: {
30
+ disableDotRule: true
31
+ },
32
+ onAfterSetupMiddleware(devServer) {
33
+ // This service worker file is effectively a 'no-op' that will reset any
34
+ // previous service worker registered for the same host:port combination.
35
+ devServer.app.use(noopServiceWorkerMiddleware(config.output.publicPath))
36
+ }
37
+ })
@@ -1,6 +1,7 @@
1
1
  const fg = require('fast-glob')
2
2
  const path = require('path')
3
3
 
4
+ const {config} = require('../shared')
4
5
  const log = require('../shared/log')
5
6
  const {defaultAlias} = require('../shared/resolve-alias')
6
7
  const createSassLinkImporter = require('./sassLinkImporter.js')
@@ -60,12 +61,12 @@ module.exports = ({config, packagesToLink, linkAll}) => {
60
61
  }
61
62
 
62
63
  /**
63
- * Create a sass-loader config for scss files that
64
+ * Create a @s-ui/sass-loader config for scss files that
64
65
  * are handled by Sass. These are nested modules imported
65
66
  * and thus is sass binary which needs a special config for them.
66
67
  */
67
68
  const sassLoaderWithLinkImporter = {
68
- loader: require.resolve('sass-loader'),
69
+ loader: require.resolve('@s-ui/sass-loader'),
69
70
  options: {
70
71
  sassOptions: {
71
72
  importer: createSassLinkImporter(entryPoints)
@@ -80,7 +81,7 @@ module.exports = ({config, packagesToLink, linkAll}) => {
80
81
  const {rules} = config.module
81
82
  const rulesWithLink = rules.map(rule => {
82
83
  const {use, test: regex} = rule
83
- if (!regex.test('.css')) return rule
84
+ if (!regex.test('.css') || use === 'null-loader') return rule
84
85
 
85
86
  return {
86
87
  ...rule,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@s-ui/bundler",
3
- "version": "8.0.0-beta.0",
3
+ "version": "8.0.0-beta.1",
4
4
  "description": "Config-free bundler for ES6 React apps.",
5
5
  "bin": {
6
6
  "sui-bundler": "./bin/sui-bundler.js"
@@ -21,30 +21,32 @@
21
21
  },
22
22
  "homepage": "https://github.com/SUI-Components/sui/tree/master/packages/sui-bundler#readme",
23
23
  "dependencies": {
24
- "@babel/core": "7.12.10",
24
+ "@babel/core": "7.16.0",
25
25
  "@s-ui/helpers": "1",
26
- "autoprefixer": "9.8.6",
27
- "babel-loader": "8.2.2",
26
+ "@s-ui/sass-loader": "1",
27
+ "autoprefixer": "10.4.0",
28
+ "babel-loader": "8.2.3",
28
29
  "babel-preset-sui": "3",
29
- "chalk": "4.1.0",
30
30
  "commander": "6.2.1",
31
- "css-loader": "4.3.0",
32
- "css-minimizer-webpack-plugin": "1.1.5",
33
- "fast-glob": "3.2.4",
34
- "fibers": "5.0.0",
35
- "get-port": "5.1.1",
36
- "html-webpack-plugin": "4.5.0",
37
- "mini-css-extract-plugin": "1.3.3",
31
+ "css-loader": "6.5.1",
32
+ "css-minimizer-webpack-plugin": "3.1.1",
33
+ "esbuild-loader": "2.16.0",
34
+ "fast-glob": "3.2.7",
35
+ "html-webpack-plugin": "5.5.0",
36
+ "mini-css-extract-plugin": "2.4.4",
38
37
  "null-loader": "4.0.1",
39
- "postcss": "7.0.35",
40
- "postcss-loader": "4.1.0",
38
+ "process": "0.11.10",
39
+ "postcss": "8.3.11",
40
+ "postcss-loader": "6.2.0",
41
+ "react-dev-utils": "11.0.4",
41
42
  "rimraf": "3.0.2",
42
- "sass": "1.30.0",
43
- "sass-loader": "10.1.0",
44
- "style-loader": "2.0.0",
45
- "webpack": "5.10.1",
46
- "webpack-manifest-plugin": "3.0.0",
47
- "webpack-node-externals": "2.5.2",
48
- "webpack-plugin-serve": "1.2.1"
43
+ "sass": "1.43.4",
44
+ "speed-measure-webpack-plugin": "1.5.0",
45
+ "style-loader": "3.3.1",
46
+ "terser-webpack-plugin": "5.2.4",
47
+ "webpack": "5.61.0",
48
+ "webpack-dev-server": "4.4.0",
49
+ "webpack-manifest-plugin": "4.0.2",
50
+ "webpack-node-externals": "3.0.0"
49
51
  }
50
52
  }
package/shared/config.js CHANGED
@@ -7,5 +7,7 @@ const {'sui-bundler': config = {}} = packageJsonConfig
7
7
  const {extractComments, sourcemaps} = config
8
8
 
9
9
  exports.config = config
10
+ exports.useExperimentalMinifier =
11
+ config.optimizations && config.optimizations.useExperimentalMinifier
10
12
  exports.extractComments = extractComments || false
11
13
  exports.sourceMap = (sourcemaps && sourcemaps.prod) || false
@@ -1,3 +1,5 @@
1
+ // from: https://github.com/facebook/create-react-app/blob/main/packages/react-dev-utils/InlineChunkHtmlPlugin.js
2
+
1
3
  /**
2
4
  * Copyright (c) 2015-present, Facebook, Inc.
3
5
  *
package/shared/log.js CHANGED
@@ -1,11 +1,10 @@
1
1
  /* eslint-disable no-console */
2
-
3
- const chalk = require('chalk')
2
+ const colors = require('@s-ui/helpers/colors')
4
3
 
5
4
  module.exports = {
6
- info: msg => console.log(chalk.white(msg)),
7
- error: msg => console.log(chalk.red(msg)),
8
- success: msg => console.log(chalk.green(msg)),
9
- warn: msg => console.log(chalk.yellow(msg)),
10
- processing: msg => console.log(chalk.blue(msg))
5
+ info: msg => console.log(colors.gray(msg)),
6
+ error: msg => console.log(colors.red(msg)),
7
+ success: msg => console.log(colors.green(msg)),
8
+ warn: msg => console.log(colors.yellow(msg)),
9
+ processing: msg => console.log(colors.cyan(msg))
11
10
  }
@@ -1,6 +1,6 @@
1
1
  const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
2
2
 
3
- module.exports = () =>
3
+ const createCssMinimizerPlugin = () =>
4
4
  new CssMinimizerPlugin({
5
5
  minimizerOptions: {
6
6
  preset: [
@@ -11,3 +11,5 @@ module.exports = () =>
11
11
  ]
12
12
  }
13
13
  })
14
+
15
+ module.exports = () => createCssMinimizerPlugin()
@@ -1,8 +1,9 @@
1
+ const {ESBuildMinifyPlugin} = require('esbuild-loader')
1
2
  const TerserPlugin = require('terser-webpack-plugin')
2
3
  const {CI = false} = process.env
3
4
  const CI_PARALLEL_CORES = 2
4
5
 
5
- module.exports = ({extractComments}) =>
6
+ const terser = ({extractComments, sourceMap}) =>
6
7
  new TerserPlugin({
7
8
  extractComments,
8
9
  terserOptions: {
@@ -43,5 +44,20 @@ module.exports = ({extractComments}) =>
43
44
  // For CI: Use only fixed cores as it gives incorrect info and could cause troubles
44
45
  // Related: https://github.com/webpack-contrib/terser-webpack-plugin/issues/202
45
46
  // If not CI then use os.cpus().length - 1
46
- parallel: CI ? CI_PARALLEL_CORES : true
47
+ parallel: CI ? CI_PARALLEL_CORES : true,
48
+ // Enable file caching
49
+ cache: true,
50
+ // use sourceMap if parameter is provided
51
+ sourceMap: !!sourceMap
47
52
  })
53
+
54
+ const esbuild = ({extractComments, sourceMap}) =>
55
+ new ESBuildMinifyPlugin({
56
+ target: 'es6',
57
+ sourcemap: sourceMap !== 'none' && sourceMap !== false
58
+ })
59
+
60
+ module.exports = ({extractComments, sourceMap, useExperimentalMinifier}) =>
61
+ useExperimentalMinifier
62
+ ? esbuild({extractComments, sourceMap})
63
+ : terser({extractComments, sourceMap})
@@ -8,6 +8,8 @@ module.exports = {
8
8
  {
9
9
  loader: require.resolve('babel-loader'),
10
10
  options: {
11
+ cacheDirectory: true,
12
+ cacheCompression: false,
11
13
  babelrc: false,
12
14
  compact: true,
13
15
  presets: [
@@ -12,6 +12,7 @@ const {PWD} = process.env
12
12
  const defaultPackagesToAlias = [
13
13
  'react',
14
14
  'react-router-dom',
15
+ '@s-ui/pde',
15
16
  '@s-ui/react-context',
16
17
  '@s-ui/react-router'
17
18
  ]
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in https://github.com/facebook/create-react-app/blob/main/packages/react-dev-utils/LICENSE
6
+ */
7
+
8
+ const fs = require('fs')
9
+ const path = require('path')
10
+
11
+ function checkRequiredFiles(files) {
12
+ let currentFilePath
13
+ try {
14
+ files.forEach(filePath => {
15
+ currentFilePath = filePath
16
+ fs.accessSync(filePath, fs.F_OK)
17
+ })
18
+ return true
19
+ } catch (err) {
20
+ const dirName = path.dirname(currentFilePath)
21
+ const fileName = path.basename(currentFilePath)
22
+
23
+ console.log('Could not find a required file:')
24
+ console.log(` Name: ${fileName}`)
25
+ console.log(` Searched in: ${dirName}`)
26
+
27
+ return false
28
+ }
29
+ }
30
+
31
+ module.exports = checkRequiredFiles
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in https://github.com/facebook/create-react-app/blob/main/packages/react-dev-utils/LICENSE
6
+ */
7
+
8
+ function clearConsole() {
9
+ process.stdout.write(
10
+ process.platform === 'win32' ? '\x1B[2J\x1B[0f' : '\x1B[2J\x1B[3J\x1B[H'
11
+ )
12
+ }
13
+
14
+ module.exports = clearConsole