From 71e059afa16271058ce9149f74adb9e99898e10f Mon Sep 17 00:00:00 2001 From: Mohamed Shams El-Deen Date: Mon, 17 Aug 2026 23:50:34 +0300 Subject: [PATCH 1/3] feat(ui): add StackBlitzPreview component & replace TODOs with it --- components/StackBlitzPreview/index.jsx | 23 ++++++++++ components/StackBlitzPreview/index.module.css | 43 +++++++++++++++++++ .../concepts/module-federation.md | 3 +- pages/guides/getting-started/index.md | 3 +- public/assets/open-in-stackblitz-button.svg | 1 + scripts/html/doc-kit.config.mjs | 5 +++ 6 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 components/StackBlitzPreview/index.jsx create mode 100644 components/StackBlitzPreview/index.module.css create mode 100644 public/assets/open-in-stackblitz-button.svg diff --git a/components/StackBlitzPreview/index.jsx b/components/StackBlitzPreview/index.jsx new file mode 100644 index 00000000..b7a82964 --- /dev/null +++ b/components/StackBlitzPreview/index.jsx @@ -0,0 +1,23 @@ +import styles from './index.module.css'; + +export default function StackBlitzPreview(props = {}) { + const { + example = '', + description = 'Check out this guide live on StackBlitz.', + } = props; + + const url = `https://stackblitz.com/github/webpack/webpack-doc-kit/tree/main/examples/${example}`; + + return ( + + ); +} diff --git a/components/StackBlitzPreview/index.module.css b/components/StackBlitzPreview/index.module.css new file mode 100644 index 00000000..a8b89c82 --- /dev/null +++ b/components/StackBlitzPreview/index.module.css @@ -0,0 +1,43 @@ +@reference "../../styles/index.css"; + +.preview { + @apply px-6 + py-5 + my-6 + bg-neutral-100 + dark:bg-neutral-900 + border-l-[3px] + border-blue-600 + dark:border-blue-500 + text-neutral-900 + dark:text-neutral-50 + rounded-r-md; +} + +.previewPrefix { + @apply capitalize + font-semibold + block + text-base + mt-0 + mb-2 + text-neutral-700 + dark:text-neutral-400; +} + +.preview p { + @apply mt-0 + mb-5; +} + +.preview a { + @apply inline-block + transition-opacity + hover:opacity-80; +} + +.preview img { + @apply block + w-auto + h-auto; +} diff --git a/pages/guides/getting-started/concepts/module-federation.md b/pages/guides/getting-started/concepts/module-federation.md index 453361f6..8ff39fa9 100644 --- a/pages/guides/getting-started/concepts/module-federation.md +++ b/pages/guides/getting-started/concepts/module-federation.md @@ -1,6 +1,7 @@ --- title: Module Federation authors: sokra,chenxsan,EugeneHlushko,jamesgeorge007,ScriptedAlchemy,snitin315,XiaofengXie16,KyleBastien,Alevale,burhanuday,RexSkz,avivkeller +mdx: true --- # Module Federation @@ -11,7 +12,7 @@ Multiple separate builds should be able to form a single application. These sepa This is often called Micro-Frontends, but it is not limited to that pattern. - + ## Low-level concepts diff --git a/pages/guides/getting-started/index.md b/pages/guides/getting-started/index.md index 8938dec5..a7d9cd5e 100644 --- a/pages/guides/getting-started/index.md +++ b/pages/guides/getting-started/index.md @@ -1,6 +1,7 @@ --- title: Getting Started authors: bebraw,varunjayaraman,cntanglijun,chrisVillanueva,johnstew,simon04,aaronang,TheDutchCoder,sudarsangp,Vanguard90,chenxsan,EugeneHlushko,ATGardner,ayvarot,bjarki,ztomasze,Spiral90210,byzyk,wizardofhogwarts,myshov,anshumanv,d3lm,snitin315,Etheryen,zowiebeha,avivkeller,alexander-akait +mdx: true --- # Getting Started @@ -12,7 +13,7 @@ webpack is used to efficiently compile JavaScript modules. Once [installed](/gui > [!WARNING] > The examples in this guide use `webpack-cli` 7, which requires Node.js 20.9.0 or later. - + ## Quick start (minimal working example) diff --git a/public/assets/open-in-stackblitz-button.svg b/public/assets/open-in-stackblitz-button.svg new file mode 100644 index 00000000..d85bc3b2 --- /dev/null +++ b/public/assets/open-in-stackblitz-button.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/scripts/html/doc-kit.config.mjs b/scripts/html/doc-kit.config.mjs index 0782bd5a..2c4c48e7 100644 --- a/scripts/html/doc-kit.config.mjs +++ b/scripts/html/doc-kit.config.mjs @@ -114,6 +114,10 @@ export default { 'components/HomePage/HomeSponsorSection/index.jsx' ), '#theme/Sponsors/Board': join(ROOT, 'layouts/Sponsors/Board.jsx'), + '#theme/StackBlitzPreview': join( + ROOT, + 'components/StackBlitzPreview/index.jsx' + ), }, components: { @@ -124,6 +128,7 @@ export default { BlogLayout: '#theme/BlogLayout', Byline: '#theme/Blog/Byline', MetaBar: '#theme/Metabar', + StackBlitzPreview: '#theme/StackBlitzPreview', }, bundler: createViteBundler({ plugins: [tailwindcss()], From 76b5a1142a6a8fb5f08303d463ebfc803f582abc Mon Sep 17 00:00:00 2001 From: Mohamed Shams El-Deen Date: Mon, 17 Aug 2026 23:51:15 +0300 Subject: [PATCH 2/3] chore: migrate examples directory from webpack.js.org --- eslint.config.mjs | 1 + examples/getting-started/README.md | 11 +++++ examples/getting-started/dist/index.html | 10 +++++ examples/getting-started/package.json | 21 ++++++++++ examples/getting-started/src/index.js | 12 ++++++ examples/getting-started/webpack.config.js | 9 ++++ examples/module-federation/README.md | 19 +++++++++ examples/module-federation/app1/package.json | 24 +++++++++++ .../module-federation/app1/public/index.html | 10 +++++ examples/module-federation/app1/src/App.js | 24 +++++++++++ .../module-federation/app1/src/bootstrap.js | 5 +++ examples/module-federation/app1/src/index.js | 5 +++ .../module-federation/app1/webpack.config.js | 41 +++++++++++++++++++ examples/module-federation/app2/package.json | 23 +++++++++++ .../module-federation/app2/public/index.html | 10 +++++ examples/module-federation/app2/src/App.js | 18 ++++++++ .../module-federation/app2/src/bootstrap.js | 6 +++ examples/module-federation/app2/src/index.js | 1 + .../module-federation/app2/webpack.config.js | 41 +++++++++++++++++++ examples/module-federation/lerna.json | 5 +++ examples/module-federation/package.json | 17 ++++++++ 21 files changed, 313 insertions(+) create mode 100644 examples/getting-started/README.md create mode 100644 examples/getting-started/dist/index.html create mode 100644 examples/getting-started/package.json create mode 100644 examples/getting-started/src/index.js create mode 100644 examples/getting-started/webpack.config.js create mode 100644 examples/module-federation/README.md create mode 100644 examples/module-federation/app1/package.json create mode 100644 examples/module-federation/app1/public/index.html create mode 100644 examples/module-federation/app1/src/App.js create mode 100644 examples/module-federation/app1/src/bootstrap.js create mode 100644 examples/module-federation/app1/src/index.js create mode 100644 examples/module-federation/app1/webpack.config.js create mode 100644 examples/module-federation/app2/package.json create mode 100644 examples/module-federation/app2/public/index.html create mode 100644 examples/module-federation/app2/src/App.js create mode 100644 examples/module-federation/app2/src/bootstrap.js create mode 100644 examples/module-federation/app2/src/index.js create mode 100644 examples/module-federation/app2/webpack.config.js create mode 100644 examples/module-federation/lerna.json create mode 100644 examples/module-federation/package.json diff --git a/eslint.config.mjs b/eslint.config.mjs index d8c9f875..7cd6ace1 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -29,6 +29,7 @@ export default [ 'out/', '.cache/', 'webpack/', + 'examples/', 'pages/api', 'pages/docs/api', 'pages/docs/loaders', diff --git a/examples/getting-started/README.md b/examples/getting-started/README.md new file mode 100644 index 00000000..e081fd3f --- /dev/null +++ b/examples/getting-started/README.md @@ -0,0 +1,11 @@ +# Getting Started + +## How to use + +Run the following commands in the root directory. + +```bash +npm install +npm run build +npm run start +``` diff --git a/examples/getting-started/dist/index.html b/examples/getting-started/dist/index.html new file mode 100644 index 00000000..6a86be35 --- /dev/null +++ b/examples/getting-started/dist/index.html @@ -0,0 +1,10 @@ + + + + + Getting Started + + + + + diff --git a/examples/getting-started/package.json b/examples/getting-started/package.json new file mode 100644 index 00000000..be78e79f --- /dev/null +++ b/examples/getting-started/package.json @@ -0,0 +1,21 @@ +{ + "name": "getting-started-using-a-configuration", + "version": "1.0.0", + "private": true, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "webpack", + "start": "serve dist" + }, + "keywords": [], + "author": "", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21" + }, + "devDependencies": { + "serve": "^12.0.0", + "webpack": "^5.38.1", + "webpack-cli": "^4.7.2" + } +} diff --git a/examples/getting-started/src/index.js b/examples/getting-started/src/index.js new file mode 100644 index 00000000..5426945c --- /dev/null +++ b/examples/getting-started/src/index.js @@ -0,0 +1,12 @@ +import _ from 'lodash'; + +function component() { + const element = document.createElement('div'); + + // Lodash, now imported by this script + element.innerHTML = _.join(['Hello', 'webpack'], ' '); + + return element; +} + +document.body.appendChild(component()); diff --git a/examples/getting-started/webpack.config.js b/examples/getting-started/webpack.config.js new file mode 100644 index 00000000..655b2948 --- /dev/null +++ b/examples/getting-started/webpack.config.js @@ -0,0 +1,9 @@ +const path = require('path'); + +module.exports = { + entry: './src/index.js', + output: { + filename: 'main.js', + path: path.resolve(__dirname, 'dist'), + }, +}; diff --git a/examples/module-federation/README.md b/examples/module-federation/README.md new file mode 100644 index 00000000..cfd1cf5d --- /dev/null +++ b/examples/module-federation/README.md @@ -0,0 +1,19 @@ +# Module Federation + +## How to use + +Run the following commands in the root directory. + +```bash +npm install +npm start +``` + +Both `app1` and `app2` are independently deployed apps: + +- `app1`: http://localhost:3001 +- `app2`: http://localhost:3002 + +Check out this link below for more examples: + +[https://github.com/module-federation/module-federation-examples](https://github.com/module-federation/module-federation-examples) diff --git a/examples/module-federation/app1/package.json b/examples/module-federation/app1/package.json new file mode 100644 index 00000000..09f36053 --- /dev/null +++ b/examples/module-federation/app1/package.json @@ -0,0 +1,24 @@ +{ + "name": "app1", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "scripts": { + "start": "webpack serve", + "build": "webpack --mode production" + }, + "dependencies": { + "react": "^17.0.2", + "react-dom": "^17.0.2" + }, + "devDependencies": { + "@babel/core": "^7.14.3", + "@babel/preset-react": "^7.13.13", + "babel-loader": "^8.2.2", + "external-remotes-plugin": "^1.0.0", + "html-webpack-plugin": "^5.3.1", + "webpack": "^5.38.1", + "webpack-cli": "^4.7.2", + "webpack-dev-server": "^4.0.0" + } +} diff --git a/examples/module-federation/app1/public/index.html b/examples/module-federation/app1/public/index.html new file mode 100644 index 00000000..05048d70 --- /dev/null +++ b/examples/module-federation/app1/public/index.html @@ -0,0 +1,10 @@ + + + + + App 1 + + +
+ + diff --git a/examples/module-federation/app1/src/App.js b/examples/module-federation/app1/src/App.js new file mode 100644 index 00000000..299c3c34 --- /dev/null +++ b/examples/module-federation/app1/src/App.js @@ -0,0 +1,24 @@ +import React, { Suspense } from 'react'; +const RemoteApp = React.lazy(() => import('app2/App')); + +const App = () => { + return ( +
+
+

App1

+
+ + + +
+ ); +}; + +export default App; diff --git a/examples/module-federation/app1/src/bootstrap.js b/examples/module-federation/app1/src/bootstrap.js new file mode 100644 index 00000000..a8680f71 --- /dev/null +++ b/examples/module-federation/app1/src/bootstrap.js @@ -0,0 +1,5 @@ +import App from './App'; +import React from 'react'; +import ReactDOM from 'react-dom'; + +ReactDOM.render(, document.getElementById('root')); diff --git a/examples/module-federation/app1/src/index.js b/examples/module-federation/app1/src/index.js new file mode 100644 index 00000000..71914b09 --- /dev/null +++ b/examples/module-federation/app1/src/index.js @@ -0,0 +1,5 @@ +// You can write your own logic here to determine the actual url +window.app2Url = 'http://localhost:3002'; + +// Use dynamic import here to allow webpack to interface with module federation code +import('./bootstrap'); diff --git a/examples/module-federation/app1/webpack.config.js b/examples/module-federation/app1/webpack.config.js new file mode 100644 index 00000000..de9f5dae --- /dev/null +++ b/examples/module-federation/app1/webpack.config.js @@ -0,0 +1,41 @@ +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const { ModuleFederationPlugin } = require('webpack').container; +const ExternalTemplateRemotesPlugin = require('external-remotes-plugin'); +const path = require('path'); + +module.exports = { + entry: './src/index', + mode: 'development', + devServer: { + static: path.join(__dirname, 'dist'), + port: 3001, + }, + output: { + publicPath: 'auto', + }, + module: { + rules: [ + { + test: /\.jsx?$/, + loader: 'babel-loader', + exclude: /node_modules/, + options: { + presets: ['@babel/preset-react'], + }, + }, + ], + }, + plugins: [ + new ModuleFederationPlugin({ + name: 'app1', + remotes: { + app2: 'app2@[app2Url]/remoteEntry.js', + }, + shared: { react: { singleton: true }, 'react-dom': { singleton: true } }, + }), + new ExternalTemplateRemotesPlugin(), + new HtmlWebpackPlugin({ + template: './public/index.html', + }), + ], +}; diff --git a/examples/module-federation/app2/package.json b/examples/module-federation/app2/package.json new file mode 100644 index 00000000..ee8e65ee --- /dev/null +++ b/examples/module-federation/app2/package.json @@ -0,0 +1,23 @@ +{ + "name": "app2", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "scripts": { + "start": "webpack serve", + "build": "webpack --mode production" + }, + "dependencies": { + "react": "^17.0.2", + "react-dom": "^17.0.2" + }, + "devDependencies": { + "@babel/core": "^7.14.3", + "@babel/preset-react": "^7.13.13", + "babel-loader": "^8.2.2", + "html-webpack-plugin": "^5.3.1", + "webpack": "^5.38.1", + "webpack-cli": "^4.7.2", + "webpack-dev-server": "^4.0.0" + } +} diff --git a/examples/module-federation/app2/public/index.html b/examples/module-federation/app2/public/index.html new file mode 100644 index 00000000..68b1a43a --- /dev/null +++ b/examples/module-federation/app2/public/index.html @@ -0,0 +1,10 @@ + + + + + App 2 + + +
+ + diff --git a/examples/module-federation/app2/src/App.js b/examples/module-federation/app2/src/App.js new file mode 100644 index 00000000..28777142 --- /dev/null +++ b/examples/module-federation/app2/src/App.js @@ -0,0 +1,18 @@ +import React from 'react'; + +const App = () => { + return ( +
+

App 2

+
+ ); +}; + +export default App; diff --git a/examples/module-federation/app2/src/bootstrap.js b/examples/module-federation/app2/src/bootstrap.js new file mode 100644 index 00000000..ae31e413 --- /dev/null +++ b/examples/module-federation/app2/src/bootstrap.js @@ -0,0 +1,6 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; + +import App from './App'; + +ReactDOM.render(, document.getElementById('root')); diff --git a/examples/module-federation/app2/src/index.js b/examples/module-federation/app2/src/index.js new file mode 100644 index 00000000..b93c7a02 --- /dev/null +++ b/examples/module-federation/app2/src/index.js @@ -0,0 +1 @@ +import('./bootstrap'); diff --git a/examples/module-federation/app2/webpack.config.js b/examples/module-federation/app2/webpack.config.js new file mode 100644 index 00000000..caa81ea2 --- /dev/null +++ b/examples/module-federation/app2/webpack.config.js @@ -0,0 +1,41 @@ +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const { ModuleFederationPlugin } = require('webpack').container; +const path = require('path'); + +module.exports = { + entry: './src/index', + mode: 'development', + devServer: { + static: path.join(__dirname, 'dist'), + port: 3002, + }, + output: { + publicPath: 'auto', + }, + module: { + rules: [ + { + test: /\.jsx?$/, + loader: 'babel-loader', + exclude: /node_modules/, + options: { + presets: ['@babel/preset-react'], + }, + }, + ], + }, + plugins: [ + // To learn more about the usage of this plugin, please visit https://webpack.js.org/plugins/module-federation-plugin/ + new ModuleFederationPlugin({ + name: 'app2', + filename: 'remoteEntry.js', + exposes: { + './App': './src/App', + }, + shared: { react: { singleton: true }, 'react-dom': { singleton: true } }, + }), + new HtmlWebpackPlugin({ + template: './public/index.html', + }), + ], +}; diff --git a/examples/module-federation/lerna.json b/examples/module-federation/lerna.json new file mode 100644 index 00000000..341a73db --- /dev/null +++ b/examples/module-federation/lerna.json @@ -0,0 +1,5 @@ +{ + "version": "1.0.0", + "npmClient": "npm", + "useWorkspaces": true +} diff --git a/examples/module-federation/package.json b/examples/module-federation/package.json new file mode 100644 index 00000000..2212be3f --- /dev/null +++ b/examples/module-federation/package.json @@ -0,0 +1,17 @@ +{ + "name": "module-federation", + "private": true, + "workspaces": { + "packages": [ + "app1", + "app2" + ] + }, + "scripts": { + "start": "lerna run --parallel start", + "build": "lerna run build" + }, + "devDependencies": { + "lerna": "^4.0.0" + } +} From 11c2515019d79a448fefa5e9a58ace520b5ea240 Mon Sep 17 00:00:00 2001 From: Mohamed Shams El-Deen Date: Thu, 20 Aug 2026 16:18:54 +0300 Subject: [PATCH 3/3] chore: remove examples directory and point StackBlitz to legacy repo --- components/StackBlitzPreview/index.jsx | 2 +- examples/getting-started/README.md | 11 ----- examples/getting-started/dist/index.html | 10 ----- examples/getting-started/package.json | 21 ---------- examples/getting-started/src/index.js | 12 ------ examples/getting-started/webpack.config.js | 9 ---- examples/module-federation/README.md | 19 --------- examples/module-federation/app1/package.json | 24 ----------- .../module-federation/app1/public/index.html | 10 ----- examples/module-federation/app1/src/App.js | 24 ----------- .../module-federation/app1/src/bootstrap.js | 5 --- examples/module-federation/app1/src/index.js | 5 --- .../module-federation/app1/webpack.config.js | 41 ------------------- examples/module-federation/app2/package.json | 23 ----------- .../module-federation/app2/public/index.html | 10 ----- examples/module-federation/app2/src/App.js | 18 -------- .../module-federation/app2/src/bootstrap.js | 6 --- examples/module-federation/app2/src/index.js | 1 - .../module-federation/app2/webpack.config.js | 41 ------------------- examples/module-federation/lerna.json | 5 --- examples/module-federation/package.json | 17 -------- 21 files changed, 1 insertion(+), 313 deletions(-) delete mode 100644 examples/getting-started/README.md delete mode 100644 examples/getting-started/dist/index.html delete mode 100644 examples/getting-started/package.json delete mode 100644 examples/getting-started/src/index.js delete mode 100644 examples/getting-started/webpack.config.js delete mode 100644 examples/module-federation/README.md delete mode 100644 examples/module-federation/app1/package.json delete mode 100644 examples/module-federation/app1/public/index.html delete mode 100644 examples/module-federation/app1/src/App.js delete mode 100644 examples/module-federation/app1/src/bootstrap.js delete mode 100644 examples/module-federation/app1/src/index.js delete mode 100644 examples/module-federation/app1/webpack.config.js delete mode 100644 examples/module-federation/app2/package.json delete mode 100644 examples/module-federation/app2/public/index.html delete mode 100644 examples/module-federation/app2/src/App.js delete mode 100644 examples/module-federation/app2/src/bootstrap.js delete mode 100644 examples/module-federation/app2/src/index.js delete mode 100644 examples/module-federation/app2/webpack.config.js delete mode 100644 examples/module-federation/lerna.json delete mode 100644 examples/module-federation/package.json diff --git a/components/StackBlitzPreview/index.jsx b/components/StackBlitzPreview/index.jsx index b7a82964..ae56aa2f 100644 --- a/components/StackBlitzPreview/index.jsx +++ b/components/StackBlitzPreview/index.jsx @@ -6,7 +6,7 @@ export default function StackBlitzPreview(props = {}) { description = 'Check out this guide live on StackBlitz.', } = props; - const url = `https://stackblitz.com/github/webpack/webpack-doc-kit/tree/main/examples/${example}`; + const url = `https://stackblitz.com/github/webpack/webpack.js.org/tree/main/examples/${example}`; return (