@studyportals/webpack-helper 7.0.0-3 → 7.0.1-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/README.md CHANGED
@@ -1,329 +1,316 @@
1
- # WebpackHelper
2
-
3
- WebpackHelper is a utility that makes it easy to set up a webpack configuration for Studyportals' projects that adhere to our [Webpack quality criteria](https://knowledge-vault.studyportals.xyz/quality-standards/front-end/webpack-quality-criteria.html).
4
-
5
- ## Table of Contents
6
-
7
- - [Webpack version](#webpack-version)
8
- - [Notes on updating Webpack from v4 to v5](#notes-on-updating-webpack-from-v4-to-v5)
9
- - [Quick Start](#quick-start)
10
- - [Chunks Retry](#chunks-retry)
11
- - [Defaults](#defaults)
12
- - [Setup](#setup)
13
- - [Limitations](#limitations)
14
- - [Configuration](#configuration)
15
- - [entry](#entry-required)
16
- - [output](#output-required)
17
- - [preset](#preset)
18
- - [bob](#bob)
19
- - [common](#common)
20
- - [staticPath](#staticpath-required)
21
- - [development](#development)
22
- - [production](#production)
23
- - [Presets](#presets)
24
- - [javascript](#javascript)
25
- - [typescript](#typescript)
26
- - [vue-typescript](#vue-typescript)
27
- - [DoD compliance with Babel and Browserslist](#dod-compliance-with-babel-and-browserslist)
28
-
29
- ## Webpack version
30
-
31
- This version of WebpackHelper is based on webpack 5. Some earlier WebpackHelper versions used earlier versions of Webpack. If you get syntax errors when updating to the latest version of WebpackHelper, please check out the [Webpack documentation](https://webpack.js.org/configuration/).
32
-
33
- ### Notes on updating Webpack from v4 to v5
34
-
35
- Below are some notes that might be helpful when you're upgrading a microservice from webpack-helper v2 (based on Webpack v4) to v3 (based on Webpack v5).
36
-
37
- #### Exporting
38
-
39
- Webpack-helper **v2 and below**: Your `webpack.config.js` file ended with the following:
40
-
41
- ```javascript
42
- module.exports = mode => configuration.get(mode);
43
- ```
44
-
45
- Webpack-helper **v3 and beyond**: Your `webpack.config.js` file should end with the following (as is also mentioned further below):
46
-
47
- ```javascript
48
- module.exports = (env, details) => configuration.get(details.mode);
49
- ```
50
-
51
- ## Quick Start
52
-
53
- ```bash
54
- npm i -D @studyportals/webpack-helper
55
- ```
56
-
57
- After installation, getting started is quite easy. Just set up a `webpack.config.js` file in the root of your project, require Webpack Helper and set up a configuration using it's `create` method like so:
58
-
59
- ```javascript
60
- const path = require('path');
61
- const WebpackHelper = require("@studyportals/webpack-helper");
62
-
63
- const configuration = WebpackHelper.create({
64
- entry: [
65
- "./src/main.ts"
66
- ],
67
- output: {
68
- path: path.resolve(__dirname, './dist'),
69
- fileName: 'bundle',
70
- hash: true,
71
- // Use this if you want to control hashing for js and css separately
72
- hash: {
73
- js: true,
74
- css: false
75
- }
76
- },
77
- preset: "vue-typescript",
78
- bob: {
79
- name: 'MicroService',
80
- html: '<div id=\"MicroServicePlaceholder\"></div>',
81
- baseURL: '/dist',
82
- defer: ['style'],
83
- dllPackages: [
84
- {
85
- name: "package-dll",
86
- manifest: require("@studyportals/package-dll/dist/manifest.json")
87
- }
88
- ]
89
- },
90
- common: {
91
- //any config
92
- },
93
- //needed for webpack-dev-server configuration
94
- staticPath: path.join(__dirname, "."),
95
- production: {
96
- //any config
97
- }
98
- });
99
- ```
100
-
101
- When your configuration is created you can get an instance of it for the correct environment and export it for webpack to use like so:
102
-
103
- ```javascript
104
- module.exports = (env, details) => configuration.get(details.mode);
105
- ```
106
-
107
- ## Chunks Retry
108
-
109
- Webpack Helpers has a default configuration to retry chunks which cannot get loaded on the first try (for whatever reason, network or otherwise).
110
-
111
- It has an Exponential Backoff to calculate the delay between retries of a maximum of `2` seconds.
112
-
113
- The functionality is implemented thru a plugin called `webpack-retry-chunk-load-plugin` <https://www.npmjs.com/package/webpack-retry-chunk-load-plugin>.
114
-
115
- ### Defaults
116
-
117
- By default it is enabled if the selected preset is `vue-typescript` and it uses `6` as the number of retries it does and it uses the `rollbar` instance on the `window` object (Portal instance) to log an error when it reaches the threshold of retries without being able to load the chunk (`new Error('Failed to load chunk for after retries')`).
118
-
119
- ### Setup
120
-
121
- To configure the functionality you can provide an object following this interface
122
-
123
- ```js
124
- interface IChunksRetryPluginConfig {
125
- inject: boolean; //if you want the plugin injected
126
-
127
- threshold: number; //amount of retries
128
-
129
- thresholdReachedCallBack?: string; //a function (body of it as string) to be called when the amount of retries has been exhausted
130
-
131
- rollbarInstanceIdentifier?: string; //a key of a Rollbar instance present on the 'window' object e.g if you want to use window['rollbar_PQ'] to track the error in the Profile Questionnaire project in Rollbar then you send 'rollbar_PQ'
132
-
133
- disableDefaultRollbarError?: boolean; //if you don't want to log by default when the threshold has been reached
134
- }
135
- ```
136
-
137
- and you can provide this thru the `webpack` config of your service like so
138
-
139
- ```js
140
- const configuration = WebpackHelper.create({
141
- chunksRetryConfig: {
142
- threshold: 10,
143
- thresholdReachedCallBack: `console.log("hello")`,
144
- },
145
- ...
146
- ```
147
-
148
- ### Limitations
149
-
150
- We have some limitations in this implementation based on the plugin we used and that the code will be part of the webpack exported code
151
-
152
- ### Only use ES5
153
-
154
- You can only write ES5 code inside the `thresholdReachedCallBack`
155
-
156
- ### String as function
157
-
158
- The function `thresholdReachedCallBack` must be a string (aka the body of the function) and we cannot change that to be a function while retaining the simplicity of the code.
159
-
160
- ## Configuration
161
-
162
- Webpack Helper offers a compact but flexible configuration interface. Below you will find every option available.
163
-
164
- ### entry **(required)**
165
-
166
- The entrypoint for your webpack bundle. This can either be configured as an object with the bundle name as a key and the path as a value or as an array of paths if your project requires multiple entry points.
167
-
168
- ```javascript
169
- entry: [
170
- "./src/main.ts"
171
- ]
172
-
173
- //or
174
-
175
- entry: {
176
- bundle: "./src/main.ts"
177
- }
178
- ```
179
-
180
- ### Working with packaged components & libraries
181
-
182
- When working with packaged components and libraries it is required to keep the bundle name in line with the major version of the package. This helps to prevent reference issues when multiple versions of a package load on a single page.
183
-
184
- ```javascript
185
- // version 1
186
- entry: {
187
- multiselect_v1: "./src/main.ts"
188
- }
189
-
190
- // version 2
191
- entry: {
192
- multiselect_v2: "./src/main.ts"
193
- }
194
- ```
195
-
196
- #### DLL
197
-
198
- When working with a packaged component as a DLL, both the JS bundle and CSS bundle from the core package must be referenced, as below:
199
-
200
- ```javascript
201
-
202
- entry: {
203
- multiselect_v2: [
204
- '@studyportals/multiselect/dist/multiselect.js',
205
- '@studyportals/multiselect/dist/multiselect.css'
206
- ]
207
- }
208
-
209
- ```
210
-
211
- ### output **(required)**
212
-
213
- The output object has some options that define how your bundle will be output. It has the following properties:
214
-
215
- - `path`**(required)**: The target directory for all output files.
216
- - `library`: The name of the exported library, which will also be used to namespace sourcemaps. This will default to `null`.
217
- - `publicPath`: The url to the output directory resolved relative to the HTML page. This will default to `null`.
218
- - `fileName`: A custom filename for your bundle. This will default to `[name]` which refers to the name you've given your entrypoint.
219
- - `hash`: Whether or not to add build hashes to your filenames. This will default to `true`. Whenever you want different values for your js and css you can pass an object with separate properties and values as in the example below.
220
- - `crossOriginLoading`: Tells webpack to enable cross-origin loading of chunks. Can either be set to `anonymous` or `user-credentials`.
221
-
222
- ```javascript
223
- output: {
224
- path: path.resolve(__dirname, './dist'),
225
- library: 'test-microservice',
226
- publicPath: '/assets/',
227
- fileName: 'application',
228
- crossOriginLoading: 'anonymous',
229
- hash: false,
230
- //or
231
- hash: {
232
- js: true,
233
- css: false
234
- }
235
- }
236
- ```
237
-
238
- ### preset
239
-
240
- The preset property determines which preset to load into your webpack configuration.
241
-
242
- ```javascript
243
- preset: "vue-typescript | typescript | javascript"
244
- ```
245
-
246
- ### bob
247
-
248
- The bob object adds all necessary configuration to have your project generate a manifest file to be used by [Bob](https://github.com/studyportals/Bob).
249
-
250
- - `name`**(required)**: The name of your microservice.
251
- - `html`**(required)**: The HTML that needs to be output by your microservice. Can be a path to a document or a snippet.
252
- - `baseURL`: The baseURL for your microservice assets.
253
- - `async`: An array of JS filenames to be loaded async.
254
- - `defer`: An array of CSS filenames to be lazy-loaded.
255
- - `exclude`: An array of filenames (CSS and JS) that should be excluded from your manifest file.
256
- - `dllPackages`: An array of objects that reference your Dll dependencies. They all require a name and a Dll manifest in the form of a json file.
257
-
258
- ```javascript
259
- bob: {
260
- name: 'MicroService',
261
- html: '<div id=\"MicroServicePlaceholder\"></div>',
262
- baseURL: '/dist',
263
- defer: ['style'],
264
- exclude: ['demo-assets'],
265
- dllPackages: [
266
- {
267
- name: "package-dll",
268
- manifest: require("@studyportals/package-dll/dist/manifest.json")
269
- }
270
- ]
271
- }
272
- ```
273
-
274
- WebpackHelper uses [BobManifestGenerator](https://github.com/studyportals/BobManifestGenerator) to generate a manifest file.
275
-
276
- ### common
277
-
278
- Extra Webpack configuration to be used for all environments can be passed in the `common` object. This configuration needs to adhere to Webpack's configuration interface and will be merged in with the other configuration through [webpack-merge](https://github.com/survivejs/webpack-merge).
279
-
280
- ### staticPath **(required)**
281
-
282
- Your configuration must include the following
283
-
284
- ```javascript
285
- staticPath: path.join(__dirname, "."),
286
- ```
287
-
288
- No Extra configuration is needed for the webpack-dev-server
289
-
290
- ### development
291
-
292
- Extra Webpack configuration to be used for all development builds can be passed in the `development` object. This configuration needs to adhere to Webpack's configuration interface and will be merged in with the other configuration through [webpack-merge](https://github.com/survivejs/webpack-merge).
293
-
294
- **NOTE**: Some default configuration for development builds will be added automatically. Details can be found [here](src/defaults/defaults.md).
295
-
296
- ### production
297
-
298
- Extra Webpack configuration to be used for all production builds can be passed in the `production` object. This configuration needs to adhere to Webpack's configuration interface and will be merged in with the other configuration through [webpack-merge](https://github.com/survivejs/webpack-merge).
299
-
300
- **NOTE**: Some default configuration for production builds will be added automatically. Details can be found [here](src/defaults/defaults.md).
301
-
302
- ## Presets
303
-
304
- In order to make your life as easy as possible, Webpack Helper ships with a set of presets that will take care of putting some essential plugins and loaders in your configuration. The different presets are listed below.
305
-
306
- More in depth information on what configuration these presets will add to your project can be found [here](src/presets/presets.md).
307
-
308
- ### javascript
309
-
310
- The javascript preset will resolve all `.js` and `.json` files and transpiles them with Babel. If your project has styling, it will separate that out in a separate `.css` file.
311
-
312
- ### typescript
313
-
314
- The typescript preset will resolve all `.ts`, `.tsx`, `.js` and `.json` files. It transpiles them using tsc and Babel. Be aware that you will need to include a `tsconfig.json` in your project for it to work properly. If your project has styling, it will separate that out in a separate `.css` file.
315
-
316
- ### vue-typescript
317
-
318
- The vue-typescript preset will resolve all `.vue`, `.ts`, `.tsx`, `.js` and `.json` files. It transpiles them using vue-loader, tsc and Babel. Be aware that you will need to include a `tsconfig.json` in your project for it to work properly. If your project has styling, it will separate that out in a separate `.css` file.
319
-
320
- ## DoD compliance with Babel and Browserslist
321
-
322
- In order to comply to [Studyportals' definition of done](https://knowledge-vault.studyportals.xyz/definitions-of-done/product/) we use `babel` to transpile our front-end code according to the browsers we need to support. To do this your project needs some configuration. When Webpack Helper is installed it will put standard configuration in the root of your project which consists of 2 files:
323
-
324
- - `.babelrc`: A standard configuration for babel that loads the `babel-env` and `babel-typescripts` presets. You might need to add more plugins for your specific project.
325
- - `.browserslistrc`: A configuration file for browserslist. This is used by `babel-env` to determine which browsers to transpile the code for. Within this file the configuration for student facing products will be loaded by default but other configurations can be easily loaded by uncommenting some lines.
326
-
327
- ## Unit testing
328
-
329
- From version `6.0.0` onwards test dependencies are no longer included and should be installed separately. It's also recommended to replace jest with vitest due the complex nature of package jungle. A upgrade guide can be find [here](docs/jest-to-vitest-upgrade-guide.md)
1
+ # WebpackHelper
2
+
3
+ WebpackHelper is a utility that makes it easy to set up a webpack configuration for Studyportals' projects that adhere to our [Webpack quality criteria](https://knowledge-vault.studyportals.xyz/quality-standards/front-end/webpack-quality-criteria.html).
4
+
5
+ ## Table of Contents
6
+
7
+ - [Webpack version](#webpack-version)
8
+ - [Notes on updating Webpack from v4 to v5](#notes-on-updating-webpack-from-v4-to-v5)
9
+ - [Quick Start](#quick-start)
10
+ - [Chunks Retry](#chunks-retry)
11
+ - [Defaults](#defaults)
12
+ - [Setup](#setup)
13
+ - [Limitations](#limitations)
14
+ - [Configuration](#configuration)
15
+ - [entry](#entry-required)
16
+ - [output](#output-required)
17
+ - [preset](#preset)
18
+ - [bob](#bob)
19
+ - [common](#common)
20
+ - [development](#development)
21
+ - [production](#production)
22
+ - [Presets](#presets)
23
+ - [javascript](#javascript)
24
+ - [typescript](#typescript)
25
+ - [vue-typescript](#vue-typescript)
26
+ - [DoD compliance with Babel and Browserslist](#dod-compliance-with-babel-and-browserslist)
27
+
28
+ ## Webpack version
29
+
30
+ This version of WebpackHelper is based on webpack 5. Some earlier WebpackHelper versions used earlier versions of Webpack. If you get syntax errors when updating to the latest version of WebpackHelper, please check out the [Webpack documentation](https://webpack.js.org/configuration/).
31
+
32
+ ### Notes on updating Webpack from v4 to v5
33
+
34
+ Below are some notes that might be helpful when you're upgrading a microservice from webpack-helper v2 (based on Webpack v4) to v3 (based on Webpack v5).
35
+
36
+ #### Exporting
37
+
38
+ Webpack-helper **v2 and below**: Your `webpack.config.js` file ended with the following:
39
+
40
+ ```javascript
41
+ module.exports = mode => configuration.get(mode);
42
+ ```
43
+
44
+ Webpack-helper **v3 and beyond**: Your `webpack.config.js` file should end with the following (as is also mentioned further below):
45
+
46
+ ```javascript
47
+ module.exports = (env, details) => configuration.get(details.mode);
48
+ ```
49
+
50
+ ## Quick Start
51
+
52
+ ```bash
53
+ npm i -D @studyportals/webpack-helper
54
+ ```
55
+
56
+ After installation, getting started is quite easy. Just set up a `webpack.config.js` file in the root of your project, require Webpack Helper and set up a configuration using it's `create` method like so:
57
+
58
+ ```javascript
59
+ const path = require('path');
60
+ const WebpackHelper = require("@studyportals/webpack-helper");
61
+
62
+ const configuration = WebpackHelper.create({
63
+ entry: [
64
+ "./src/main.ts"
65
+ ],
66
+ output: {
67
+ path: path.resolve(__dirname, './dist'),
68
+ fileName: 'bundle',
69
+ hash: true,
70
+ // Use this if you want to control hashing for js and css separately
71
+ hash: {
72
+ js: true,
73
+ css: false
74
+ }
75
+ },
76
+ preset: "vue-typescript",
77
+ bob: {
78
+ name: 'MicroService',
79
+ html: '<div id=\"MicroServicePlaceholder\"></div>',
80
+ baseURL: '/dist',
81
+ defer: ['style'],
82
+ dllPackages: [
83
+ {
84
+ name: "package-dll",
85
+ manifest: require("@studyportals/package-dll/dist/manifest.json")
86
+ }
87
+ ]
88
+ },
89
+ common: {
90
+ //any config
91
+ },
92
+ production: {
93
+ //any config
94
+ }
95
+ });
96
+ ```
97
+
98
+ When your configuration is created you can get an instance of it for the correct environment and export it for webpack to use like so:
99
+
100
+ ```javascript
101
+ module.exports = (env, details) => configuration.get(details.mode);
102
+ ```
103
+
104
+ ## Chunks Retry
105
+
106
+ Webpack Helpers has a default configuration to retry chunks which cannot get loaded on the first try (for whatever reason, network or otherwise).
107
+
108
+ It has an Exponential Backoff to calculate the delay between retries of a maximum of `2` seconds.
109
+
110
+ The functionality is implemented thru a plugin called `webpack-retry-chunk-load-plugin` <https://www.npmjs.com/package/webpack-retry-chunk-load-plugin>.
111
+
112
+ ### Defaults
113
+
114
+ By default it is enabled if the selected preset is `vue-typescript` and it uses `6` as the number of retries it does and it uses the `rollbar` instance on the `window` object (Portal instance) to log an error when it reaches the threshold of retries without being able to load the chunk (`new Error('Failed to load chunk for after retries')`).
115
+
116
+ ### Setup
117
+
118
+ To configure the functionality you can provide an object following this interface
119
+
120
+ ```js
121
+ interface IChunksRetryPluginConfig {
122
+ inject: boolean; //if you want the plugin injected
123
+
124
+ threshold: number; //amount of retries
125
+
126
+ thresholdReachedCallBack?: string; //a function (body of it as string) to be called when the amount of retries has been exhausted
127
+
128
+ rollbarInstanceIdentifier?: string; //a key of a Rollbar instance present on the 'window' object e.g if you want to use window['rollbar_PQ'] to track the error in the Profile Questionnaire project in Rollbar then you send 'rollbar_PQ'
129
+
130
+ disableDefaultRollbarError?: boolean; //if you don't want to log by default when the threshold has been reached
131
+ }
132
+ ```
133
+
134
+ and you can provide this thru the `webpack` config of your service like so
135
+
136
+ ```js
137
+ const configuration = WebpackHelper.create({
138
+ chunksRetryConfig: {
139
+ threshold: 10,
140
+ thresholdReachedCallBack: `console.log("hello")`,
141
+ },
142
+ ...
143
+ ```
144
+
145
+ ### Limitations
146
+
147
+ We have some limitations in this implementation based on the plugin we used and that the code will be part of the webpack exported code
148
+
149
+ ### Only use ES5
150
+
151
+ You can only write ES5 code inside the `thresholdReachedCallBack`
152
+
153
+ ### String as function
154
+
155
+ The function `thresholdReachedCallBack` must be a string (aka the body of the function) and we cannot change that to be a function while retaining the simplicity of the code.
156
+
157
+ ## Configuration
158
+
159
+ Webpack Helper offers a compact but flexible configuration interface. Below you will find every option available.
160
+
161
+ ### entry **(required)**
162
+
163
+ The entrypoint for your webpack bundle. This can either be configured as an object with the bundle name as a key and the path as a value or as an array of paths if your project requires multiple entry points.
164
+
165
+ ```javascript
166
+ entry: [
167
+ "./src/main.ts"
168
+ ]
169
+
170
+ //or
171
+
172
+ entry: {
173
+ bundle: "./src/main.ts"
174
+ }
175
+ ```
176
+
177
+ ### Working with packaged components & libraries
178
+
179
+ When working with packaged components and libraries it is required to keep the bundle name in line with the major version of the package. This helps to prevent reference issues when multiple versions of a package load on a single page.
180
+
181
+ ```javascript
182
+ // version 1
183
+ entry: {
184
+ multiselect_v1: "./src/main.ts"
185
+ }
186
+
187
+ // version 2
188
+ entry: {
189
+ multiselect_v2: "./src/main.ts"
190
+ }
191
+ ```
192
+
193
+ #### DLL
194
+
195
+ When working with a packaged component as a DLL, both the JS bundle and CSS bundle from the core package must be referenced, as below:
196
+
197
+ ```javascript
198
+
199
+ entry: {
200
+ multiselect_v2: [
201
+ '@studyportals/multiselect/dist/multiselect.js',
202
+ '@studyportals/multiselect/dist/multiselect.css'
203
+ ]
204
+ }
205
+
206
+ ```
207
+
208
+ ### output **(required)**
209
+
210
+ The output object has some options that define how your bundle will be output. It has the following properties:
211
+
212
+ - `path`**(required)**: The target directory for all output files.
213
+ - `library`: The name of the exported library, which will also be used to namespace sourcemaps. This will default to `null`.
214
+ - `publicPath`: The url to the output directory resolved relative to the HTML page. This will default to `null`.
215
+ - `fileName`: A custom filename for your bundle. This will default to `[name]` which refers to the name you've given your entrypoint.
216
+ - `hash`: Whether or not to add build hashes to your filenames. This will default to `true`. Whenever you want different values for your js and css you can pass an object with separate properties and values as in the example below.
217
+ - `crossOriginLoading`: Tells webpack to enable cross-origin loading of chunks. Can either be set to `anonymous` or `user-credentials`.
218
+
219
+ ```javascript
220
+ output: {
221
+ path: path.resolve(__dirname, './dist'),
222
+ library: 'test-microservice',
223
+ publicPath: '/assets/',
224
+ fileName: 'application',
225
+ crossOriginLoading: 'anonymous',
226
+ hash: false,
227
+ //or
228
+ hash: {
229
+ js: true,
230
+ css: false
231
+ }
232
+ }
233
+ ```
234
+
235
+ ### preset
236
+
237
+ The preset property determines which preset to load into your webpack configuration.
238
+
239
+ ```javascript
240
+ preset: "vue-typescript | typescript | javascript"
241
+ ```
242
+
243
+ ### bob
244
+
245
+ The bob object adds all necessary configuration to have your project generate a manifest file to be used by [Bob](https://github.com/studyportals/Bob).
246
+
247
+ - `name`**(required)**: The name of your microservice.
248
+ - `html`**(required)**: The HTML that needs to be output by your microservice. Can be a path to a document or a snippet.
249
+ - `baseURL`: The baseURL for your microservice assets.
250
+ - `async`: An array of JS filenames to be loaded async.
251
+ - `defer`: An array of CSS filenames to be lazy-loaded.
252
+ - `exclude`: An array of filenames (CSS and JS) that should be excluded from your manifest file.
253
+ - `dllPackages`: An array of objects that reference your Dll dependencies. They all require a name and a Dll manifest in the form of a json file.
254
+
255
+ ```javascript
256
+ bob: {
257
+ name: 'MicroService',
258
+ html: '<div id=\"MicroServicePlaceholder\"></div>',
259
+ baseURL: '/dist',
260
+ defer: ['style'],
261
+ exclude: ['demo-assets'],
262
+ dllPackages: [
263
+ {
264
+ name: "package-dll",
265
+ manifest: require("@studyportals/package-dll/dist/manifest.json")
266
+ }
267
+ ]
268
+ }
269
+ ```
270
+
271
+ WebpackHelper uses [BobManifestGenerator](https://github.com/studyportals/BobManifestGenerator) to generate a manifest file.
272
+
273
+ ### common
274
+
275
+ Extra Webpack configuration to be used for all environments can be passed in the `common` object. This configuration needs to adhere to Webpack's configuration interface and will be merged in with the other configuration through [webpack-merge](https://github.com/survivejs/webpack-merge).
276
+
277
+ ### development
278
+
279
+ Extra Webpack configuration to be used for all development builds can be passed in the `development` object. This configuration needs to adhere to Webpack's configuration interface and will be merged in with the other configuration through [webpack-merge](https://github.com/survivejs/webpack-merge).
280
+
281
+ **NOTE**: Some default configuration for development builds will be added automatically. Details can be found [here](src/defaults/defaults.md).
282
+
283
+ ### production
284
+
285
+ Extra Webpack configuration to be used for all production builds can be passed in the `production` object. This configuration needs to adhere to Webpack's configuration interface and will be merged in with the other configuration through [webpack-merge](https://github.com/survivejs/webpack-merge).
286
+
287
+ **NOTE**: Some default configuration for production builds will be added automatically. Details can be found [here](src/defaults/defaults.md).
288
+
289
+ ## Presets
290
+
291
+ In order to make your life as easy as possible, Webpack Helper ships with a set of presets that will take care of putting some essential plugins and loaders in your configuration. The different presets are listed below.
292
+
293
+ More in depth information on what configuration these presets will add to your project can be found [here](src/presets/presets.md).
294
+
295
+ ### javascript
296
+
297
+ The javascript preset will resolve all `.js` and `.json` files and transpiles them with Babel. If your project has styling, it will separate that out in a separate `.css` file.
298
+
299
+ ### typescript
300
+
301
+ The typescript preset will resolve all `.ts`, `.tsx`, `.js` and `.json` files. It transpiles them using tsc and Babel. Be aware that you will need to include a `tsconfig.json` in your project for it to work properly. If your project has styling, it will separate that out in a separate `.css` file.
302
+
303
+ ### vue-typescript
304
+
305
+ The vue-typescript preset will resolve all `.vue`, `.ts`, `.tsx`, `.js` and `.json` files. It transpiles them using vue-loader, tsc and Babel. Be aware that you will need to include a `tsconfig.json` in your project for it to work properly. If your project has styling, it will separate that out in a separate `.css` file.
306
+
307
+ ## DoD compliance with Babel and Browserslist
308
+
309
+ In order to comply to [Studyportals' definition of done](https://knowledge-vault.studyportals.xyz/definitions-of-done/product/) we use `babel` to transpile our front-end code according to the browsers we need to support. To do this your project needs some configuration. When Webpack Helper is installed it will put standard configuration in the root of your project which consists of 2 files:
310
+
311
+ - `.babelrc`: A standard configuration for babel that loads the `babel-env` and `babel-typescripts` presets. You might need to add more plugins for your specific project.
312
+ - `.browserslistrc`: A configuration file for browserslist. This is used by `babel-env` to determine which browsers to transpile the code for. Within this file the configuration for student facing products will be loaded by default but other configurations can be easily loaded by uncommenting some lines.
313
+
314
+ ## Unit testing
315
+
316
+ From version `6.0.0` onwards test dependencies are no longer included and should be installed separately. It's also recommended to replace jest with vitest due the complex nature of package jungle. A upgrade guide can be find [here](docs/jest-to-vitest-upgrade-guide.md)
@@ -1,3 +1,3 @@
1
- #extends @studyportals/browserslist-config/clients
2
- #extends @studyportals/browserslist-config/internal
1
+ #extends @studyportals/browserslist-config/clients
2
+ #extends @studyportals/browserslist-config/internal
3
3
  extends @studyportals/browserslist-config/student
package/package.json CHANGED
@@ -1,51 +1,54 @@
1
- {
2
- "name": "@studyportals/webpack-helper",
3
- "version": "7.0.0-3",
4
- "description": "A collection of standard configurations and helpers for webpack.",
5
- "main": "src/main.js",
6
- "scripts": {
7
- "test": "vitest --watch=false --coverage",
8
- "build": "tsc",
9
- "prepublish": "npm run build",
10
- "postinstall": "cp ./assets/.browserslistrc ../../../",
11
- "deploy-beta": "npm version prerelease && npm run build && npm publish --tag beta --access=public --auth-type=legacy && rm -rf node_modules"
12
- },
13
- "files": [
14
- "src/**/*.js",
15
- "assets/*"
16
- ],
17
- "author": {
18
- "name": "Frank Kluijtmans",
19
- "email": "frank@studyportals.com"
20
- },
21
- "license": "ISC",
22
- "dependencies": {
23
- "@studyportals/bob-manifest-generator": "^5.0.1",
24
- "@studyportals/browserslist-config": "^1.2.4",
25
- "@studyportals/dll-availability-tracker": "^2.0.0",
26
- "@studyportals/vue-config": "^5.0.3",
27
- "css-loader": "^6.10.0",
28
- "css-minimizer-webpack-plugin": "^6.0.0",
29
- "esbuild-loader": "^4.0.3",
30
- "esbuild-plugin-browserslist": "^0.11.1",
31
- "file-loader": "^6.2.0",
32
- "fork-ts-checker-webpack-plugin": "^9.0.2",
33
- "mini-css-extract-plugin": "^2.8.0",
34
- "path": "^0.12.7",
35
- "prettier": "^2.8.8",
36
- "sass": "^1.71.1",
37
- "sass-loader": "^14.1.1",
38
- "terser-webpack-plugin": "^5.3.10",
39
- "typescript": "^5.3.3",
40
- "vue-loader": "^17.4.2",
41
- "webpack": "^5.90.3",
42
- "webpack-cli": "^5.1.4",
43
- "webpack-dev-server": "^5.2.2",
44
- "webpack-merge": "^5.10.0"
45
- },
46
- "devDependencies": {
47
- "@types/node": "^20.11.20",
48
- "@vitest/coverage-v8": "^1.3.1",
49
- "vitest": "^1.3.1"
50
- }
51
- }
1
+ {
2
+ "name": "@studyportals/webpack-helper",
3
+ "version": "7.0.1-0",
4
+ "description": "A collection of standard configurations and helpers for webpack.",
5
+ "main": "src/main.js",
6
+ "scripts": {
7
+ "test": "vitest --watch=false --coverage",
8
+ "build": "tsc",
9
+ "prepublish": "npm run build",
10
+ "postinstall": "cp ./assets/.browserslistrc ../../../",
11
+ "deploy-beta": "npm version prerelease && npm run build && npm publish --tag beta --access=public --auth-type=legacy && rm -rf node_modules"
12
+ },
13
+ "files": [
14
+ "src/**/*.js",
15
+ "assets/*"
16
+ ],
17
+ "author": {
18
+ "name": "Frank Kluijtmans",
19
+ "email": "frank@studyportals.com"
20
+ },
21
+ "license": "ISC",
22
+ "dependencies": {
23
+ "@studyportals/bob-manifest-generator": "^5.0.1",
24
+ "@studyportals/browserslist-config": "^1.2.4",
25
+ "@studyportals/dll-availability-tracker": "^2.0.0",
26
+ "@studyportals/vue-config": "^5.0.3",
27
+ "@swc/core": "^1.12.7",
28
+ "@swc/helpers": "^0.5.17",
29
+ "css-loader": "^6.10.0",
30
+ "css-minimizer-webpack-plugin": "^6.0.0",
31
+ "esbuild-loader": "^4.0.3",
32
+ "esbuild-plugin-browserslist": "^0.11.1",
33
+ "file-loader": "^6.2.0",
34
+ "fork-ts-checker-webpack-plugin": "^9.0.2",
35
+ "mini-css-extract-plugin": "^2.8.0",
36
+ "path": "^0.12.7",
37
+ "prettier": "^2.8.8",
38
+ "sass": "^1.71.1",
39
+ "sass-loader": "^14.1.1",
40
+ "swc-loader": "^0.2.6",
41
+ "terser-webpack-plugin": "^5.3.10",
42
+ "typescript": "^5.3.3",
43
+ "vue-loader": "^17.4.2",
44
+ "webpack": "^5.90.3",
45
+ "webpack-cli": "^5.1.4",
46
+ "webpack-dev-server": "^5.2.2",
47
+ "webpack-merge": "^5.10.0"
48
+ },
49
+ "devDependencies": {
50
+ "@types/node": "^20.11.20",
51
+ "@vitest/coverage-v8": "^1.3.1",
52
+ "vitest": "^1.3.1"
53
+ }
54
+ }
@@ -4,6 +4,7 @@ exports.Preset = void 0;
4
4
  var Preset;
5
5
  (function (Preset) {
6
6
  Preset["VUE_TYPESCRIPT"] = "vue-typescript";
7
+ Preset["VUE_TYPESCRIPT_SWC"] = "vue-typescript-swc";
7
8
  Preset["TYPESCRIPT"] = "typescript";
8
9
  Preset["JAVASCRIPT"] = "javascript";
9
10
  })(Preset || (exports.Preset = Preset = {}));
@@ -20,12 +20,12 @@ class ChunksRetryPluginFactory {
20
20
  static CustomRetryChunksPlugin(preset) {
21
21
  const { retryChunksConfig } = preset;
22
22
  return new RetryChunkLoadPlugin({
23
- cacheBust: `function() {
24
- return Date.now();
23
+ cacheBust: `function() {
24
+ return Date.now();
25
25
  }`,
26
- retryDelay: `function(retryAttempt) {
27
- return Math.min(2000, Math.pow(2, retryAttempt) * 100);
28
- }
26
+ retryDelay: `function(retryAttempt) {
27
+ return Math.min(2000, Math.pow(2, retryAttempt) * 100);
28
+ }
29
29
  `,
30
30
  maxRetries: retryChunksConfig.threshold,
31
31
  lastResortScript: ChunksRetryPluginFactory.CreateLastResortScript(preset)
@@ -35,18 +35,18 @@ class ChunksRetryPluginFactory {
35
35
  const { retryChunksConfig } = preset;
36
36
  let lastResortScript = ``;
37
37
  if (retryChunksConfig.thresholdReachedCallBack) {
38
- lastResortScript += `
39
- ${retryChunksConfig.thresholdReachedCallBack}
38
+ lastResortScript += `
39
+ ${retryChunksConfig.thresholdReachedCallBack}
40
40
  `;
41
41
  }
42
42
  if (!retryChunksConfig.disableDefaultRollbarError) {
43
43
  const rollbarInstanceIdentifier = retryChunksConfig.rollbarInstanceIdentifier || 'rollbar';
44
- lastResortScript += `
45
- if (!window || !window['${rollbarInstanceIdentifier}'] || !window['${rollbarInstanceIdentifier}'].error) {
46
- return;
47
- }
48
-
49
- window['${rollbarInstanceIdentifier}'].error(new Error('Failed to load chunk for after retries'));
44
+ lastResortScript += `
45
+ if (!window || !window['${rollbarInstanceIdentifier}'] || !window['${rollbarInstanceIdentifier}'].error) {
46
+ return;
47
+ }
48
+
49
+ window['${rollbarInstanceIdentifier}'].error(new Error('Failed to load chunk for after retries'));
50
50
  `;
51
51
  }
52
52
  return lastResortScript;
@@ -69,6 +69,8 @@ class Configuration {
69
69
  case preset_1.Preset.VUE_TYPESCRIPT:
70
70
  this.injectPreset(new vue_typescript_preset_1.VueTypeScriptPreset(mode, this.chunksRetryConfig, this.customElementTags));
71
71
  break;
72
+ case preset_1.Preset.VUE_TYPESCRIPT_SWC:
73
+ this.injectPreset(new vue_typescript_preset_1.VueTypeScriptPreset(mode, this.chunksRetryConfig, this.customElementTags));
72
74
  case preset_1.Preset.TYPESCRIPT:
73
75
  this.injectPreset(new typescript_preset_1.TypeScriptPreset(mode, this.chunksRetryConfig));
74
76
  break;
@@ -17,8 +17,8 @@ class RetryChunkLoadPlugin {
17
17
  ? maxRetryValueFromOptions
18
18
  : 1;
19
19
  const getCacheBustString = () => this.options.cacheBust
20
- ? `
21
- (${this.options.cacheBust})();
20
+ ? `
21
+ (${this.options.cacheBust})();
22
22
  `
23
23
  : '"cache-bust=true"';
24
24
  mainTemplate.hooks.localVars.tap({ name: pluginName, stage: 1 }, (source, chunk) => {
@@ -30,41 +30,41 @@ class RetryChunkLoadPlugin {
30
30
  : `function() { return ${this.options.retryDelay || 0} }`;
31
31
  if (!addRetryCode)
32
32
  return source;
33
- const script = runtimeTemplate.iife('', `
34
- if(typeof ${RuntimeGlobals.require} !== "undefined") {
35
- var oldGetScript = ${RuntimeGlobals.getChunkScriptFilename};
36
- var oldLoadScript = ${RuntimeGlobals.ensureChunk};
37
- var queryMap = {};
38
- var countMap = {};
39
- var getRetryDelay = ${getRetryDelay}
40
- ${RuntimeGlobals.getChunkScriptFilename} = function(chunkId){
41
- var result = oldGetScript(chunkId);
42
- return result + (queryMap.hasOwnProperty(chunkId) ? '?' + queryMap[chunkId] : '');
43
- };
44
- ${RuntimeGlobals.ensureChunk} = function(chunkId){
45
- var result = oldLoadScript(chunkId);
46
- return result.catch(function(error){
47
- var retries = countMap.hasOwnProperty(chunkId) ? countMap[chunkId] : ${maxRetries};
48
- if (retries < 1) {
49
- var realSrc = oldGetScript(chunkId);
50
- error.message = 'Loading chunk ' + chunkId + ' failed after ${maxRetries} retries.\\n(' + realSrc + ')';
33
+ const script = runtimeTemplate.iife('', `
34
+ if(typeof ${RuntimeGlobals.require} !== "undefined") {
35
+ var oldGetScript = ${RuntimeGlobals.getChunkScriptFilename};
36
+ var oldLoadScript = ${RuntimeGlobals.ensureChunk};
37
+ var queryMap = {};
38
+ var countMap = {};
39
+ var getRetryDelay = ${getRetryDelay}
40
+ ${RuntimeGlobals.getChunkScriptFilename} = function(chunkId){
41
+ var result = oldGetScript(chunkId);
42
+ return result + (queryMap.hasOwnProperty(chunkId) ? '?' + queryMap[chunkId] : '');
43
+ };
44
+ ${RuntimeGlobals.ensureChunk} = function(chunkId){
45
+ var result = oldLoadScript(chunkId);
46
+ return result.catch(function(error){
47
+ var retries = countMap.hasOwnProperty(chunkId) ? countMap[chunkId] : ${maxRetries};
48
+ if (retries < 1) {
49
+ var realSrc = oldGetScript(chunkId);
50
+ error.message = 'Loading chunk ' + chunkId + ' failed after ${maxRetries} retries.\\n(' + realSrc + ')';
51
51
  error.request = realSrc;${this.options.lastResortScript
52
52
  ? this.options.lastResortScript
53
- : ''}
54
- throw error;
55
- }
56
- return new Promise(function (resolve) {
57
- var retryAttempt = ${maxRetries} - retries + 1;
58
- setTimeout(function () {
59
- var retryAttemptString = '&retry-attempt=' + retryAttempt;
60
- var cacheBust = ${getCacheBustString()} + retryAttemptString;
61
- queryMap[chunkId] = cacheBust;
62
- countMap[chunkId] = retries - 1;
63
- resolve(${RuntimeGlobals.ensureChunk}(chunkId));
64
- }, getRetryDelay(retryAttempt))
65
- })
66
- });
67
- };
53
+ : ''}
54
+ throw error;
55
+ }
56
+ return new Promise(function (resolve) {
57
+ var retryAttempt = ${maxRetries} - retries + 1;
58
+ setTimeout(function () {
59
+ var retryAttemptString = '&retry-attempt=' + retryAttempt;
60
+ var cacheBust = ${getCacheBustString()} + retryAttemptString;
61
+ queryMap[chunkId] = cacheBust;
62
+ countMap[chunkId] = retries - 1;
63
+ resolve(${RuntimeGlobals.ensureChunk}(chunkId));
64
+ }, getRetryDelay(retryAttempt))
65
+ })
66
+ });
67
+ };
68
68
  }`);
69
69
  return (source +
70
70
  prettier.format(script, {
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TypeScriptPreset = void 0;
4
+ const browser_list_to_esbuild_target_factory_1 = require("../factories/browser-list-to-esbuild-target-factory");
5
+ const MiniCssExtractPlugin = require('mini-css-extract-plugin');
6
+ class TypeScriptPreset {
7
+ constructor(mode, retryChunksConfig) {
8
+ this.mode = mode;
9
+ this.retryChunksConfig = retryChunksConfig;
10
+ }
11
+ getPlugins(filename) {
12
+ return [
13
+ new MiniCssExtractPlugin({
14
+ filename
15
+ }),
16
+ ];
17
+ }
18
+ getModule() {
19
+ return {
20
+ rules: [
21
+ {
22
+ test: /\.css$/,
23
+ use: [
24
+ MiniCssExtractPlugin.loader,
25
+ 'css-loader'
26
+ ],
27
+ },
28
+ {
29
+ test: /\.scss$/,
30
+ use: [
31
+ MiniCssExtractPlugin.loader,
32
+ 'css-loader',
33
+ {
34
+ loader: 'sass-loader',
35
+ options: {
36
+ api: 'modern-compiler'
37
+ }
38
+ }
39
+ ],
40
+ },
41
+ {
42
+ test: /\.[jt]sx?$/,
43
+ loader: 'esbuild-loader',
44
+ options: {
45
+ target: new browser_list_to_esbuild_target_factory_1.BrowserListToEsbuildTargetFactory().createTarget(),
46
+ supported: {
47
+ 'class-static-blocks': false,
48
+ 'optional-chain': false,
49
+ }
50
+ },
51
+ resolve: {
52
+ fullySpecified: false
53
+ },
54
+ exclude: /node_modules\/(?!@studyportals\/).*/,
55
+ },
56
+ {
57
+ test: /\.(png|jpg|gif|svg)$/,
58
+ loader: 'file-loader',
59
+ options: {
60
+ name: '[name].[ext]?[fullhash]'
61
+ }
62
+ }
63
+ ]
64
+ };
65
+ }
66
+ getExtensions() {
67
+ return [
68
+ '*',
69
+ '.ts',
70
+ '.js',
71
+ '.json'
72
+ ];
73
+ }
74
+ }
75
+ exports.TypeScriptPreset = TypeScriptPreset;
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VueTypescriptSwcPreset = void 0;
4
+ const mode_1 = require("../enums/mode");
5
+ const MiniCssExtractPlugin = require('mini-css-extract-plugin');
6
+ const webpack = require("webpack");
7
+ const VueLoaderPlugin = require('vue-loader').VueLoaderPlugin;
8
+ const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
9
+ class VueTypescriptSwcPreset {
10
+ constructor(mode, retryChunksConfig, customElementTags) {
11
+ this.mode = mode;
12
+ this.retryChunksConfig = retryChunksConfig;
13
+ this.customElementTags = customElementTags;
14
+ }
15
+ getPlugins(filename) {
16
+ return [
17
+ new ForkTsCheckerWebpackPlugin(),
18
+ new webpack.DllReferencePlugin({
19
+ manifest: require(`@studyportals/vue-config/dist/vue3_library_v5${this.mode === mode_1.Mode.PRODUCTION ? '.min' : ''}.json`)
20
+ }),
21
+ new MiniCssExtractPlugin({
22
+ filename,
23
+ ignoreOrder: true
24
+ }),
25
+ new VueLoaderPlugin()
26
+ ];
27
+ }
28
+ getModule() {
29
+ return {
30
+ rules: [
31
+ {
32
+ test: /\.css$/,
33
+ use: [
34
+ MiniCssExtractPlugin.loader,
35
+ 'css-loader'
36
+ ],
37
+ },
38
+ {
39
+ test: /\.scss$/,
40
+ use: [
41
+ MiniCssExtractPlugin.loader,
42
+ 'css-loader',
43
+ {
44
+ loader: 'sass-loader',
45
+ options: {
46
+ api: 'modern-compiler'
47
+ }
48
+ }
49
+ ],
50
+ },
51
+ {
52
+ test: /\.vue$/,
53
+ loader: 'vue-loader',
54
+ options: {
55
+ loaders: {
56
+ 'scss': [
57
+ 'vue-style-loader',
58
+ 'css-loader',
59
+ 'sass-loader'
60
+ ]
61
+ },
62
+ hotReload: false,
63
+ compilerOptions: {
64
+ isCustomElement: (tag) => this.customElementTags.includes(tag)
65
+ }
66
+ }
67
+ },
68
+ {
69
+ test: /\.(ts|js)x?$/,
70
+ exclude: /node_modules/,
71
+ use: {
72
+ loader: 'swc-loader',
73
+ options: {
74
+ jsc: {
75
+ keepClassNames: true,
76
+ parser: {
77
+ syntax: 'typescript',
78
+ tsx: true,
79
+ decorators: true,
80
+ },
81
+ transform: {
82
+ legacyDecorator: true,
83
+ decoratorMetadata: true
84
+ },
85
+ target: 'es6'
86
+ },
87
+ module: {
88
+ type: 'es6'
89
+ }
90
+ }
91
+ }
92
+ },
93
+ {
94
+ test: /\.(png|jpg|gif|svg)$/,
95
+ loader: 'file-loader',
96
+ options: {
97
+ name: '[name].[ext]?[fullhash]'
98
+ }
99
+ },
100
+ ]
101
+ };
102
+ }
103
+ getExtensions() {
104
+ return [
105
+ '*',
106
+ '.ts',
107
+ '.js',
108
+ '.vue',
109
+ '.json'
110
+ ];
111
+ }
112
+ }
113
+ exports.VueTypescriptSwcPreset = VueTypescriptSwcPreset;
@@ -1,20 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.VueTypescriptNoCodeSplittingPreset = void 0;
4
- const MiniCssExtractPlugin = require('mini-css-extract-plugin');
5
- const VueLoaderPlugin = require('vue-loader').VueLoaderPlugin;
6
- const vue_typescript_preset_1 = require("./vue-typescript.preset");
7
- class VueTypescriptNoCodeSplittingPreset extends vue_typescript_preset_1.VueTypeScriptPreset {
8
- constructor(mode) {
9
- super(mode);
10
- }
11
- getPlugins(filename) {
12
- return [
13
- new MiniCssExtractPlugin({
14
- filename
15
- }),
16
- new VueLoaderPlugin()
17
- ];
18
- }
19
- }
20
- exports.VueTypescriptNoCodeSplittingPreset = VueTypescriptNoCodeSplittingPreset;