@studyportals/webpack-helper 7.0.1-5 → 8.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
@@ -7,6 +7,10 @@ WebpackHelper is a utility that makes it easy to set up a webpack configuration
7
7
  - [Webpack version](#webpack-version)
8
8
  - [Notes on updating Webpack from v4 to v5](#notes-on-updating-webpack-from-v4-to-v5)
9
9
  - [Quick Start](#quick-start)
10
+ - [SCSS Migration](#scss-migration-from-153x-to--1540)
11
+ - [Minimum compiler that shows each warning](#minimum-compiler-that-shows-each-warning)
12
+ - [Migration](#migration)
13
+ - [List of changes](#list-of-changes)
10
14
  - [Chunks Retry](#chunks-retry)
11
15
  - [Defaults](#defaults)
12
16
  - [Setup](#setup)
@@ -101,6 +105,75 @@ When your configuration is created you can get an instance of it for the correct
101
105
  module.exports = (env, details) => configuration.get(details.mode);
102
106
  ```
103
107
 
108
+ ## SCSS Migration from 1.53.x to >= 1.54.0
109
+
110
+ This package is used by other services that build with `sass`. Each `sass` release is a JavaScript build of the same-numbered Dart Sass compiler, so bumping from 1.53.x to 1.54.0 silently enables a raft of breaking-change warnings. Eventually when Dart Sass 3 is released, these warnings become hard errors that will break downstream builds.
111
+
112
+ | Dependency in *package.json* | Real compiler behind the scenes | Notes |
113
+ | ---------------------------- | ------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- |
114
+ | `"sass": "^1.89.2"` | Dart Sass 1.89.2 (JS build) | Running `npx sass --version` shows the exact Dart Sass version. |
115
+ | `"sass-loader": "^16"` | Webpack loader that invokes **whatever Sass implementation you installed** (defaults to the `sass` package above). | |
116
+
117
+ ### Minimum compiler that shows each warning
118
+
119
+ | Change (see checklist below) | First **warns** in | Becomes an **error** |
120
+ | ---------------------------------------------- | ------------------ | -------------------- |
121
+ | Invalid combinators (`> >`, leading `+`, etc.) | 1.54.0 | already errors |
122
+ | Media-Query Level 4 logic | 1.54.0 | 1.56.0 |
123
+ | Strict unary `+ -` spacing | 1.55.0 | already errors |
124
+ | Duplicate `!default`/`!global` flags | 1.62.0 | already errors |
125
+ | Reserved `type()` function | 1.86.0 | next major |
126
+ | `/` division → `math.div()` | 1.33.0 | next major |
127
+ | `@import` → module system | 1.80.0 | Dart Sass 3 |
128
+
129
+ ### Migration
130
+
131
+ To help us migrate, there is a package called `sass-migrator` that you can use to resolve the majority of the issues.
132
+
133
+ ```bash
134
+ npm install --save-dev sass-migrator
135
+ ```
136
+
137
+ Then run
138
+
139
+ ```bash
140
+ # migrate @import → @use/@forward
141
+ npx sass-migrator module --migrate-deps "src/**/*.scss"
142
+
143
+ # replace “/” division with math.div()
144
+ npx sass-migrator division --migrate-deps "src/**/*.scss"
145
+
146
+ # add the required space for ambiguous + / - operators
147
+ npx sass-migrator strict-unary --migrate-deps "src/**/*.scss"
148
+
149
+ # swap legacy color helpers (lighten(), darken(), …) for sass:color APIs
150
+ npx sass-migrator color --migrate-deps "src/**/*.scss"
151
+ ```
152
+
153
+ #### List of changes
154
+
155
+ | # | Change you must make | **Before — old SCSS** | **After — new SCSS** | Why it matters |
156
+ | -- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
157
+ | 1 | Replace **`@import` → `@use/@forward`** | A) `@import "tools/colors";`<br>B) `@import "theme/light";`<br>    `@import "components/button";` | A) `@use "tools/colors" as colors;`<br>B) `@use "theme/light" as *;`<br>    `@use "components/button";` | `@import` builds a huge global namespace and re-parses files; removed in Dart Sass 3.0. |
158
+ | 2 | Slash-division → **`math.div()`** | A) `width: 100%/3;`<br>B) `$col: 940px/12;` | `@use "sass:math";`<br>A) `width: math.div(100%, 3);`<br>B) `$col: math.div(940px, 12);` | `/` is being re-defined as a list separator. |
159
+ | 3 | Make unary `+` / `-` unambiguous | A) `gap: 10px -$space;`<br>B) `margin: +$n ($n*2);` | A) `gap: 10px - $space;` or `gap: 10px (-$space);`<br>B) `margin: + $n (#{$n*2});` | Compiler now errors on ambiguous signs. |
160
+ | 4 | Rename a custom **`type()`** function | A) `@function type($x) {…}`<br>B) `$v: type(42);` | A) `@function kind($x) {…}`<br>B) `$v: kind(42);` | CSS adds its own reserved `type()`. |
161
+ | 5 | Swap legacy colour helpers for **`sass:color`** | A) `$hover: lighten($brand, 10%);`<br>B) `$new: adjust-hue($brand, 20deg);` | `@use "sass:color";`<br>A) `$hover: color.adjust($brand, $lightness: 10%);`<br>B) `$new: color.adjust($brand, $hue: 20deg);` | Old helpers assume sRGB only. |
162
+ | 6 | Remove duplicate flags | A) `$pad: 1rem !default !default;`<br>B) `$debug: null !global !global;` | `$pad: 1rem !default;`<br>`$debug: null !global;` | A second `!default`/`!global` is now an error. |
163
+ | 7 | Delete **`meta.feature-exists()`** | A) `@use "sass:meta";`<br>  `@if meta.feature-exists("global-variable-shadowing") {…}`<br>B) `$has: feature-exists(calc);` | Usually just delete — all features it checks are always present. | Function is obsolete. |
164
+ | 8 | Fix stray / doubled combinators | A) `+ .alert {…}`<br>B) `nav > > li {…}` | A) `.alert {…}`<br>B) `nav > li {…}` | Invalid CSS selectors now error. |
165
+ | 9 | Keep declarations **before** nested rules | `.card {`<br>  `color:#333;`<br>  `&__header {…}`<br>  `font-weight:bold;`<br>`}` | `.card {`<br>  `color:#333;`<br>  `&__header {…}`<br>  `& { font-weight:bold; }`<br>`}` | Mirrors CSS Nesting source-order rules. |
166
+ | 10 | Use CSS-4 logic in **`@media`** | A) `@media (not (prefers-reduced-motion)) {…}`<br>B) `@media ((hover) and (pointer:fine)) {…}` | `@media not (prefers-reduced-motion) {…}`<br>`@media (hover) and (pointer:fine) {…}` | Old parenthesised syntax conflicts with MQ L4. |
167
+ | 11 | Always interpolate custom-prop values | A) `--accent: $brand;`<br>B) `--size: $gap * 1.5;` | `--accent: #{$brand};`<br>`--size: #{$gap * 1.5};` | Stops Sass mistaking raw CSS tokens for vars. |
168
+ | 12 | Give colour funcs the right units | A) `hsl(0.5turn,100%,50%);`<br>B) `$deg: 90grad; hue($c,$deg);` | A) `hsl(180deg,100%,50%);`<br>B) `$deg: 90deg; color.adjust($c,$hue:$deg);` | Functions now enforce CSS-spec units. |
169
+ | 13 | Use **`math.abs()`** for percentages | A) `$pos: abs(-10%);`<br>B) `padding: abs(5%);` | `@use "sass:math";`<br>A) `$pos: math.abs(-10%);`<br>B) `padding: math.abs(5%);` | Global `abs()` drops `%` support. |
170
+ | 14 | Rename any name starting **`--`** | A) `@mixin --theme($c){…}`<br>B) `@function --shadow(){…}` | `@mixin _theme($c){…}`<br>`@function _shadow(){…}` | `--` reserved for future native CSS mixins. |
171
+ | 15 | Remove special **`@-moz-document`** parser | `@-moz-document url-prefix("https://") { … }`<br>`@-moz-document domain(mozilla.org) { … }` | *(Delete or treat as an unknown at-rule; only `@-moz-document url-prefix()` hack still compiles.)* | Feature gone from Firefox → dropped from Sass. |
172
+ | 16 | **Don’t `@extend` a compound selector** | A) `.notice { @extend .msg.info; }`<br>B) `.alert { @extend .box.error; }` | `.notice { @extend .msg, .info; }`<br>`.alert { @extend .box, .error; }` | Dart Sass forbids extending `.foo.bar`. |
173
+ | 17 | **You can’t overwrite a mixin or function that came in via `@use`** | `@import "~@studyportals/styles-abstracts/abstracts.scss";`<br>`@include TextStyle($name);`<br>`font-weight: 700;`| `@use "~@studyportals/styles-abstracts/abstracts.scss" as *;`<br>`@include TextStyle($name);`| Error immediately since `@use` (1.23) — name collisions are blocked ([sass-lang.com][1]) |
174
+
175
+ [1]: https://sass-lang.com/blog/the-module-system-is-launched/ "Sass: The Module System is Launched"
176
+
104
177
  ## Chunks Retry
105
178
 
106
179
  Webpack Helpers has a default configuration to retry chunks which cannot get loaded on the first try (for whatever reason, network or otherwise).
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@studyportals/webpack-helper",
3
- "version": "7.0.1-5",
3
+ "version": "8.1.0",
4
4
  "description": "A collection of standard configurations and helpers for webpack.",
5
5
  "main": "src/main.js",
6
6
  "scripts": {
7
7
  "test": "vitest --watch=false --coverage",
8
8
  "build": "tsc",
9
9
  "prepublish": "npm run build",
10
- "postinstall": "cp ./assets/.browserslistrc ../../../",
10
+ "postinstall": "test -d ../../../ && cp ./assets/.browserslistrc ../../../ || true",
11
11
  "deploy-beta": "npm version prerelease && npm run build && npm publish --tag beta --access=public --auth-type=legacy && rm -rf node_modules"
12
12
  },
13
13
  "files": [
@@ -20,12 +20,10 @@
20
20
  },
21
21
  "license": "ISC",
22
22
  "dependencies": {
23
- "@babel/core": "^7.27.4",
24
23
  "@studyportals/bob-manifest-generator": "^5.0.1",
25
- "@studyportals/browserslist-config": "^1.2.4",
24
+ "@studyportals/browserslist-config": "^2.0.0",
26
25
  "@studyportals/dll-availability-tracker": "^2.0.0",
27
26
  "@studyportals/vue-config": "^5.0.3",
28
- "babel-loader": "^10.0.0",
29
27
  "css-loader": "^6.10.0",
30
28
  "css-minimizer-webpack-plugin": "^6.0.0",
31
29
  "esbuild-loader": "^4.0.3",
@@ -35,11 +33,9 @@
35
33
  "mini-css-extract-plugin": "^2.8.0",
36
34
  "path": "^0.12.7",
37
35
  "prettier": "^2.8.8",
38
- "sass": "^1.71.1",
39
- "sass-loader": "^14.1.1",
40
- "swc-loader": "^0.2.6",
36
+ "sass": "^1.89.2",
37
+ "sass-loader": "^16.0.5",
41
38
  "terser-webpack-plugin": "^5.3.10",
42
- "ts-loader": "^9.5.2",
43
39
  "typescript": "^5.3.3",
44
40
  "vue-loader": "^17.4.2",
45
41
  "webpack": "^5.90.3",
@@ -4,7 +4,6 @@ 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";
8
7
  Preset["TYPESCRIPT"] = "typescript";
9
8
  Preset["JAVASCRIPT"] = "javascript";
10
9
  })(Preset || (exports.Preset = Preset = {}));
@@ -16,7 +16,6 @@ const mode_1 = require("../enums/mode");
16
16
  const production_config_1 = require("../defaults/production.config");
17
17
  const development_config_1 = require("../defaults/development.config");
18
18
  const chunks_retry_plugin_factory_1 = __importDefault(require("../factories/chunks-retry-plugin-factory"));
19
- const vue_typescript_swc_preset_1 = require("../presets/vue-typescript-swc.preset");
20
19
  const ManifestGenerator = require("@studyportals/bob-manifest-generator").ManifestGenerator;
21
20
  const DllReferencePlugin = require("@studyportals/bob-manifest-generator").DllReferencePlugin;
22
21
  const { merge } = require('webpack-merge');
@@ -70,8 +69,6 @@ class Configuration {
70
69
  case preset_1.Preset.VUE_TYPESCRIPT:
71
70
  this.injectPreset(new vue_typescript_preset_1.VueTypeScriptPreset(mode, this.chunksRetryConfig, this.customElementTags));
72
71
  break;
73
- case preset_1.Preset.VUE_TYPESCRIPT_SWC:
74
- this.injectPreset(new vue_typescript_swc_preset_1.VueTypescriptSwcPreset(mode, this.chunksRetryConfig, this.customElementTags));
75
72
  case preset_1.Preset.TYPESCRIPT:
76
73
  this.injectPreset(new typescript_preset_1.TypeScriptPreset(mode, this.chunksRetryConfig));
77
74
  break;
@@ -1,75 +0,0 @@
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;
@@ -1,106 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.VueTypescriptSwcPreset = void 0;
4
- const mode_1 = require("../enums/mode");
5
- const webpack = require("webpack");
6
- const MiniCssExtractPlugin = require('mini-css-extract-plugin');
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
- console.log(`[VueTypescriptSwcPreset] Constructor called for mode: ${mode}`);
15
- }
16
- getPlugins(filename) {
17
- return [
18
- new ForkTsCheckerWebpackPlugin(),
19
- new webpack.DllReferencePlugin({
20
- manifest: require(`@studyportals/vue-config/dist/vue3_library_v5${this.mode === mode_1.Mode.PRODUCTION ? '.min' : ''}.json`)
21
- }),
22
- new MiniCssExtractPlugin({
23
- filename,
24
- ignoreOrder: true
25
- }),
26
- new VueLoaderPlugin()
27
- ];
28
- }
29
- getModule() {
30
- return {
31
- rules: [
32
- {
33
- test: /\.css$/,
34
- use: [
35
- MiniCssExtractPlugin.loader,
36
- 'css-loader'
37
- ],
38
- },
39
- {
40
- test: /\.scss$/,
41
- use: [
42
- MiniCssExtractPlugin.loader,
43
- 'css-loader',
44
- 'sass-loader'
45
- ],
46
- },
47
- {
48
- test: /\.vue$/,
49
- loader: 'vue-loader',
50
- options: {
51
- loaders: {
52
- 'scss': [
53
- 'vue-style-loader',
54
- 'css-loader',
55
- 'sass-loader'
56
- ]
57
- },
58
- hotReload: false,
59
- }
60
- },
61
- {
62
- test: /\.(ts|js)x?$/,
63
- exclude: /node_modules/,
64
- use: {
65
- loader: 'swc-loader',
66
- options: {
67
- jsc: {
68
- keepClassNames: true,
69
- parser: {
70
- syntax: 'typescript',
71
- tsx: true,
72
- decorators: true,
73
- },
74
- transform: {
75
- legacyDecorator: true,
76
- decoratorMetadata: true
77
- },
78
- target: 'es6'
79
- },
80
- module: {
81
- type: 'es6'
82
- }
83
- }
84
- }
85
- },
86
- {
87
- test: /\.(png|jpg|gif|svg)$/,
88
- loader: 'file-loader',
89
- options: {
90
- name: '[name].[ext]?[fullhash]'
91
- }
92
- },
93
- ]
94
- };
95
- }
96
- getExtensions() {
97
- return [
98
- '*',
99
- '.ts',
100
- '.js',
101
- '.vue',
102
- '.json'
103
- ];
104
- }
105
- }
106
- exports.VueTypescriptSwcPreset = VueTypescriptSwcPreset;