diff --git a/components/Blog/Card/index.jsx b/components/Blog/Card/index.jsx
new file mode 100644
index 0000000..db42ba5
--- /dev/null
+++ b/components/Blog/Card/index.jsx
@@ -0,0 +1,55 @@
+import styles from './index.module.css';
+
+const formatDate = dateString => {
+ if (!dateString) return '';
+ const date = new Date(dateString);
+ return date.toLocaleDateString('en-GB', {
+ day: 'numeric',
+ month: 'short',
+ year: 'numeric',
+ });
+};
+
+export default function BlogCard({
+ slug,
+ title,
+ date,
+ description,
+ contributors = [],
+}) {
+ return (
+
+
+
+
+
+
+
{title || 'Untitled Post'}
+
{description}
+
+
+
+
+ {contributors.map(user => (
+
+
+
+ ))}
+
+
+
•
+
{formatDate(date)}
+
+
+ );
+}
diff --git a/components/Blog/Card/index.module.css b/components/Blog/Card/index.module.css
new file mode 100644
index 0000000..f6c34ff
--- /dev/null
+++ b/components/Blog/Card/index.module.css
@@ -0,0 +1,125 @@
+@reference "../../../styles/index.css";
+
+.card {
+ @apply relative
+ flex
+ flex-col
+ h-full
+ rounded-xl
+ border
+ border-neutral-200
+ bg-white
+ p-6
+ overflow-hidden
+ transition-colors
+ duration-150
+ hover:border-blue-300
+ hover:bg-blue-50/40
+ dark:border-neutral-800
+ dark:bg-neutral-900
+ dark:hover:border-blue-400/60
+ dark:hover:bg-blue-950/40;
+}
+
+.decoration {
+ @apply absolute
+ -right-8
+ -top-8
+ size-32
+ bg-blue-500
+ opacity-0
+ transition-all
+ duration-500
+ translate-x-4
+ -translate-y-4;
+
+ clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
+}
+
+.card:hover .decoration {
+ @apply opacity-5
+ dark:opacity-10
+ translate-x-0
+ translate-y-0
+ rotate-12;
+}
+
+.mainLink {
+ @apply absolute
+ inset-0
+ z-0
+ focus:outline-none;
+}
+
+.content {
+ @apply flex
+ flex-col
+ gap-3
+ pb-5
+ pointer-events-none;
+}
+
+.title {
+ @apply m-0
+ text-xl
+ font-bold
+ leading-tight
+ text-neutral-900
+ dark:text-white;
+}
+
+.description {
+ @apply m-0
+ line-clamp-3
+ text-base
+ leading-relaxed
+ text-neutral-600
+ dark:text-neutral-400;
+}
+
+.footer {
+ @apply mt-auto
+ flex
+ items-center
+ border-t
+ border-neutral-100
+ pt-3
+ dark:border-neutral-800/80;
+}
+
+.avatars {
+ @apply flex
+ items-center
+ -space-x-2;
+}
+
+.avatarLink {
+ @apply relative
+ z-10
+ transition-transform
+ hover:-translate-y-1;
+}
+
+.avatar {
+ @apply size-8
+ rounded-full
+ border-2
+ border-white
+ bg-neutral-100
+ dark:border-neutral-900
+ dark:bg-neutral-800;
+}
+
+.dot {
+ @apply mx-3
+ text-neutral-300
+ dark:text-neutral-600;
+}
+
+.date {
+ @apply tabular-nums
+ text-sm
+ font-medium
+ text-neutral-500
+ dark:text-neutral-400;
+}
diff --git a/components/Layout.jsx b/components/Layout.jsx
index 66c1b1c..ec3bfef 100644
--- a/components/Layout.jsx
+++ b/components/Layout.jsx
@@ -1,11 +1,13 @@
import DefaultLayout from '@node-core/doc-kit/src/generators/web/ui/components/Layout/index.jsx';
import HomeLayout from '../layouts/Home/index.jsx';
import SponsorsLayout from '../layouts/Sponsors/index.jsx';
+import BlogLayout from '../layouts/Blog/index.jsx';
import '../styles/index.css';
const LAYOUTS = {
home: HomeLayout,
sponsors: SponsorsLayout,
+ blogs: BlogLayout,
};
export default function Layout(props) {
diff --git a/layouts/Blog/index.jsx b/layouts/Blog/index.jsx
new file mode 100644
index 0000000..a244dc5
--- /dev/null
+++ b/layouts/Blog/index.jsx
@@ -0,0 +1,40 @@
+import PartialArticle from '../PartialArticle/index.jsx';
+import BlogCard from '../../components/Blog/Card/index.jsx';
+import blogsData from '../../generated/blogs.json';
+import styles from './index.module.css';
+
+/**
+ * Blogs page layout. Lists all Webpack blog posts in a grid,
+ * wrapped inside the PartialArticle shell to preserve the Sidebar and Navbar.
+ *
+ * @param {{ metadata: object }} props
+ */
+export default function BlogLayout({ metadata }) {
+ return (
+
+
+
+
+
+ {blogsData.map(post => (
+
+ ))}
+
+
+
+
+ );
+}
diff --git a/layouts/Blog/index.module.css b/layouts/Blog/index.module.css
new file mode 100644
index 0000000..4cff33f
--- /dev/null
+++ b/layouts/Blog/index.module.css
@@ -0,0 +1,47 @@
+@reference "../../styles/index.css";
+
+.blogSection {
+ @apply bg-white
+ py-16
+ lg:py-20
+ dark:bg-neutral-950;
+}
+
+.container {
+ @apply mx-auto
+ max-w-7xl
+ px-6;
+}
+
+.header {
+ @apply mb-12
+ border-b
+ border-neutral-200
+ pb-8
+ text-center
+ dark:border-neutral-800;
+}
+
+.mainTitle {
+ @apply mb-3
+ text-3xl
+ font-bold
+ text-neutral-900
+ lg:text-4xl
+ dark:text-white;
+}
+
+.subtitle {
+ @apply mx-auto
+ max-w-2xl
+ text-lg
+ text-neutral-600
+ dark:text-neutral-400;
+}
+
+.grid {
+ @apply grid
+ gap-6
+ sm:grid-cols-2
+ lg:grid-cols-3;
+}
diff --git a/package.json b/package.json
index 7acf629..c723445 100644
--- a/package.json
+++ b/package.json
@@ -3,6 +3,7 @@
"build:prepare": "node scripts/prepare/index.mjs",
"build:data": "npm-run-all build:data:*",
"build:data:sponsors": "node scripts/data/sponsors.mjs",
+ "build:data:blog": "node scripts/data/blogs.mjs",
"build:md": "npm-run-all build:md:*",
"build:md:api": "node scripts/markdown/api.mjs",
"build:md:readmes": "node scripts/markdown/readmes.mjs",
diff --git a/pages/blogs/2020-10-10-webpack-5-release.md b/pages/blogs/2020-10-10-webpack-5-release.md
new file mode 100644
index 0000000..549d27b
--- /dev/null
+++ b/pages/blogs/2020-10-10-webpack-5-release.md
@@ -0,0 +1,1444 @@
+---
+title: Webpack 5 release
+sort: 20201010
+contributors:
+ - sokra
+ - chenxsan
+---
+
+# Webpack 5 release
+
+Webpack 4 was released in February 2018.
+Since then we shipped a lot of features without breaking changes.
+We know that people dislike major changes with breaking changes.
+Especially with webpack, which people usually only touch twice a year, and the remaining time it "just works".
+But shipping features without breaking changes also has a cost:
+We can't do major API or architectural improvements.
+
+So from time to time, there is a point where the difficulties pile up and we are forced to do breaking changes to not mess everything up.
+That's the time for a new major version.
+So webpack 5 contains these architectural improvements and the features that were not possible to implement without them.
+
+The major version was also the chance to revise some of the defaults and to align with proposals and specifications that come up in the meantime.
+
+So today (2020-10-10) webpack 5.0.0 is released, but this doesn't mean it's done, bugfree or even feature-complete.
+As with webpack 4 we continue development by fixing problems and adding features.
+In the next days there will probably be a lot bugfixes. Features will come later.
+
+## Common Questions
+
+### So what does the release mean?
+
+It means we finished doing breaking changes.
+Many refactorings have been done to up-level the architecture and create a good base for future features (and current features).
+
+### So when is the time to upgrade?
+
+It depends. There is a good chance that upgrading fails and you would need to give it a second or 3rd try.
+If you are open to that, try to upgrade now and provide feedback to webpack, plugins and loaders.
+We are eager to fix those problems. Someone has to start and you would be one of the first ones benefiting from it.
+
+## Sponsoring Update
+
+Webpack is fully based upon [sponsoring](https://opencollective.com/webpack).
+It's not tied to (and paid by) a big company like some other Open Source projects.
+99% of the earnings from sponsoring are distributed towards contributors and maintainers based on the contributions they do.
+We believe in investing the money towards making webpack better.
+
+But there is a pandemic, and companies ain't that much open to sponsoring anymore.
+Webpack is suffering under these circumstances too (like many other companies and people).
+
+We were never able to pay our contributors the amount we think they deserve, but now we only have half of the money available, so we need to make a more serious cut.
+Until the situation improves we will only pay contributors and maintainers the first 10 days of each month.
+The remaining days they could work voluntarily, paid by their employer, work on something else, or take some days off.
+This allows us to pay for their work in the first 10 days more equivalent to the invested time.
+
+The biggest "Thank You" goes to [trivago](https://tech.trivago.com/opensource) which has been sponsoring webpack a huge amount for the last 3 years.
+Sadly they are unable to continue their sponsorship this year, as they have been hit hard by Covid-19.
+I hope some other company steps up and follows these (gigantic) footsteps.
+
+Thanks to [all the sponsors](/#sponsors).
+
+## General direction
+
+This release focus on the following:
+
+- Improve build performance with Persistent Caching.
+- Improve Long Term Caching with better algorithms and defaults.
+- Improve bundle size with better Tree Shaking and Code Generation.
+- Improve compatibility with the web platform.
+- Clean up internal structures that were left in a weird state while implementing features in v4 without introducing any breaking changes.
+- Prepare for future features by introducing breaking changes now, allowing us to stay on v5 for as long as possible.
+
+## **Migration** Guide
+
+[See here for a **migration** guide](/migrate/5)
+
+## Major Changes: Removals
+
+### Removed Deprecated Items
+
+All items deprecated in v4 were removed.
+
+**MIGRATION**: Make sure that your webpack 4 build does not print deprecation warnings.
+
+Here are a few things that were removed but did not have deprecation warnings in v4:
+
+- IgnorePlugin and BannerPlugin must now be passed only one argument that can be an object, string or function.
+
+### Deprecation codes
+
+New deprecations include a deprecation code so they are easier to reference.
+
+### Syntax deprecated
+
+`require.include` has been deprecated and will emit a warning by default when used.
+
+Behavior can be changed with `Rule.parser.requireInclude` to allowed, deprecated or disabled.
+
+### Automatic Node.js Polyfills Removed
+
+In the early days, webpack's aim was to allow running most Node.js modules in the browser, but the module landscape changed and many module uses are now written mainly for frontend purposes. Webpack <= 4 ships with polyfills for many of the Node.js core modules, which are automatically applied once a module uses any of the core modules (i.e. the `crypto` module).
+
+While this makes using modules written for Node.js easier, it adds these huge polyfills to the bundle. In many cases these polyfills are unnecessary.
+
+Webpack 5 stops automatically polyfilling these core modules and focus on frontend-compatible modules. Our goal is to improve compatibility with the web platform, where Node.js core modules are not available.
+
+**MIGRATION**:
+
+- Try to use frontend-compatible modules whenever possible.
+- It's possible to manually add a polyfill for a Node.js core module. An error message will give a hint on how to achieve that.
+- Package authors: Use the `browser` field in `package.json` to make a package frontend-compatible. Provide alternative implementations/dependencies for the browser.
+
+## Major Changes: Long Term Caching
+
+### Deterministic Chunk, Module IDs and Export names
+
+New algorithms were added for long term caching. These are enabled by default in production mode.
+
+`chunkIds: "deterministic"`
+`moduleIds: "deterministic"`
+`mangleExports: "deterministic"`
+
+The algorithms assign short (3 or 5 digits) numeric IDs to modules and chunks and short (2 characters) names to exports in a deterministic way.
+This is a trade-off between bundle size and long term caching.
+
+`moduleIds/chunkIds/mangleExports: false` disables the default behavior and one can provide a custom algorithm via plugin. Note that in webpack 4 `moduleIds/chunkIds: false` without custom plugin resulted in a working build, while in webpack 5 you must provide a custom plugin.
+
+**MIGRATION**: Best use the default values for `chunkIds`, `moduleIds` and `mangleExports`. You can also opt-in to the old defaults `chunkIds: "size", moduleIds: "size", mangleExports: "size"`, this will generate smaller bundles, but invalidate them more often for caching.
+
+Note: In webpack 4 hashed module ids yielded reduced gzip performance. This was related to changed module order and has been fixed.
+
+Note: In webpack 5, `deterministic` Ids are enabled by default in production mode
+
+### Real Content Hash
+
+Webpack 5 will use a real hash of the file content when using `[contenthash]` now. Before it "only" used a hash of the internal structure.
+This can be positive impact on long term caching when only comments are changed or variables are renamed. These changes are not visible after minimizing.
+
+## Major Changes: Development Support
+
+### Named Chunk IDs
+
+A new named chunk id algorithm enabled by default in development mode gives chunks (and filenames) human-readable names.
+A Module ID is determined by its path, relative to the `context`.
+A Chunk ID is determined by the chunk's content.
+
+So you no longer need to use `import(/* webpackChunkName: "name" */ "module")` for debugging.
+But it would still make sense if you want to control the filenames for production environments.
+
+It's possible to use `chunkIds: "named"` in production, but make sure not to accidentally expose sensitive information about module names.
+
+**MIGRATION**: If you dislike the filenames being changed in development, you can pass `chunkIds: "natural"` to use the old numeric mode.
+
+### Module Federation
+
+Webpack 5 adds a new feature called "Module Federation", which allows multiple webpack builds to work together.
+From runtime perspective modules from multiple builds will behave like a huge connected module graph.
+From developer perspective modules can be imported from specified remote builds and used with minimal restrictions.
+
+For more details see [this separate guide](/concepts/module-federation).
+
+## Major Changes: New Web Platform Features
+
+### JSON modules
+
+JSON modules now align with the proposal and emit a warning when a non-default export is used.
+JSON modules no longer have named exports when importing from a strict ECMAScript module.
+
+**MIGRATION**: Use the default export.
+
+Even when using the default export, unused properties are dropped by the `optimization.usedExports` optimization and properties are mangled by the `optimization.mangleExports` optimization.
+
+It's possible to specify a custom JSON parser in `Rule.parser.parse` to import JSON-like files (e.g. for toml, yaml, json5, etc.).
+
+### import.meta
+
+- `import.meta.webpackHot` is an alias for `module.hot` which is also available in strict ESM
+- `import.meta.webpack` is the webpack major version as number
+- `import.meta.url` is the `file:` url of the current file (similar to `__filename` but as file url)
+
+### Asset modules
+
+Webpack 5 has now native support for modules representing assets.
+These modules will either emit a file into the output folder or inject a DataURI into the javascript bundle.
+Either way they give a URL to work with.
+
+They can be used via multiple ways:
+
+- `import url from "./image.png"` and setting `type: "asset"` in `module.rules` when matching such import. (old way)
+- `new URL("./image.png", import.meta.url)` (new way)
+
+The "new way" syntax was chosen to allow running code without bundler too. This syntax is also available in native ECMAScript modules in the browser.
+
+### Native Worker support
+
+When combining `new URL` for assets with `new Worker`/`new SharedWorker`/`navigator.serviceWorker.register` webpack will automatically create a new entrypoint for a web worker.
+
+`new Worker(new URL("./worker.js", import.meta.url))`
+
+The syntax was chosen to allow running code without bundler too. This syntax is also available in native ECMAScript modules in the browser.
+
+### URIs
+
+Webpack 5 supports handling of protocols in requests.
+
+- `data:` is supported. Base64 or raw encoding is supported. Mimetype can be mapped to loaders and module type in `module.rules`. Example: `import x from "data:text/javascript,export default 42"`
+- `file:` is supported.
+- `http(s):` is supported, but requires opt-in via `new webpack.experiments.schemesHttp(s)UriPlugin()`
+ - By default when targeting "web", these URIs result in requests to external resource (they are externals)
+
+Fragments in requests are supported: Example: `./file.js#fragment`
+
+### Async modules
+
+Webpack 5 supports so called "async modules".
+That are modules that do not evaluate synchronously, but are async and Promise-based instead.
+
+Importing them via `import` is automatically handled and no additional syntax is needed and difference is hardly notice-able.
+
+Importing them via `require()` will return a Promise that resolves to the exports.
+
+In webpack there are multiple ways to have async modules:
+
+- async externals
+- WebAssembly Modules in the new spec
+- ECMAScript Modules that are using Top-Level-Await
+
+### Externals
+
+Webpack 5 adds additional external types to cover more applications:
+
+`promise`: An expression that evaluates to a Promise. The external module is an async module and the resolved value is used as module exports.
+
+`import`: Native `import()` is used to load the specified request. The external module is an async module.
+
+`module`: Not implemented yet, but planned to load modules via `import x from "..."`.
+
+`script`: Loads a url via `
+
+
+