@raisenow/tamaro-cli 1.0.4 → 1.0.8

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 ADDED
@@ -0,0 +1,201 @@
1
+ # Getting started
2
+
3
+ It's a command-line interface for all operations with Tamaro customer configurations and *Tamaro Core*.
4
+
5
+ You don't need to install it manually. The recommended way is to run it using `npx` command, which must be available along with `node` and `npm` commands.
6
+
7
+ # Usage
8
+
9
+ To see an overview of all possible commands just run the following command without any arguments:
10
+
11
+ ```bash
12
+ npx -y @raisenow/tamaro-cli
13
+ ```
14
+
15
+ To see the info about some particular command (for example `dev` command), prepend `help` before the command name:
16
+
17
+ ```bash
18
+ npx -y @raisenow/tamaro-cli help dev
19
+ ```
20
+
21
+ Substitute `dev` with the command you want to get info about.
22
+
23
+ # Commands
24
+
25
+ Available commands:
26
+ - [dev](#dev)
27
+ - [build](#build)
28
+ - [deploy](#deploy)
29
+ - [serve](#serve)
30
+
31
+ ## dev
32
+
33
+ Runs development web-server for *Tamaro Core* or particular customer configuration.
34
+
35
+ Options:
36
+ - `--local-core` – Load *Tamaro Core* from localhost instead of CDN
37
+
38
+ ### Run development web-server using Tamaro Core from CDN
39
+
40
+ Run development web-server for `example-02-typical-customisations` customer configuration.
41
+
42
+ After running this command, development web-server should be running on http://localhost:1234/ (port may differ).
43
+
44
+ ```bash
45
+ cd /path/to/tamaro-configurations/configs/example-02-typical-customisations
46
+ npx -y @raisenow/tamaro-cli dev
47
+ ```
48
+
49
+ ### Run development web-server using locally running Tamaro Core
50
+
51
+ 1. Run development web-server for *Tamaro Core* in the first terminal tab.
52
+
53
+ After running this command, development web-server should be running on http://localhost:1234/ (port may differ).
54
+
55
+ ```bash
56
+ cd /path/to/tamaro-core
57
+ npx -y @raisenow/tamaro-cli dev
58
+ ```
59
+
60
+ 2. Run development web-server for `example-02-typical-customisations` customer configuration in the second terminal tab.
61
+
62
+ After running this command, development web-server should be running on http://localhost:1235/ (port may differ).
63
+
64
+ ```bash
65
+ cd /path/to/tamaro-configurations/configs/example-02-typical-customisations
66
+ npx -y @raisenow/tamaro-cli dev --local-core
67
+ ```
68
+
69
+ ## build
70
+
71
+ Build optimised (minified) bundle of *Tamaro Core* or customer configuration for production.
72
+
73
+ Options:
74
+ - `--local-core` – Load *Tamaro Core* from localhost instead of CDN
75
+ - `--analyze` – Generate bundle statistics to `reports` folder
76
+ - `--deploy` – Deploy *Tamaro Core* or customer configuration bundle to AWS
77
+ - `--serve` – Run web-server for the bundle
78
+ - `--tag <tag>` – Tag which will be used for deployment of the bundle
79
+
80
+ Before trying to deploy a bundle, make sure you have proper AWS credentials in your environment, otherwise deployment will fail.
81
+ More info about configuring AWS credentials and profiles is in the [wiki page](https://raisenow.atlassian.net/wiki/spaces/DEVOPS/pages/3201731220).
82
+
83
+ ### Build and deploy customer configuration
84
+
85
+ Build and deploy optimised (minified) bundle of `example-02-typical-customisations` customer configuration.
86
+
87
+ ```bash
88
+ cd /path/to/tamaro-configurations/configs/example-02-typical-customisations
89
+ npx -y @raisenow/tamaro-cli build --deploy
90
+ ```
91
+
92
+ As a result bundle should be deployed to: https://tamaro.raisenow.com/example-02-typical-customisations/latest/index.html
93
+
94
+ ### Build and deploy customer configuration with a specific tag
95
+
96
+ Build and deploy optimised (minified) bundle of `example-02-typical-customisations` customer configuration with `WEB-123` tag.
97
+
98
+ ```bash
99
+ cd /path/to/tamaro-configurations/configs/example-02-typical-customisations
100
+ npx -y @raisenow/tamaro-cli build --deploy --tag WEB-123
101
+ ```
102
+
103
+ As a result bundle should be deployed to: https://tamaro.raisenow.com/example-02-typical-customisations/WEB-123/index.html
104
+
105
+ ### Build and serve customer configuration
106
+
107
+ Build and serve optimised (minified) bundle of `example-02-typical-customisations` customer configuration.
108
+
109
+ After running this command, web-server should be running on http://localhost:1234/ (port may differ).
110
+
111
+ ```bash
112
+ cd /path/to/tamaro-configurations/configs/example-02-typical-customisations
113
+ npx -y @raisenow/tamaro-cli build --serve
114
+ ```
115
+
116
+
117
+ ## deploy
118
+
119
+ Deploy prebuilt Tamaro Core or customer configuration bundle to AWS.
120
+
121
+ Options:
122
+ - `--tag <tag>` – Tag which will be used for deployment of the bundle
123
+
124
+ Make sure you have built the bundle before deploying it with this command, otherwise you may mistakenly deploy the bundle from previous build.
125
+
126
+ Example:
127
+
128
+ 1. Build optimised (minified) bundle of `example-02-typical-customisations` customer configuration.
129
+
130
+ ```bash
131
+ cd /path/to/tamaro-configurations/configs/example-02-typical-customisations
132
+ npx -y @raisenow/tamaro-cli build
133
+ ```
134
+
135
+ 2. Deploy it:
136
+
137
+ ```bash
138
+ npx -y @raisenow/tamaro-cli deploy
139
+ ```
140
+
141
+ 3. Optionally deploy it with `WEB-123` tag:
142
+
143
+ ```bash
144
+ npx -y @raisenow/tamaro-cli deploy --tag WEB-123
145
+ ```
146
+
147
+ ## serve
148
+
149
+ Run web-server for prebuilt bundle.
150
+
151
+ Example:
152
+
153
+ 1. Build optimised (minified) bundle of `example-02-typical-customisations` customer configuration.
154
+
155
+ ```bash
156
+ cd /path/to/tamaro-configurations/configs/example-02-typical-customisations
157
+ npx -y @raisenow/tamaro-cli build
158
+ ```
159
+
160
+ 2. Serve it.
161
+
162
+ After running this command, web-server should be running on http://localhost:1234/ (port may differ).
163
+
164
+ ```bash
165
+ npx -y @raisenow/tamaro-cli serve
166
+ ```
167
+
168
+
169
+ # Development
170
+
171
+ Make sure you have installed and activated proper `node` and `npm` versions.
172
+
173
+ - `node: ">= 16"`
174
+ - `npm: ">= 8"`
175
+
176
+ Clone the repo and install its dependencies:
177
+
178
+ ```bash
179
+ git clone git@bitbucket.org:raisenow/tamaro-cli.git
180
+ cd tamaro-cli
181
+ npm ci
182
+ ```
183
+
184
+ Link package source to be able to run its local version:
185
+
186
+ ```bash
187
+ npm link .
188
+ ```
189
+
190
+ Run the `dev` script to watch source files and automatically rebuild on changes.
191
+ It must be running during *Tamaro CLI* development process.
192
+
193
+ ```bash
194
+ npm run dev
195
+ ```
196
+
197
+ To use local linked version of *Tamaro CLI*, use it without `@raisenow/` scope, `-y` flag is also not needed:
198
+
199
+ ```bash
200
+ npx tamaro-cli dev
201
+ ```
Binary file
package/src/cli.ts CHANGED
@@ -29,20 +29,25 @@ const cli = createCommand().name(pkg.name).version(pkg.version, '-v, --version')
29
29
 
30
30
  cli
31
31
  .command('dev')
32
- .description('Run dev server for Tamaro core or customer configuration')
33
- .option('--local-core', 'Load tamaro-core from localhost instead of CDN')
32
+ .description('Run dev web-server for Tamaro Core or customer configuration')
33
+ .option('--local-core', 'Load Tamaro Core from localhost instead of CDN')
34
34
  .action(async (options: DevOptions) => {
35
35
  await dev(options)
36
36
  })
37
37
 
38
38
  cli
39
39
  .command('build')
40
- .description('Build Tamaro core or customer configuration for production')
41
- .option('--analyze', 'Generate some build stats to "reports" folder')
42
- .option('--deploy', 'Deploy to AWS')
43
- .option('--latest', 'Deploy with tag "latest"')
44
- .option('--serve', 'Run web-server for previously created build')
45
- .option('--tag <tag>', 'Deploy widget with a specific tag')
40
+ .description(
41
+ 'Build optimised (minified) bundle of Tamaro Core or customer configuration for production',
42
+ )
43
+ .option('--local-core', 'Load Tamaro Core from localhost instead of CDN')
44
+ .option('--analyze', 'Generate bundle statistics to "reports" folder')
45
+ .option(
46
+ '--deploy',
47
+ 'Deploy Tamaro Core or customer configuration bundle to AWS',
48
+ )
49
+ .option('--serve', 'Run web-server for the bundle')
50
+ .option('--tag <tag>', 'Tag which will be used for deployment of the bundle')
46
51
  .action(async (options: BuildOptions) => {
47
52
  await build(options)
48
53
 
@@ -57,16 +62,17 @@ cli
57
62
 
58
63
  cli
59
64
  .command('deploy')
60
- .description('Deploy Tamaro core or customer configuration to AWS')
61
- .option('--latest', 'Deploy with tag "latest"')
62
- .option('--tag <tag>', 'Deploy widget with a specific tag')
65
+ .description(
66
+ 'Deploy prebuilt Tamaro Core or customer configuration bundle to AWS',
67
+ )
68
+ .option('--tag <tag>', 'Tag which will be used for deployment of the bundle')
63
69
  .action(async (options: DeployOptions) => {
64
70
  await deploy(options)
65
71
  })
66
72
 
67
73
  cli
68
74
  .command('serve')
69
- .description('Run web-server for previously created build')
75
+ .description('Run web-server for prebuilt bundle')
70
76
  .action(async () => {
71
77
  await serve()
72
78
  })
@@ -5,9 +5,9 @@ import resolveBin from 'resolve-bin'
5
5
  ///////////////////////////////////////////////////////////////////////////////
6
6
 
7
7
  export type BuildOptions = {
8
+ localCore?: boolean
8
9
  analyze?: boolean
9
10
  deploy?: boolean
10
- latest?: boolean
11
11
  tag?: string
12
12
  serve?: boolean
13
13
  }
@@ -15,9 +15,10 @@ export type BuildOptions = {
15
15
  ///////////////////////////////////////////////////////////////////////////////
16
16
 
17
17
  const prepareBuildFlags = (options: BuildOptions): string => {
18
- const {analyze} = options
18
+ const {localCore, analyze} = options
19
19
  let flags: string[] = []
20
20
 
21
+ flags = localCore ? [...flags, '--env localCore'] : flags
21
22
  flags = analyze ? [...flags, '--env analyze'] : flags
22
23
 
23
24
  return flags.join(' ')
@@ -4,7 +4,6 @@ import {getIfCoreFns, getPaths, logCommand} from 'lib/helpers'
4
4
  ///////////////////////////////////////////////////////////////////////////////
5
5
 
6
6
  export type DeployOptions = {
7
- latest?: boolean
8
7
  tag?: string
9
8
  }
10
9
 
@@ -13,7 +12,7 @@ export type DeployOptions = {
13
12
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
14
13
  export const deploy = async (options: DeployOptions): Promise<void> => {
15
14
  // todo: ensure build exists
16
- // todo: handle "tag" and "latest" options
15
+ // todo: handle "tag" option
17
16
  // todo: implement
18
17
  const {ifCore} = getIfCoreFns()
19
18
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -6,7 +6,7 @@ import {getIfCoreFns, getPaths, logCommand} from 'lib/helpers'
6
6
  export const serve = async (): Promise<void> => {
7
7
  const {ifCore} = getIfCoreFns()
8
8
  const paths = getPaths(ifCore)
9
- const cmd = `npx http-server ${paths.appDist} --cors`
9
+ const cmd = `npx -y http-server ${paths.appDist} --cors --port 1234`
10
10
  logCommand(cmd)
11
11
  commandSync(cmd, {stdio: 'inherit'})
12
12
  }
@@ -5,8 +5,8 @@ import {notify as nodeNotify} from 'node-notifier'
5
5
  import {getIfUtils, IfUtils, IfUtilsFn} from 'webpack-config-utils'
6
6
  import columnify from 'columnify'
7
7
  import boxen from 'boxen'
8
- import dotenvExpand from 'dotenv-expand'
9
- import dotenv from 'dotenv'
8
+ import {expand as dotenvExpand} from 'dotenv-expand'
9
+ import {config as dotenvConfig} from 'dotenv'
10
10
  import stripIndent from 'strip-indent'
11
11
 
12
12
  ///////////////////////////////////////////////////////////////////////////////
@@ -141,7 +141,7 @@ export const getEnvVars = (
141
141
  ifCore: IfUtilsFn,
142
142
  ifLocalCore: IfUtilsFn,
143
143
  ) => {
144
- dotenvExpand(dotenv.config({path: filePath}))
144
+ dotenvExpand(dotenvConfig({path: filePath}))
145
145
 
146
146
  process.env.NODE_ENV ??= ifMin('production', 'development')
147
147
  process.env.BABEL_ENV ??= ifMin('production', 'development')
@@ -170,7 +170,7 @@ export const getEnvVars = (
170
170
  process.env.WIDGET_UUID = getWidgetUuid()
171
171
 
172
172
  if (ifLocalCore()) {
173
- process.env.CORE_URL = `http://0.0.0.0:8080/index.js`
173
+ process.env.CORE_URL = `http://0.0.0.0:1234/index.js`
174
174
  } else {
175
175
  let version = process.env.CORE_VERSION
176
176
  version = version ? `@${version}` : ''
@@ -273,8 +273,7 @@ export const notify = (args: NotifyArgs): void => {
273
273
  nodeNotify({
274
274
  title,
275
275
  message,
276
- // __dirname is "dist" in runtime
277
- contentImage: resolveOwn('src/assets/rnw-logo.jpg'),
276
+ contentImage: resolveOwn('src/assets/rnw-logo.png'),
278
277
  sound: 'Funk',
279
278
  })
280
279
  }
@@ -8,6 +8,7 @@ import webpack, {
8
8
  ProgressPlugin,
9
9
  RuleSetUseItem,
10
10
  } from 'webpack'
11
+ import {getPortPromise} from 'portfinder'
11
12
  import {TsconfigPathsPlugin} from 'tsconfig-paths-webpack-plugin'
12
13
  import {CleanWebpackPlugin} from 'clean-webpack-plugin'
13
14
  import HtmlWebpackPlugin from 'html-webpack-plugin'
@@ -28,6 +29,7 @@ import {
28
29
  getPaths,
29
30
  logDataTable,
30
31
  moduleFileExtensions,
32
+ resolveApp,
31
33
  resolveOwn,
32
34
  } from 'lib/helpers'
33
35
 
@@ -47,6 +49,7 @@ const getWebpackConfig = async (env: any): Promise<Configuration> => {
47
49
  const appHtmlFiles = glob.sync(paths.appHtml)
48
50
  const envVars = getEnvVars(paths.appEnv, ifMin, ifCore, ifLocalCore)
49
51
  const {ifHmr} = getIfUtils({hmr: process.env.HMR_ENABLED === 'true'}, ['hmr'])
52
+ const port = await getPortPromise({port: 1234})
50
53
 
51
54
  logDataTable(paths, 'Paths')
52
55
  logDataTable(envVars.raw, 'Environment variables')
@@ -67,7 +70,6 @@ const getWebpackConfig = async (env: any): Promise<Configuration> => {
67
70
  options: {
68
71
  sourceMap: ifNotMin(),
69
72
  importLoaders: 3,
70
- esModule: false,
71
73
  ...cssOptions,
72
74
  },
73
75
  },
@@ -114,7 +116,6 @@ const getWebpackConfig = async (env: any): Promise<Configuration> => {
114
116
  pathinfo: false,
115
117
  filename: ifCore('index.js', 'widget.js'),
116
118
  chunkFilename: ifMin('[name]-[contenthash:16].js', '[name].js'),
117
- // assetModuleFilename: ifMin('assets/[name]-[contenthash:16][ext]', 'assets/[name][ext]'),
118
119
  assetModuleFilename: 'assets/[name]-[contenthash:16][ext]',
119
120
  crossOriginLoading: 'anonymous',
120
121
  uniqueName: process.env.WEBPACK_UNIQUE_NAME,
@@ -142,151 +143,173 @@ const getWebpackConfig = async (env: any): Promise<Configuration> => {
142
143
  use: require.resolve('source-map-loader'),
143
144
  }),
144
145
 
145
- // Javascript and Typescript (Babel)
146
146
  {
147
- test: /\.(js|ts)x?$/,
148
- exclude: /node_modules/,
149
- loader: require.resolve('babel-loader'),
150
- options: {
151
- babelrc: false,
152
- configFile: false,
153
- sourceMaps: ifNotMin(),
154
- inputSourceMap: ifNotMin(),
155
- presets: removeEmpty([
156
- require.resolve('@babel/preset-env'),
157
- [
158
- require.resolve('@babel/preset-typescript'),
159
- {
160
- allowDeclareFields: true,
147
+ oneOf: [
148
+ // App Javascript and Typescript (Babel)
149
+ // and some dependencies distributed in a non-es5 formats
150
+ {
151
+ test: /\.(js|ts)x?$/,
152
+ include: ifCore(
153
+ [
154
+ resolveApp('src'),
155
+ resolveApp('node_modules/micromark'),
156
+ resolveApp('node_modules/decode-named-character-reference'),
157
+ ],
158
+ [resolveApp('.'), resolveApp('../../src')],
159
+ ),
160
+
161
+ loader: require.resolve('babel-loader'),
162
+ options: {
163
+ babelrc: false,
164
+ configFile: false,
165
+ sourceMaps: ifNotMin(),
166
+ inputSourceMap: ifNotMin(),
167
+ presets: [
168
+ require.resolve('@babel/preset-env'),
169
+ [
170
+ require.resolve('@babel/preset-typescript'),
171
+ {
172
+ allowDeclareFields: true,
173
+ },
174
+ ],
175
+ require.resolve('@babel/preset-react'),
176
+ ],
177
+ plugins: removeEmpty([
178
+ [
179
+ require.resolve('@babel/plugin-transform-runtime'),
180
+ {
181
+ corejs: {
182
+ version: 3,
183
+ proposals: true,
184
+ },
185
+ absoluteRuntime: dirname(
186
+ require.resolve('@babel/runtime-corejs3/package.json'),
187
+ ),
188
+ },
189
+ ],
190
+ [
191
+ require.resolve('@babel/plugin-proposal-decorators'),
192
+ {
193
+ legacy: true,
194
+ },
195
+ ],
196
+ require.resolve('@babel/plugin-syntax-dynamic-import'),
197
+ require.resolve('babel-plugin-lodash'),
198
+ ifHmr(require.resolve('react-refresh/babel')),
199
+ ]),
200
+ },
201
+ },
202
+
203
+ // Other Javascript (not in app) - no transformation
204
+ {
205
+ test: /\.(js|mjs)$/,
206
+ },
207
+
208
+ // Styles (not modules)
209
+ {
210
+ test: /\.s?css$/,
211
+ exclude: /\.module\.s?css$/,
212
+ use: getCssLoaders({
213
+ modules: false,
214
+ }),
215
+ },
216
+
217
+ // Styles (modules)
218
+ {
219
+ test: /\.module\.s?css$/,
220
+ use: getCssLoaders({
221
+ modules: {localIdentName: '[local]__[hash:base64]'},
222
+ }),
223
+ },
224
+
225
+ // SVG (in HTML and styles)
226
+ {
227
+ test: /\.svg$/,
228
+ issuer: [/\.html$/, /\.s?css$/],
229
+ type: 'asset',
230
+ parser: {
231
+ dataUrlCondition: {
232
+ maxSize: imageInlineSizeLimit,
161
233
  },
162
- ],
163
- require.resolve('@babel/preset-react'),
164
- ]),
165
- plugins: removeEmpty([
166
- [
167
- require.resolve('@babel/plugin-transform-runtime'),
234
+ },
235
+ },
236
+
237
+ // SVG (in components)
238
+ {
239
+ test: /\.svg$/,
240
+ issuer: [/\.(ts|tsx|js|jsx|md|mdx)$/],
241
+ use: [
168
242
  {
169
- corejs: {
170
- version: 3,
171
- proposals: true,
243
+ loader: require.resolve('@svgr/webpack'),
244
+ options: {
245
+ svgoConfig: {
246
+ plugins: [
247
+ {
248
+ removeHiddenElems: false,
249
+ moveGroupAttrsToElems: false,
250
+ collapseGroups: false,
251
+ },
252
+ ],
253
+ },
254
+ prettier: false,
255
+ titleProp: true,
256
+ ref: true,
172
257
  },
173
- absoluteRuntime: dirname(
174
- require.resolve('@babel/runtime-corejs3/package.json'),
175
- ),
176
258
  },
177
- ],
178
- [
179
- require.resolve('@babel/plugin-proposal-decorators'),
180
259
  {
181
- legacy: true,
260
+ loader: require.resolve('url-loader'),
261
+ options: {
262
+ name: 'assets/[name]-[contenthash:16].[ext]',
263
+ limit: imageInlineSizeLimit,
264
+ },
182
265
  },
183
266
  ],
184
- require.resolve('@babel/plugin-syntax-dynamic-import'),
185
- require.resolve('babel-plugin-lodash'),
186
- ifHmr(require.resolve('react-refresh/babel')),
187
- ]),
188
- },
189
- },
190
-
191
- // Styles (not modules)
192
- {
193
- test: /\.s?css$/,
194
- exclude: /\.module\.s?css$/,
195
- use: getCssLoaders({
196
- modules: false,
197
- }),
198
- },
199
-
200
- // Styles (modules)
201
- {
202
- test: /\.module\.s?css$/,
203
- use: getCssLoaders({
204
- modules: {localIdentName: '[local]__[hash:base64]'},
205
- }),
206
- },
207
-
208
- // SVG (in HTML)
209
- {
210
- test: /\.svg$/,
211
- issuer: /\.html$/,
212
- type: 'asset',
213
- parser: {
214
- dataUrlCondition: {
215
- maxSize: imageInlineSizeLimit,
216
267
  },
217
- },
218
- },
219
268
 
220
- // SVG (in components)
221
- {
222
- test: /\.svg$/,
223
- issuer: {
224
- not: [/\.html$/],
225
- },
226
- use: [
269
+ // Images and fonts
227
270
  {
228
- loader: require.resolve('@svgr/webpack'),
229
- options: {
230
- svgoConfig: {
231
- plugins: [
232
- {
233
- removeHiddenElems: false,
234
- moveGroupAttrsToElems: false,
235
- collapseGroups: false,
236
- },
237
- ],
271
+ test: /\.(png|jpe?g|webp|gif|ico|ttf|eot|woff2?)$/,
272
+ type: 'asset',
273
+ parser: {
274
+ dataUrlCondition: {
275
+ maxSize: imageInlineSizeLimit,
238
276
  },
239
277
  },
240
278
  },
279
+
280
+ // YML
241
281
  {
242
- loader: require.resolve('url-loader'),
282
+ test: /\.ya?ml$/,
283
+ use: [
284
+ {loader: require.resolve('json-loader')},
285
+ {loader: require.resolve('yaml-loader')},
286
+ ],
287
+ },
288
+
289
+ // HTML
290
+ {
291
+ test: /\.html$/,
292
+ loader: require.resolve('html-loader'),
243
293
  options: {
244
- // name: ifMin(
245
- // 'assets/[name]-[contenthash:16].[ext]',
246
- // 'assets/[name].[ext]'
247
- // ),
248
- name: 'assets/[name]-[contenthash:16].[ext]',
249
- limit: imageInlineSizeLimit,
294
+ minimize: false,
250
295
  },
251
296
  },
252
- ],
253
- },
254
297
 
255
- // Images and fonts
256
- {
257
- test: /\.(png|jpe?g|webp|gif|ico|ttf|eot|woff2?)$/,
258
- type: 'asset',
259
- parser: {
260
- dataUrlCondition: {
261
- maxSize: imageInlineSizeLimit,
298
+ // All other files - fallback
299
+ // This must be the latest rule!
300
+ {
301
+ exclude: [/^$/, /\.(js|jsx|ts|tsx|mjs)$/, /\.html$/, /\.json$/],
302
+ type: 'asset/resource',
262
303
  },
263
- },
264
- },
265
-
266
- // YML
267
- {
268
- test: /\.ya?ml$/,
269
- use: [
270
- {loader: require.resolve('json-loader')},
271
- {loader: require.resolve('yaml-loader')},
272
304
  ],
273
305
  },
274
-
275
- // HTML
276
- {
277
- test: /\.html$/,
278
- loader: require.resolve('html-loader'),
279
- options: {
280
- esModule: false,
281
- minimize: false,
282
- },
283
- },
284
306
  ]),
285
307
  },
286
308
 
287
309
  devtool: ifMin(false, 'cheap-module-source-map'),
288
310
 
289
311
  devServer: {
312
+ port,
290
313
  static: false,
291
314
  historyApiFallback: {
292
315
  disableDotRule: true,
Binary file