From 3d01e6b464bffdc72578f0d4ca47e62385f2160a Mon Sep 17 00:00:00 2001 From: Tavian Taylor Date: Tue, 14 Oct 2025 14:37:18 +0100 Subject: [PATCH 1/4] Optimize webpack files --- packages/stacks-classic/webpack.config.js | 46 +++------------------ packages/stacks-docs/webpack.config.js | 39 +++--------------- webpack-common.js | 49 +++++++++++++++++++++++ 3 files changed, 60 insertions(+), 74 deletions(-) create mode 100644 webpack-common.js diff --git a/packages/stacks-classic/webpack.config.js b/packages/stacks-classic/webpack.config.js index f205af9d41..7032e845b1 100644 --- a/packages/stacks-classic/webpack.config.js +++ b/packages/stacks-classic/webpack.config.js @@ -1,5 +1,5 @@ const path = require("path"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const { tsRule, lessRule, miniCssPlugin, commonResolve } = require("../../webpack-common"); const baseConfig = (isProd, minify) => ({ name: "stacks" + (minify ? ".min" : ""), @@ -22,53 +22,17 @@ const baseConfig = (isProd, minify) => ({ }, module: { rules: [ - { - test: /\.tsx?$/, - exclude: /node_modules/, - use: [ - { - loader: "ts-loader", - options: { - configFile: "tsconfig.build.json", - }, - }, - ], - }, - { - test: /\.less$/, - use: [ - isProd ? MiniCssExtractPlugin.loader : "", - { - loader: "css-loader", - options: { - importLoaders: 1, - url: false, - }, - }, - { - loader: "postcss-loader", - options: { - postcssOptions: { - plugins: minify ? [require("cssnano")] : [], - }, - }, - }, - "less-loader", - ], - }, + tsRule("tsconfig.build.json"), + lessRule(minify), ], }, optimization: { minimize: minify, }, plugins: [ - new MiniCssExtractPlugin({ - filename: `css/[name].css`, - }), + miniCssPlugin(`css/[name].css`), ], - resolve: { - extensions: [".tsx", ".ts", ".js"], - }, + resolve: commonResolve, }); // build the bundle twice - once minified and once not diff --git a/packages/stacks-docs/webpack.config.js b/packages/stacks-docs/webpack.config.js index 4f6b212a06..efd10ba388 100644 --- a/packages/stacks-docs/webpack.config.js +++ b/packages/stacks-docs/webpack.config.js @@ -1,6 +1,6 @@ const fs = require("fs"); const path = require("path"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const { tsRule, lessRule, miniCssPlugin, commonResolve, commonDevServer } = require("../../webpack-common"); module.exports = (_, argv) => { const isProd = argv.mode === "production" @@ -28,41 +28,14 @@ module.exports = (_, argv) => { }, module: { rules: [ - { - test: /\.tsx?$/, - exclude: /node_modules/, - use: [ - "ts-loader", - ], - }, - { - test: /\.less$/, - use: [ - isProd ? MiniCssExtractPlugin.loader : "", - { - loader: "css-loader", - options: { - importLoaders: 1, - url: false, - }, - }, - "postcss-loader", - "less-loader", - ], - }, + tsRule(), // no special config file here + lessRule(isProd), ], }, plugins: [ - new MiniCssExtractPlugin() + miniCssPlugin(), ], - resolve: { - extensions: [".tsx", ".ts", ".js"], - }, - devServer: { - webSocketURL: { - // 11ty/browsersync steal the default port (8080), so set it to something else - port: 8081 - } - } + resolve: commonResolve, + devServer: commonDevServer, }; }; diff --git a/webpack-common.js b/webpack-common.js new file mode 100644 index 0000000000..897a15ec35 --- /dev/null +++ b/webpack-common.js @@ -0,0 +1,49 @@ +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); + +exports.tsRule = (configFile) => ({ + test: /\.tsx?$/, + exclude: /node_modules/, + use: [ + { + loader: "ts-loader", + options: configFile ? { configFile } : {}, + }, + ], +}); + +exports.lessRule = (minify = false) => ({ + test: /\.less$/, + use: [ + MiniCssExtractPlugin.loader, + { + loader: "css-loader", + options: { + importLoaders: 1, + url: false, + }, + }, + { + loader: "postcss-loader", + options: { + postcssOptions: { + plugins: minify ? [require("cssnano")] : [], + }, + }, + }, + "less-loader", + ], +}); + +exports.miniCssPlugin = (filename = "css/[name].css") => + new MiniCssExtractPlugin({ filename }); + +exports.commonResolve = { + extensions: [".tsx", ".ts", ".js"], +}; + +exports.commonDevServer = { + webSocketURL: { + // 11ty/browsersync steal the default port (8080), so set it to something else + port: 8081, + }, +}; \ No newline at end of file From 51050e7364ae3946bc32c4876e44a871255ffeb4 Mon Sep 17 00:00:00 2001 From: Tavian Taylor Date: Tue, 14 Oct 2025 16:35:43 +0100 Subject: [PATCH 2/4] upgrade webpack config files to ECMA script --- packages/stacks-classic/webpack.config.js | 42 -------- packages/stacks-classic/webpack.config.mjs | 96 +++++++++++++++++++ .../{webpack.config.js => webpack.config.mjs} | 39 +++++--- webpack-common.js | 49 ---------- 4 files changed, 123 insertions(+), 103 deletions(-) delete mode 100644 packages/stacks-classic/webpack.config.js create mode 100644 packages/stacks-classic/webpack.config.mjs rename packages/stacks-docs/{webpack.config.js => webpack.config.mjs} (50%) diff --git a/packages/stacks-classic/webpack.config.js b/packages/stacks-classic/webpack.config.js deleted file mode 100644 index 7032e845b1..0000000000 --- a/packages/stacks-classic/webpack.config.js +++ /dev/null @@ -1,42 +0,0 @@ -const path = require("path"); -const { tsRule, lessRule, miniCssPlugin, commonResolve } = require("../../webpack-common"); - -const baseConfig = (isProd, minify) => ({ - name: "stacks" + (minify ? ".min" : ""), - // run the minified bundle first, then the unminified bundle - dependencies: minify ? [] : ["stacks.min"], - mode: isProd ? "production" : "development", - devtool: isProd ? false : "inline-source-map", - entry: { - // add .min to the file names of minified bundles - [minify ? "stacks.min" : "stacks"]: path.resolve(__dirname, "lib/index.ts"), - }, - output: { - filename: `js/[name].js`, - path: path.resolve(__dirname, "dist"), - // don't empty out the dist folder when running the second build - clean: minify, - compareBeforeEmit: true, - library: "Stacks", - libraryTarget: "umd", - }, - module: { - rules: [ - tsRule("tsconfig.build.json"), - lessRule(minify), - ], - }, - optimization: { - minimize: minify, - }, - plugins: [ - miniCssPlugin(`css/[name].css`), - ], - resolve: commonResolve, -}); - -// build the bundle twice - once minified and once not -module.exports = [ - (_, argv) => baseConfig(isProd = argv.mode === "production", true), - (_, argv) => baseConfig(isProd = argv.mode === "production", false), -]; diff --git a/packages/stacks-classic/webpack.config.mjs b/packages/stacks-classic/webpack.config.mjs new file mode 100644 index 0000000000..3430261530 --- /dev/null +++ b/packages/stacks-classic/webpack.config.mjs @@ -0,0 +1,96 @@ +import path from "path" +import MiniCssExtractPlugin from 'mini-css-extract-plugin'; +import cssnano from 'cssnano' +import { fileURLToPath } from 'node:url'; +import { dirname } from 'node:path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const tsRule = (configFile) => ({ + test: /\.tsx?$/, + exclude: /node_modules/, + use: [ + { + loader: "ts-loader", + options: configFile ? { configFile } : {}, + }, + ], +}); + +const lessRule = (minify = false) => ({ + test: /\.less$/, + use: [ + MiniCssExtractPlugin.loader, + { + loader: "css-loader", + options: { + importLoaders: 1, + url: false, + }, + }, + { + loader: "postcss-loader", + options: { + postcssOptions: { + plugins: minify ? [cssnano] : [], + }, + }, + }, + "less-loader", + ], +}); + +const miniCssPlugin = (filename = "css/[name].css") => + new MiniCssExtractPlugin({ filename }); + +const commonResolve = { + extensions: [".tsx", ".ts", ".js"], +}; + +const baseConfig = (isProd, minify) => ({ + name: "stacks" + (minify ? ".min" : ""), + // run the minified bundle first, then the unminified bundle + dependencies: minify ? [] : ["stacks.min"], + mode: isProd ? "production" : "development", + devtool: isProd ? false : "inline-source-map", + entry: { + // add .min to the file names of minified bundles + [minify ? "stacks.min" : "stacks"]: path.resolve(__dirname, "lib/index.ts"), + }, + output: { + filename: `js/[name].js`, + path: path.resolve(__dirname, "dist"), + // don't empty out the dist folder when running the second build + clean: minify, + compareBeforeEmit: true, + library: "Stacks", + libraryTarget: "umd", + }, + module: { + rules: [ + tsRule("tsconfig.build.json"), + lessRule(minify), + ], + }, + optimization: { + minimize: minify, + }, + plugins: [ + miniCssPlugin(`css/[name].css`), + ], + resolve: commonResolve, +}); + +export { + tsRule, + lessRule, + miniCssPlugin, + commonResolve, +} + +// build the bundle twice - once minified and once not +export default [ + (_, argv) => baseConfig(argv.mode === "production", true), + (_, argv) => baseConfig(argv.mode === "production", false), +]; diff --git a/packages/stacks-docs/webpack.config.js b/packages/stacks-docs/webpack.config.mjs similarity index 50% rename from packages/stacks-docs/webpack.config.js rename to packages/stacks-docs/webpack.config.mjs index efd10ba388..d6d6d6f76b 100644 --- a/packages/stacks-docs/webpack.config.js +++ b/packages/stacks-docs/webpack.config.mjs @@ -1,13 +1,25 @@ -const fs = require("fs"); -const path = require("path"); -const { tsRule, lessRule, miniCssPlugin, commonResolve, commonDevServer } = require("../../webpack-common"); +import path from "path"; +import fs from "fs"; +import { + tsRule, + lessRule, + miniCssPlugin, + commonResolve, +} from "../stacks-classic/webpack.config.mjs"; -module.exports = (_, argv) => { - const isProd = argv.mode === "production" +import { fileURLToPath } from 'node:url'; +import { dirname } from 'node:path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +export default (_, argv) => { + const isProd = argv.mode === "production"; // load each entry.*.js file in assets/js as its own bundle - const entries = fs.readdirSync(path.resolve(__dirname, "assets/js/")) - .filter(f => f.startsWith("entry.")) + const entries = fs + .readdirSync(path.resolve(__dirname, "assets/js/")) + .filter((f) => f.startsWith("entry.")) .reduce((p, n) => { // { "entry.file": "path/to/entry.file.js" } p[n.slice(0, -3)] = path.resolve(__dirname, "assets/js/", n); @@ -19,7 +31,7 @@ module.exports = (_, argv) => { devtool: isProd ? false : "inline-source-map", entry: { docs: path.resolve(__dirname, "assets/js/index.ts"), - ...entries + ...entries, }, output: { filename: "[name].js", @@ -32,10 +44,13 @@ module.exports = (_, argv) => { lessRule(isProd), ], }, - plugins: [ - miniCssPlugin(), - ], + plugins: [miniCssPlugin()], resolve: commonResolve, - devServer: commonDevServer, + devServer: { + webSocketURL: { + // 11ty/browsersync steal the default port (8080), so set it to something else + port: 8081, + }, + }, }; }; diff --git a/webpack-common.js b/webpack-common.js index 897a15ec35..e69de29bb2 100644 --- a/webpack-common.js +++ b/webpack-common.js @@ -1,49 +0,0 @@ -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); - -exports.tsRule = (configFile) => ({ - test: /\.tsx?$/, - exclude: /node_modules/, - use: [ - { - loader: "ts-loader", - options: configFile ? { configFile } : {}, - }, - ], -}); - -exports.lessRule = (minify = false) => ({ - test: /\.less$/, - use: [ - MiniCssExtractPlugin.loader, - { - loader: "css-loader", - options: { - importLoaders: 1, - url: false, - }, - }, - { - loader: "postcss-loader", - options: { - postcssOptions: { - plugins: minify ? [require("cssnano")] : [], - }, - }, - }, - "less-loader", - ], -}); - -exports.miniCssPlugin = (filename = "css/[name].css") => - new MiniCssExtractPlugin({ filename }); - -exports.commonResolve = { - extensions: [".tsx", ".ts", ".js"], -}; - -exports.commonDevServer = { - webSocketURL: { - // 11ty/browsersync steal the default port (8080), so set it to something else - port: 8081, - }, -}; \ No newline at end of file From 6a34185ab22cca5eba37bd82e2e7ccd426305ed8 Mon Sep 17 00:00:00 2001 From: Tavian Taylor Date: Tue, 14 Oct 2025 17:01:43 +0100 Subject: [PATCH 3/4] Delete webpack-common.js --- webpack-common.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 webpack-common.js diff --git a/webpack-common.js b/webpack-common.js deleted file mode 100644 index e69de29bb2..0000000000 From 79bb17b96c908b538ff32a5a7e8cbaf481b9dc05 Mon Sep 17 00:00:00 2001 From: Giamir Buoncristiani Date: Tue, 14 Oct 2025 18:34:24 +0200 Subject: [PATCH 4/4] fix incorrect extraction of docs.css for stacks docs --- packages/stacks-classic/webpack.config.mjs | 24 ++++++++-------------- packages/stacks-docs/webpack.config.mjs | 8 ++++---- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/packages/stacks-classic/webpack.config.mjs b/packages/stacks-classic/webpack.config.mjs index 3430261530..3ad4cb9c23 100644 --- a/packages/stacks-classic/webpack.config.mjs +++ b/packages/stacks-classic/webpack.config.mjs @@ -41,9 +41,6 @@ const lessRule = (minify = false) => ({ ], }); -const miniCssPlugin = (filename = "css/[name].css") => - new MiniCssExtractPlugin({ filename }); - const commonResolve = { extensions: [".tsx", ".ts", ".js"], }; @@ -56,7 +53,10 @@ const baseConfig = (isProd, minify) => ({ devtool: isProd ? false : "inline-source-map", entry: { // add .min to the file names of minified bundles - [minify ? "stacks.min" : "stacks"]: path.resolve(__dirname, "lib/index.ts"), + [minify ? "stacks.min" : "stacks"]: path.resolve( + __dirname, + "lib/index.ts" + ), }, output: { filename: `js/[name].js`, @@ -68,26 +68,20 @@ const baseConfig = (isProd, minify) => ({ libraryTarget: "umd", }, module: { - rules: [ - tsRule("tsconfig.build.json"), - lessRule(minify), - ], + rules: [tsRule("tsconfig.build.json"), lessRule(minify)], }, optimization: { minimize: minify, }, plugins: [ - miniCssPlugin(`css/[name].css`), + new MiniCssExtractPlugin({ + filename: `css/[name].css`, + }), ], resolve: commonResolve, }); -export { - tsRule, - lessRule, - miniCssPlugin, - commonResolve, -} +export { tsRule, lessRule, commonResolve }; // build the bundle twice - once minified and once not export default [ diff --git a/packages/stacks-docs/webpack.config.mjs b/packages/stacks-docs/webpack.config.mjs index d6d6d6f76b..42342b4780 100644 --- a/packages/stacks-docs/webpack.config.mjs +++ b/packages/stacks-docs/webpack.config.mjs @@ -3,12 +3,12 @@ import fs from "fs"; import { tsRule, lessRule, - miniCssPlugin, commonResolve, } from "../stacks-classic/webpack.config.mjs"; +import MiniCssExtractPlugin from "mini-css-extract-plugin"; -import { fileURLToPath } from 'node:url'; -import { dirname } from 'node:path'; +import { fileURLToPath } from "node:url"; +import { dirname } from "node:path"; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); @@ -44,7 +44,7 @@ export default (_, argv) => { lessRule(isProd), ], }, - plugins: [miniCssPlugin()], + plugins: [new MiniCssExtractPlugin()], resolve: commonResolve, devServer: { webSocketURL: {