Skip to content

Commit aeeb88c

Browse files
committed
feat: webpack v5 (#1645)
* feat: webpack-v5 * test: Update tests * docs: Updating docs to reflect changes * chore: Removing optimize-plugin local patch
1 parent 2ce2c8f commit aeeb88c

32 files changed

+1670
-2367
lines changed

.changeset/sweet-snakes-cheat.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
'preact-cli': major
3+
---
4+
5+
- Upgrades to Webpack v5
6+
- Any custom configuration you do in your `preact.config.js` may need to be altered to account for this. Plugins may need replacements or different option formats.
7+
8+
- `--esm` flag has been removed
9+
- Dual output is now enabled by default in production builds.
10+
11+
- `.babelrc` no longer overwrites matching keys
12+
- Instead, the config will be merged in to the default. The default still takes precedence when there are conflicts, so you will still need to use your `preact.config.js` if you want to edit or remove default plugins or presets.

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
**/node_modules
22
**/tests/output
3+
**/tests/subjects/*/preact.config.js
34
**/*.d.ts

README.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,14 @@ Note: If you don't specify enough data to the `npx preact-cli create` command, i
106106

107107
Create a production build
108108

109-
You can disable `default: true` flags by prefixing them with `--no-<option>`; for example, `--no-sw`, `--no-esm`, and `--no-inline-css`.
109+
You can disable `default: true` flags by prefixing them with `--no-<option>`; for example, `--no-sw`, `--no-prerender`, and `--no-inline-css`.
110110

111111
```
112112
$ preact build
113113
114114
--src Specify source directory (default src)
115115
--dest Specify output directory (default build)
116116
--cwd A directory to use instead of $PWD (default .)
117-
--esm Builds ES-2015 bundles for your code (default true)
118117
--sw Generate and attach a Service Worker (default true)
119118
--babelConfig Path to custom Babel config (default .babelrc)
120119
--json Generate build stats for bundle analysis
@@ -139,7 +138,6 @@ $ preact watch
139138
140139
--src Specify source directory (default src)
141140
--cwd A directory to use instead of $PWD (default .)
142-
--esm Builds ES-2015 bundles for your code (default false)
143141
--clear Clear the console (default true)
144142
--sw Generate and attach a Service Worker (default false)
145143
--babelConfig Path to custom Babel config (default .babelrc)
@@ -192,25 +190,25 @@ To make customizing your configuration easier, preact-cli supports plugins. Visi
192190

193191
#### Browserslist
194192

195-
You may customize your list of supported browser versions by declaring a [`"browserslist"`] key within your `package.json`. Changing these values will modify your JavaScript (via [`@babel/preset-env`]) and your CSS (via [`autoprefixer`](https://github.com/postcss/autoprefixer)) output.
193+
You may customize your list of supported browser versions by declaring a [`"browserslist"`] key within your `package.json`. Changing these values will modify your legacy JavaScript (via [`@babel/preset-env`]) and your CSS (via [`autoprefixer`](https://github.com/postcss/autoprefixer)) output.
196194

197195
By default, `preact-cli` emulates the following config:
198196

199197
> `package.json`
200198
201199
```json
202200
{
203-
"browserslist": ["> 0.25%", "IE >= 9"]
201+
"browserslist": ["> 0.5%", "last 2 versions", "Firefox ESR", "not dead"]
204202
}
205203
```
206204

207205
#### Babel
208206

209207
To customize Babel, you have two options:
210208

211-
1. You may create a [`.babelrc`] file in your project's root directory. Any settings you define here will overwrite matching config-keys within [Preact CLI preset]. For example, if you pass a `"plugins"` object, it will replace & reset all Babel plugins that Preact CLI defaults to.
209+
1. You may create a [`.babelrc`] file in your project's root directory, or use the `--babelConfig` path to point at any valid [Babel config file]. Any settings you define here will be merged into the [Preact CLI preset]. For example, if you pass a `"plugins"` object containing different plugins from those already in use, they will simply be added on top of the existing config. If there are conflicts, you'll want to look into option 2, as the default will take precedence.
212210

213-
2. If you'd like to modify or add to the existing Babel config, you must use a `preact.config.js` file. Visit the [Webpack](#webpack) section for more info, or check out the [Customize Babel] example!
211+
2. If you'd like to modify the existing Babel config you must use a `preact.config.js` file. Visit the [Webpack](#webpack) section for more info, or check out the [Customize Babel] example!
214212

215213
#### Webpack
216214

@@ -402,9 +400,9 @@ Automatic code splitting is applied to all JavaScript and TypeScript files in th
402400
[preact]: https://github.com/preactjs/preact
403401
[webpackconfighelpers]: docs/webpack-helpers.md
404402
[`.babelrc`]: https://babeljs.io/docs/usage/babelrc
403+
[babel config file]: https://babeljs.io/docs/en/config-files
405404
[simple]: https://github.com/preactjs-templates/simple
406405
[`"browserslist"`]: https://github.com/ai/browserslist
407-
[```.babelrc```]: https://babeljs.io/docs/usage/babelrc
408406
[default]: https://github.com/preactjs-templates/default
409407
[workbox]: https://developers.google.com/web/tools/workbox
410408
[preact-router]: https://github.com/preactjs/preact-router

packages/cli/package.json

Lines changed: 33 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -35,78 +35,69 @@
3535
},
3636
"dependencies": {
3737
"@babel/core": "^7.13.16",
38-
"@babel/plugin-proposal-class-properties": "^7.13.0",
3938
"@babel/plugin-proposal-decorators": "^7.13.15",
40-
"@babel/plugin-proposal-object-rest-spread": "^7.13.8",
41-
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
4239
"@babel/plugin-transform-object-assign": "^7.12.13",
4340
"@babel/plugin-transform-react-jsx": "^7.13.12",
4441
"@babel/preset-env": "^7.13.15",
4542
"@babel/preset-typescript": "^7.13.0",
4643
"@preact/async-loader": "^3.0.1",
4744
"@prefresh/babel-plugin": "^0.4.1",
4845
"@prefresh/webpack": "^3.2.2",
49-
"@types/webpack": "^4.38.0",
5046
"autoprefixer": "^10.4.7",
51-
"babel-esm-plugin": "^0.9.0",
5247
"babel-loader": "^8.2.5",
5348
"babel-plugin-macros": "^3.1.0",
5449
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
5550
"browserslist": "^4.20.3",
56-
"compression-webpack-plugin": "^6.1.1",
51+
"compression-webpack-plugin": "^9.2.0",
5752
"console-clear": "^1.0.0",
58-
"copy-webpack-plugin": "^6.4.0",
53+
"copy-webpack-plugin": "^9.1.0",
5954
"critters-webpack-plugin": "^3.0.2",
6055
"cross-spawn-promise": "^0.10.1",
61-
"css-loader": "^5.2.7",
56+
"css-loader": "^6.6.0",
57+
"css-minimizer-webpack-plugin": "3.4.1",
6258
"dotenv": "^16.0.0",
6359
"ejs-loader": "^0.5.0",
6460
"envinfo": "^7.8.1",
6561
"esm": "^3.2.25",
66-
"file-loader": "^6.2.0",
67-
"fork-ts-checker-webpack-plugin": "^4.0.4",
62+
"fork-ts-checker-webpack-plugin": "^7.1.1",
6863
"get-port": "^5.0.0",
6964
"gittar": "^0.1.0",
7065
"glob": "^8.0.3",
71-
"html-webpack-plugin": "^4.5.2",
66+
"html-webpack-plugin": "^5.5.0",
7267
"html-webpack-skip-assets-plugin": "1.0.3",
7368
"ip": "^1.1.8",
7469
"isomorphic-unfetch": "^3.1.0",
7570
"kleur": "^4.1.4",
76-
"loader-utils": "^2.0.0",
77-
"mini-css-extract-plugin": "^1.6.2",
71+
"mini-css-extract-plugin": "^2.5.3",
7872
"minimatch": "^3.0.3",
7973
"native-url": "0.3.4",
80-
"optimize-css-assets-webpack-plugin": "^6.0.1",
74+
"optimize-plugin": "^1.3.0",
8175
"ora": "^5.4.1",
82-
"pnp-webpack-plugin": "^1.7.0",
8376
"postcss": "^8.4.13",
8477
"postcss-load-config": "^3.1.4",
85-
"postcss-loader": "^4.2.0",
78+
"postcss-loader": "^6.2.1",
8679
"progress-bar-webpack-plugin": "^2.1.0",
8780
"promise-polyfill": "^8.2.3",
8881
"prompts": "^2.4.2",
89-
"raw-loader": "^4.0.2",
90-
"react-refresh": "0.10.0",
82+
"react-refresh": "0.11.0",
9183
"rimraf": "^3.0.2",
9284
"sade": "^1.8.1",
93-
"size-plugin": "^3.0.0",
85+
"size-plugin": "^2.0.2",
9486
"source-map": "^0.7.2",
9587
"source-map-loader": "^1.1.1",
9688
"stack-trace": "0.0.10",
97-
"style-loader": "^2.0.0",
98-
"terser-webpack-plugin": "^4.2.3",
99-
"typescript": "~4.6.4",
89+
"style-loader": "^3.3.1",
90+
"terser-webpack-plugin": "^5.3.0",
91+
"typescript": "^4.6.4",
10092
"update-notifier": "^5.1.0",
101-
"url-loader": "^4.1.1",
10293
"validate-npm-package-name": "^4.0.0",
103-
"webpack": "^4.44.2",
94+
"webpack": "^5.67.0",
10495
"webpack-bundle-analyzer": "^4.5.0",
10596
"webpack-dev-server": "^4.9.0",
106-
"webpack-fix-style-only-entries": "^0.6.1",
107-
"webpack-manifest-plugin": "^4.1.1",
97+
"webpack-manifest-plugin": "^5.0.0",
10898
"webpack-merge": "^5.8.0",
10999
"webpack-plugin-replace": "^1.2.0",
100+
"webpack-remove-empty-scripts": "^0.7.2",
110101
"which": "^2.0.2",
111102
"workbox-cacheable-response": "^6.5.3",
112103
"workbox-core": "^6.5.3",
@@ -120,27 +111,28 @@
120111
"@types/jest": "^24.9.1",
121112
"html-looks-like": "^1.0.2",
122113
"jest": "^24.9.0",
123-
"less": "^4.1.1",
124-
"less-loader": "^7.3.0",
114+
"less": "^4.1.3",
115+
"less-loader": "^10.2.0",
116+
"ncp": "^2.0.0",
125117
"p-retry": "^4.5.0",
126118
"polka": "^0.5.2",
127-
"preact": "^10.5.13",
128-
"preact-render-to-string": "^5.1.19",
119+
"preact": "^10.11.3",
120+
"preact-render-to-string": "^5.2.6",
129121
"preact-router": "^3.0.1",
130-
"puppeteer": "^13.7.0",
131-
"sass": "^1.34.0",
132-
"sass-loader": "^10.2.0",
133-
"shelljs": "^0.8.3",
122+
"puppeteer": "^17.1.3",
123+
"sass": "^1.56.1",
124+
"sass-loader": "^12.4.0",
125+
"shelljs": "^0.8.5",
134126
"sirv": "^1.0.11",
135-
"stylus": "^0.54.8",
136-
"stylus-loader": "^4.3.3"
127+
"stylus": "^0.59.0",
128+
"stylus-loader": "^6.2.0"
137129
},
138130
"peerDependencies": {
139-
"less-loader": "^7.3.0",
140-
"preact": "*",
141-
"preact-render-to-string": "*",
142-
"sass-loader": "^10.2.0",
143-
"stylus-loader": "^4.3.3"
131+
"less-loader": "^10.2.0",
132+
"preact": "^10.0.0",
133+
"preact-render-to-string": "^5.0.0",
134+
"sass-loader": "^12.4.0",
135+
"stylus-loader": "^6.2.0"
144136
},
145137
"peerDependenciesMeta": {
146138
"less-loader": {

packages/cli/src/index.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ prog
3737
.option('--src', 'Specify source directory', 'src')
3838
.option('--dest', 'Specify output directory', 'build')
3939
.option('--cwd', 'A directory to use instead of $PWD', '.')
40-
.option('--esm', 'Builds ES-2015 bundles for your code', true)
4140
.option('--sw', 'Generate and attach a Service Worker', true)
4241
.option('--babelConfig', 'Path to custom Babel config', '.babelrc')
4342
.option('--json', 'Generate build stats for bundle analysis', false)
@@ -89,7 +88,6 @@ prog
8988
.describe('Start a live-reload server for development')
9089
.option('--src', 'Specify source directory', 'src')
9190
.option('--cwd', 'A directory to use instead of $PWD', '.')
92-
.option('--esm', 'Builds ES-2015 bundles for your code', false)
9391
.option('--clear', 'Clears the console when the devServer updates', true)
9492
.option('--sw', 'Generate and attach a Service Worker')
9593
.option('--babelConfig', 'Path to custom Babel config', '.babelrc')

packages/cli/src/lib/babel-config.js

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,31 @@
1-
module.exports = function (env, options = {}) {
2-
const { production: isProd, refresh } = env || {};
1+
const { tryResolveConfig } = require('../util');
2+
3+
module.exports = function (env) {
4+
const { babelConfig, cwd, isProd, refresh } = env;
5+
6+
const resolvedConfig =
7+
babelConfig &&
8+
tryResolveConfig(cwd, babelConfig, babelConfig === '.babelrc');
39

410
return {
11+
babelrc: false,
12+
configFile: resolvedConfig,
513
presets: [
6-
[
14+
!isProd && [
715
require.resolve('@babel/preset-env'),
816
{
17+
loose: true,
18+
modules: false,
919
bugfixes: true,
10-
modules: options.modules || false,
1120
targets: {
12-
browsers: options.browsers,
21+
esmodules: true,
1322
},
1423
exclude: ['transform-regenerator'],
1524
},
1625
],
17-
],
26+
].filter(Boolean),
1827
plugins: [
19-
require.resolve('@babel/plugin-syntax-dynamic-import'),
20-
require.resolve('@babel/plugin-transform-object-assign'),
2128
[require.resolve('@babel/plugin-proposal-decorators'), { legacy: true }],
22-
require.resolve('@babel/plugin-proposal-class-properties'),
23-
require.resolve('@babel/plugin-proposal-object-rest-spread'),
2429
isProd &&
2530
require.resolve('babel-plugin-transform-react-remove-prop-types'),
2631
require.resolve('babel-plugin-macros'),

packages/cli/src/lib/entry.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,12 @@ if (process.env.NODE_ENV === 'development') {
1818
);
1919
} else if (process.env.ADD_SW && 'serviceWorker' in navigator) {
2020
navigator.serviceWorker.register(
21-
normalizeURL(__webpack_public_path__) +
22-
(process.env.ES_BUILD ? 'sw-esm.js' : 'sw.js')
21+
normalizeURL(__webpack_public_path__) + 'sw.js'
2322
);
2423
}
2524
} else if (process.env.ADD_SW && 'serviceWorker' in navigator) {
2625
navigator.serviceWorker.register(
27-
normalizeURL(__webpack_public_path__) +
28-
(process.env.ES_BUILD ? 'sw-esm.js' : 'sw.js')
26+
normalizeURL(__webpack_public_path__) + 'sw.js'
2927
);
3028
}
3129

packages/cli/src/lib/webpack/proxy-loader.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
var utils = require('loader-utils');
2-
31
function proxyLoader(source, map) {
4-
var options = utils.getOptions(this);
2+
var options = this.getOptions();
53

64
// First run proxy-loader run
75
if (!this.query.__proxy_loader__) {
Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,28 @@
1-
const webpack = require('webpack');
1+
const { Compilation, sources } = require('webpack');
22
const createLoadManifest = require('./create-load-manifest');
33

44
module.exports = class PushManifestPlugin {
55
constructor(isProd) {
66
this.isProd = isProd;
77
}
88
apply(compiler) {
9-
compiler.hooks.emit.tap(
10-
{
11-
name: 'PushManifestPlugin',
12-
stage: webpack.Compiler.PROCESS_ASSETS_STAGE_REPORT,
13-
},
14-
compilation => {
15-
const manifest = createLoadManifest(
16-
compilation.assets,
17-
compilation.namedChunkGroups,
18-
this.isProd
19-
);
9+
compiler.hooks.thisCompilation.tap('PushManifestPlugin', compilation => {
10+
compilation.hooks.processAssets.tap(
11+
{
12+
name: 'PushManifestPlugin',
13+
stage: Compilation.PROCESS_ASSETS_STAGE_REPORT,
14+
},
15+
() => {
16+
const manifest = JSON.stringify(
17+
createLoadManifest(compilation.assets, compilation.namedChunkGroups, this.isProd)
18+
);
2019

21-
let output = JSON.stringify(manifest);
22-
compilation.assets['push-manifest.json'] = {
23-
source() {
24-
return output;
25-
},
26-
size() {
27-
return output.length;
28-
},
29-
};
30-
31-
return compilation;
32-
33-
// callback();
34-
}
35-
);
20+
compilation.emitAsset(
21+
'push-manifest.json',
22+
new sources.RawSource(manifest)
23+
);
24+
}
25+
);
26+
});
3627
}
3728
};

0 commit comments

Comments
 (0)