From 1d66a668e134b27502aa2fdd302a7304a38f2a1b Mon Sep 17 00:00:00 2001
From: Ryan Christian <33403762+rschristian@users.noreply.github.com>
Date: Mon, 31 Jan 2022 07:51:36 -0600
Subject: [PATCH] chore: Updating webpack-dev-server (#1646)
---
.changeset/clean-kiwis-unite.md | 5 +
.../cli/lib/lib/webpack/render-html-plugin.js | 110 +-
packages/cli/lib/lib/webpack/run-webpack.js | 8 +-
.../lib/lib/webpack/webpack-client-config.js | 32 +-
packages/cli/lib/resources/body-end.ejs | 18 +-
packages/cli/lib/resources/head-end.ejs | 11 +-
packages/cli/package.json | 8 +-
.../subjects/custom-template/template.html | 6 +-
.../subjects/custom-webpack/template.html | 8 +-
yarn.lock | 1669 ++++++-----------
10 files changed, 694 insertions(+), 1181 deletions(-)
create mode 100644 .changeset/clean-kiwis-unite.md
diff --git a/.changeset/clean-kiwis-unite.md b/.changeset/clean-kiwis-unite.md
new file mode 100644
index 000000000..641bdaf0e
--- /dev/null
+++ b/.changeset/clean-kiwis-unite.md
@@ -0,0 +1,5 @@
+---
+'preact-cli': patch
+---
+
+Bumping `webpack-dev-server`
diff --git a/packages/cli/lib/lib/webpack/render-html-plugin.js b/packages/cli/lib/lib/webpack/render-html-plugin.js
index 782521a08..c649744d1 100644
--- a/packages/cli/lib/lib/webpack/render-html-plugin.js
+++ b/packages/cli/lib/lib/webpack/render-html-plugin.js
@@ -1,7 +1,9 @@
const { resolve, join } = require('path');
const os = require('os');
const { existsSync, readFileSync, writeFileSync, mkdirSync } = require('fs');
-const HtmlWebpackExcludeAssetsPlugin = require('html-webpack-exclude-assets-plugin');
+const {
+ HtmlWebpackSkipAssetsPlugin,
+} = require('html-webpack-skip-assets-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const prerender = require('./prerender');
const createLoadManifest = require('./create-load-manifest');
@@ -17,8 +19,8 @@ function read(path) {
return readFileSync(resolve(__dirname, path), 'utf-8');
}
-module.exports = async function (config) {
- const { cwd, dest, isProd, src } = config;
+module.exports = async function renderHTMLPlugin(config) {
+ const { cwd, dest, src } = config;
const inProjectTemplatePath = resolve(src, 'template.html');
let template = defaultTemplate;
if (existsSync(inProjectTemplatePath)) {
@@ -38,10 +40,7 @@ module.exports = async function (config) {
const headEnd = read('../../resources/head-end.ejs');
const bodyEnd = read('../../resources/body-end.ejs');
content = content
- .replace(
- /<%[=]?\s+preact\.title\s+%>/,
- '<%= htmlWebpackPlugin.options.title %>'
- )
+ .replace(/<%[=]?\s+preact\.title\s+%>/, '<%= cli.title %>')
.replace(/<%\s+preact\.headEnd\s+%>/, headEnd)
.replace(/<%\s+preact\.bodyEnd\s+%>/, bodyEnd);
@@ -56,53 +55,71 @@ module.exports = async function (config) {
}
const htmlWebpackConfig = values => {
- const { url, title, ...routeData } = values;
+ let { url, title, ...routeData } = values;
+
+ title =
+ title ||
+ config.title ||
+ config.manifest.name ||
+ config.manifest.short_name ||
+ (config.pkg.name || '').replace(/^@[a-z]\//, '') ||
+ 'Preact App';
+
// Do not create a folder if the url is for a specific file.
const filename = url.endsWith('.html')
? resolve(dest, url.substring(1))
: resolve(dest, url.substring(1), 'index.html');
- return Object.assign(values, {
+
+ return {
+ title,
filename,
template: `!!${require.resolve('ejs-loader')}?esModule=false!${template}`,
- minify: isProd && {
- collapseWhitespace: true,
- removeScriptTypeAttributes: true,
- removeRedundantAttributes: true,
- removeStyleLinkTypeAttributes: true,
- removeComments: true,
+ templateParameters: (compilation, assets, assetTags, options) => {
+ let entrypoints = {};
+ compilation.entrypoints.forEach((entrypoint, name) => {
+ let entryFiles = entrypoint.getFiles();
+ entrypoints[name] =
+ assets.publicPath +
+ entryFiles.find(file => /\.(m?js)(\?|$)/.test(file));
+ });
+
+ let loadManifest = compilation.assets['push-manifest.json']
+ ? JSON.parse(compilation.assets['push-manifest.json'].source())
+ : createLoadManifest(
+ compilation.assets,
+ config.esm,
+ compilation.namedChunkGroups
+ );
+
+ return {
+ cli: {
+ title,
+ url,
+ manifest: config.manifest,
+ inlineCss: config['inline-css'],
+ preload: config.preload,
+ config,
+ preRenderData: values,
+ CLI_DATA: { preRenderData: { url, ...routeData } },
+ ssr: config.prerender ? prerender({ cwd, dest, src }, values) : '',
+ loadManifest,
+ entrypoints,
+ },
+ htmlWebpackPlugin: {
+ tags: assetTags,
+ files: assets,
+ options: options,
+ },
+ };
},
+ inject: true,
+ scriptLoading: 'defer',
favicon: existsSync(resolve(src, 'assets/favicon.ico'))
? 'assets/favicon.ico'
: '',
- inject: true,
- compile: true,
- inlineCss: config['inline-css'],
- preload: config.preload,
- manifest: config.manifest,
- title:
- title ||
- config.title ||
- config.manifest.name ||
- config.manifest.short_name ||
- (config.pkg.name || '').replace(/^@[a-z]\//, '') ||
- 'Preact App',
excludeAssets: [/(bundle|polyfills)(\..*)?\.js$/],
- createLoadManifest: (assets, namedChunkGroups) => {
- if (assets['push-manifest.json']) {
- return JSON.parse(assets['push-manifest.json'].source());
- }
- return createLoadManifest(assets, config.esm, namedChunkGroups);
- },
- config,
- url,
- ssr() {
- return config.prerender && url !== PREACT_FALLBACK_URL
- ? prerender({ cwd, dest, src }, values)
- : '';
- },
- scriptLoading: 'defer',
- CLI_DATA: { preRenderData: { url, ...routeData } },
- });
+ // excludeChunks: ['bundle', 'polyfills']
+ };
};
let pages = [{ url: '/' }];
@@ -158,7 +175,7 @@ module.exports = async function (config) {
const resultPages = pages
.map(htmlWebpackConfig)
.map(conf => new HtmlWebpackPlugin(conf))
- .concat([new HtmlWebpackExcludeAssetsPlugin()]);
+ .concat([new HtmlWebpackSkipAssetsPlugin()]);
return config.prerender
? resultPages.concat([
@@ -170,10 +187,9 @@ module.exports = async function (config) {
// Adds a preact_prerender_data in every folder so that the data could be fetched separately.
class PrerenderDataExtractPlugin {
constructor(page) {
- const cliData = page.CLI_DATA || {};
- const { url } = cliData.preRenderData || {};
+ const url = page.url;
this.location_ = url.endsWith('/') ? url : url + '/';
- this.data_ = JSON.stringify(cliData.preRenderData || {});
+ this.data_ = JSON.stringify(page || {});
}
apply(compiler) {
compiler.hooks.emit.tap('PrerenderDataExtractPlugin', compilation => {
diff --git a/packages/cli/lib/lib/webpack/run-webpack.js b/packages/cli/lib/lib/webpack/run-webpack.js
index 7dec61081..735ab4a38 100644
--- a/packages/cli/lib/lib/webpack/run-webpack.js
+++ b/packages/cli/lib/lib/webpack/run-webpack.js
@@ -61,12 +61,8 @@ async function devBuild(env) {
compiler.hooks.failed.tap('CliDevPlugin', rej);
- let c = Object.assign({}, config.devServer, {
- stats: { colors: true },
- });
-
- let server = new DevServer(compiler, c);
- server.listen(env.port);
+ let server = new DevServer(config.devServer, compiler);
+ server.start();
res(server);
});
}
diff --git a/packages/cli/lib/lib/webpack/webpack-client-config.js b/packages/cli/lib/lib/webpack/webpack-client-config.js
index 803b2fc61..31e906621 100644
--- a/packages/cli/lib/lib/webpack/webpack-client-config.js
+++ b/packages/cli/lib/lib/webpack/webpack-client-config.js
@@ -163,8 +163,8 @@ function getBabelEsmPlugin(config) {
: '[name].esm.js',
chunkFilename: '[name].chunk.[chunkhash:5].esm.js',
excludedPlugins: ['BabelEsmPlugin', 'InjectManifest'],
- beforeStartExecution: (plugins) => {
- plugins.forEach((plugin) => {
+ beforeStartExecution: plugins => {
+ plugins.forEach(plugin => {
if (
plugin.constructor.name === 'DefinePlugin' &&
plugin.definitions
@@ -278,9 +278,11 @@ function isDev(config) {
const { cwd, src, refresh } = config;
return {
+ infrastructureLogging: {
+ level: 'info',
+ },
plugins: [
new webpack.NamedModulesPlugin(),
- new webpack.HotModuleReplacementPlugin(),
...(refresh ? [new RefreshPlugin()] : []),
new webpack.DefinePlugin({
'process.env.ADD_SW': config.sw,
@@ -289,22 +291,26 @@ function isDev(config) {
],
devServer: {
- inline: true,
hot: true,
compress: true,
- publicPath: '/',
- contentBase: src,
+ devMiddleware: {
+ publicPath: '/',
+ stats: 'errors-warnings',
+ },
+ static: {
+ directory: src,
+ watch: {
+ ignored: [resolve(cwd, 'build'), resolve(cwd, 'node_modules')],
+ },
+ },
https: config.https,
port: config.port,
host: process.env.HOST || config.host || '0.0.0.0',
- disableHostCheck: true,
+ allowedHosts: 'all',
historyApiFallback: true,
- quiet: true,
- clientLogLevel: 'none',
- overlay: false,
- stats: 'minimal',
- watchOptions: {
- ignored: [resolve(cwd, 'build'), resolve(cwd, 'node_modules')],
+ client: {
+ logging: 'none',
+ overlay: false,
},
},
};
diff --git a/packages/cli/lib/resources/body-end.ejs b/packages/cli/lib/resources/body-end.ejs
index 902141242..0444b0725 100644
--- a/packages/cli/lib/resources/body-end.ejs
+++ b/packages/cli/lib/resources/body-end.ejs
@@ -1,18 +1,18 @@
-<%= htmlWebpackPlugin.options.ssr() %>
-<% if (htmlWebpackPlugin.options.config.prerender === true) { %>
+<%= cli.ssr %>
+<% if (cli.config.prerender === true) { %>
<% } %>
-<% if (webpack.assets.filter(entry => entry.name.match(/bundle(\.\w{5})?.esm.js$/)).length > 0) { %>
-
+<% if (htmlWebpackPlugin.files.js.filter(entry => entry.match(/bundle(\.\w{5})?.esm.js$/)).length > 0) { %>
+
<%
/*Fetch and Promise polyfills are not needed for browsers that support type=module
Please re-evaluate below line if adding more polyfills.*/
%>
-
-
+
+
<% } else { %>
-
-
+
+
<% } %>
diff --git a/packages/cli/lib/resources/head-end.ejs b/packages/cli/lib/resources/head-end.ejs
index b5bb729aa..8ca472a8b 100644
--- a/packages/cli/lib/resources/head-end.ejs
+++ b/packages/cli/lib/resources/head-end.ejs
@@ -1,11 +1,10 @@
-<% if (htmlWebpackPlugin.options.manifest.theme_color) { %>
-
+<% if (cli.manifest.theme_color) { %>
+
<% } %>
-<% const loadManifest = htmlWebpackPlugin.options.createLoadManifest(compilation.assets, webpack.namedChunkGroups);%>
-<% const filesRegexp = htmlWebpackPlugin.options.inlineCss ? /\.(chunk\.\w{5}\.css|js)$/ : /\.(css|js)$/;%>
-<% for (const file in loadManifest[htmlWebpackPlugin.options.url]) { %>
- <% if (htmlWebpackPlugin.options.preload && file && file.match(filesRegexp)) { %>
+<% const filesRegexp = cli.inlineCss ? /\.(chunk\.\w{5}\.css|js)$/ : /\.(css|js)$/;%>
+<% for (const file in cli.loadManifest[cli.url]) { %>
+ <% if (cli.preload && file && file.match(filesRegexp)) { %>
<% /* crossorigin for main bundle as that is loaded from `
+ <%= cli.ssr %>
+