Skip to content

Commit

Permalink
feat(v2): Webpack 5, PostCSS 8 (#4089)
Browse files Browse the repository at this point in the history
* Initial webpack 5 work

* It works on my machine (lol)

* Committing a bit more work

* It works - sorta

* Update packages/docusaurus/package.json

* at least fix prettier /shrug

* making more progress. build should work now, css stuff is still a bit broken

* Terser things

Signed-off-by: Reece Dunham <me@rdil.rocks>

* Working on things

* Vendor webpack

* Repair chunks, and tests

* Rerun prettier

* Re-add client prefetching

* Update snapshots

* Update snapshots

* I hope this works

* Remove redundant dev server code

* relock

* Trying to reduce memory usage and fix things

* Dead code elim

* Search bar works!!!

* Prefetching should work again

* lock

* ts issue

* Repair snapshot

* Run prettier

* Fix the CI for now

* fix lint-prettier

* clean-css works, now for the other one

* Fix lockfile

* Fixes prettier

* Other css minification works!!!

* Add clean-css options, fix webpack versions

Signed-off-by: Reece Dunham <me@rdil.rocks>

* Fix tests and several of the webpack loaders

Signed-off-by: Reece Dunham <me@rdil.rocks>

* Re-add support for simple css minifier

* Update other related dependencies

* Fix lockfile

* Dev server fixups

Signed-off-by: Reece Dunham <me@rdil.rocks>

* Simplify css things

* Update webpack, try with postcss 7

* Other cssnano repairs

* fix lockfile

* Clean up the babel preset

* Fix lockfile

* Bump RL SSR version

* Fix the build errors

* Lockfile fix

* It works again

* webpack 5 should close compiler after run

* add proper webpack5 persistent caching config

* upgrade webpack deps again

* reduce build perf timeouts to avoid build time regressions

* test if incremental build can run on netlify

* netlify test

* netlify test

* netlify test

* netlify test

* netlify test

* netlify test

* netlify test

* netlify test

* netlify test

* netlify test

* netlify test

* netlify test

* netlify test

* netlify test

* netlify test

* test

* test

* test

* test

* netlify test

* netlify test

* netlify test

* netlify test

* netlify test

* netlify test

* netlify test

* netlify test

* netlify test

* netlify test

* fix existsSync() calls

* replace @ts-nocheck by a temporary Webpack type

* replace @ts-nocheck by a temporary Webpack type

* replace @ts-nocheck by a temporary Webpack type

* migrate existing stats.warningsFilter to config.ignoreWarnings

* remove stats from postBuild lifecycle data doc, as it is likely unused (we'll add it back if someone ask for it)

* improve build.ts TS issues + move some sync code to async

* cleanup TS of start.ts

* fix TS error

* fix TS issues

* fix TS issues

* fix ts error

* netlify test

* netlify test

* netlify test

* netlify test

* netlify test

* script cleanup

* script cleanup

* re-enable @typescript-eslint/ban-ts-comment

* Deprecate getCacheLoader / getBabelLoader but keep retrocompatibility

* useless TS

* fix and comment gca(chunkName) prefetching function

* remove deprecated mainTemplate.requireFn

* temporarily use react-loadable-ssr-addon-v5-slorber until PR merged: #4089

* comment unsafeCache option

* add explicit and more precise webpack targets

* splitChunks, use new type: "css/mini-extract" as it seems recommended for webpack 5

* webpack error handling:
- log error.details as documented
- keep using react-dev-utils/formatWebpackMessages for now

* fix webpack5 warnings for evalSourceMapMiddleware.js

* typo

* rename webpackHotDevClient

* make all modifications of react-dev-utils explicit with a comment

* revert LogPlugin adapter

* loader-utils update

* add useful share cache comment

* add useful comments regarding the null-loader used in SSR for css files

* upgrade webpack-merge in a retrocompatible way

* use MiniCssExtractPlugin.emit false as recommended

* use @docusaurus/responsive-loader

* revert MiniCssExtractPlugin esModule: false change

* add link to PR for custom CleanWebpackPlugin

* pwa: add fallback to env variable or webpack 5 fails to build

* upgrade to CssMinimizerPlugin 2.0

* only build en locale for windows tests

* line breaks between errors

* add useful comment

* Fix e2e tests with Yarn2 not finding new init template dependencies

* fix bad import

* disable browserslist target as webpack already tries to use browserlists if a config is found, and it is a problem for existing sites

* webpack5 TS fixes

* fix getMinimizer order (even if it does not work yet)

* update postcss to v8, fix cssnano minimizer errors

* add NavbarItem position to types (useful for QuestDB site upgrade to Webpack5)

* add webpack cache env variable to reduce risk of webpack 5 adoption

Co-authored-by: slorber <lorber.sebastien@gmail.com>
  • Loading branch information
RDIL and slorber committed Apr 30, 2021
1 parent 27b9f34 commit 05e7250
Show file tree
Hide file tree
Showing 63 changed files with 1,809 additions and 1,575 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/v2-build-time-perf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ jobs:
# Ensure build with a cold cache does not increase too much
- name: Build (cold cache)
run: yarn workspace docusaurus-2-website build --locale en
timeout-minutes: 10
timeout-minutes: 8

# Ensure build with a warm cache does not increase too much
- name: Build (warm cache)
run: yarn workspace docusaurus-2-website build --locale en
timeout-minutes: 10
timeout-minutes: 2

# TODO post a Github comment with build with perf warnings?
2 changes: 1 addition & 1 deletion .github/workflows/v2-tests-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ jobs:
- name: Docusaurus Jest Tests
run: yarn test
- name: Docusaurus Build
run: yarn build:v2
run: yarn build:v2 --locale en
env:
CI: true
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,11 @@
"@formatjs/intl-datetimeformat": "^3.2.12",
"@formatjs/intl-numberformat": "^6.2.2",
"@formatjs/intl-pluralrules": "^4.0.11",
"@types/cssnano": "^4.0.0",
"@types/express": "^4.17.2",
"@types/fs-extra": "^9.0.6",
"@types/jest": "^26.0.20",
"@types/loader-utils": "^1.1.3",
"@types/loader-utils": "^2.0.2",
"@types/lodash": "^4.14.168",
"@types/node": "^14.14.22",
"@types/prismjs": "^1.16.2",
Expand All @@ -87,9 +88,7 @@
"@types/semver": "^7.1.0",
"@types/shelljs": "^0.8.6",
"@types/wait-on": "^5.2.0",
"@types/webpack": "^4.41.0",
"@types/webpack-dev-server": "^3.9.0",
"@types/webpack-merge": "^4.1.5",
"@types/webpack-dev-server": "^3.11.1",
"@typescript-eslint/eslint-plugin": "^4.18.0",
"@typescript-eslint/parser": "^4.18.0",
"concurrently": "^5.3.0",
Expand Down
21 changes: 12 additions & 9 deletions packages/docusaurus-cssnano-preset/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@ const advancedBasePreset = require('cssnano-preset-advanced');
const postCssSortMediaQueries = require('postcss-sort-media-queries');
const postCssRemoveOverriddenCustomProperties = require('./src/remove-overridden-custom-properties');

const preset = advancedBasePreset({
autoprefixer: {add: false},
discardComments: {removeAll: true},
});
module.exports = function docusaurusCssnanoPreset(opts) {
const advancedPreset = advancedBasePreset({
autoprefixer: {add: false},
discardComments: {removeAll: true},
...opts,
});

preset.plugins.unshift(
[postCssSortMediaQueries],
[postCssRemoveOverriddenCustomProperties],
);
advancedPreset.plugins.unshift(
[postCssSortMediaQueries],
[postCssRemoveOverriddenCustomProperties],
);

module.exports = preset;
return advancedPreset;
};
6 changes: 3 additions & 3 deletions packages/docusaurus-cssnano-preset/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
"directory": "packages/docusaurus-cssnano-preset"
},
"dependencies": {
"cssnano-preset-advanced": "^4.0.7",
"postcss": "^7.0.2",
"postcss-sort-media-queries": "^1.7.26"
"cssnano-preset-advanced": "^5.0.0",
"postcss": "^8.2.10",
"postcss-sort-media-queries": "^3.8.9"
},
"devDependencies": {
"to-vfile": "^6.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,38 @@
* LICENSE file in the root directory of this source tree.
*/

const postcss = require('postcss');

/*
This PostCSS plugin will remove duplicate/same custom properties (which are actually overridden ones) **only** from `:root` selector.
Depending on the presence of an `!important` rule in value of custom property, the following actions will happens:
- If the same custom properties do **not** have an `!important` rule, then all of them will be removed except for the last one (which will actually be applied).
- If the same custom properties have at least one `!important` rule, then only those properties that do not have this rule will be removed.
*/

module.exports = postcss.plugin(
'postcss-remove-overridden-custom-properties',
() => {
return (root) => {
root.walkDecls((decl) => {
if (decl.parent.selector !== ':root') {
return;
}

const sameProperties =
decl.parent.nodes.filter((n) => n.prop === decl.prop) || [];
const hasImportantProperties = sameProperties.some((p) =>
Object.prototype.hasOwnProperty.call(p, 'important'),
);

const overriddenProperties = hasImportantProperties
? sameProperties.filter(
(p) => !Object.prototype.hasOwnProperty.call(p, 'important'),
)
: sameProperties.slice(0, -1);

overriddenProperties.map((p) => p.remove());
});
};
},
);
/**
* This PostCSS plugin will remove duplicate/same custom properties (which are actually overridden ones) **only** from `:root` selector.
*
* Depending on the presence of an `!important` rule in value of custom property, the following actions will happens:
*
* - If the same custom properties do **not** have an `!important` rule, then all of them will be removed except for the last one (which will actually be applied).
* - If the same custom properties have at least one `!important` rule, then only those properties that do not have this rule will be removed.
* @returns {import('postcss').Plugin}
*/
module.exports = function creator() {
return {
postcssPlugin: 'postcss-remove-overridden-custom-properties',
Declaration(decl) {
if (decl.parent.selector !== ':root') {
return;
}

const sameProperties =
decl.parent.nodes.filter((n) => n.prop === decl.prop) || [];
const hasImportantProperties = sameProperties.some((p) =>
Object.prototype.hasOwnProperty.call(p, 'important'),
);

const overriddenProperties = hasImportantProperties
? sameProperties.filter(
(p) => !Object.prototype.hasOwnProperty.call(p, 'important'),
)
: sameProperties.slice(0, -1);

overriddenProperties.map((p) => p.remove());
},
};
};

module.exports.postcss = true;
9 changes: 6 additions & 3 deletions packages/docusaurus-init/templates/bootstrap/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@
"dependencies": {
"@docusaurus/core": "2.0.0-alpha.74",
"@docusaurus/preset-bootstrap": "2.0.0-alpha.74",
"@mdx-js/react": "^1.5.8",
"classnames": "^2.2.6",
"@mdx-js/react": "^1.6.21",
"@svgr/webpack": "^5.5.0",
"clsx": "^1.1.1",
"file-loader": "^6.2.0",
"react": "^17.0.1",
"react-dom": "^17.0.1"
"react-dom": "^17.0.1",
"url-loader": "^4.1.1"
},
"browserslist": {
"production": [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import React from 'react';
import classnames from 'classnames';
import clsx from 'clsx';
import Layout from '@theme/Layout';
import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import useBaseUrl from '@docusaurus/useBaseUrl';

import styles from './styles.module.css';

const features = [
Expand Down Expand Up @@ -43,7 +42,7 @@ const features = [
function Feature({imageUrl, title, description}) {
const imgUrl = useBaseUrl(imageUrl);
return (
<div className={classnames('col col--4', styles.feature)}>
<div className={clsx('col col--4', styles.feature)}>
{imgUrl && (
<div className="text--center">
<img className={styles.featureImage} src={imgUrl} alt={title} />
Expand Down
5 changes: 4 additions & 1 deletion packages/docusaurus-init/templates/classic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@
"@docusaurus/core": "2.0.0-alpha.74",
"@docusaurus/preset-classic": "2.0.0-alpha.74",
"@mdx-js/react": "^1.6.21",
"@svgr/webpack": "^5.5.0",
"clsx": "^1.1.1",
"file-loader": "^6.2.0",
"react": "^17.0.1",
"react-dom": "^17.0.1"
"react-dom": "^17.0.1",
"url-loader": "^4.1.1"
},
"browserslist": {
"production": [
Expand Down
5 changes: 4 additions & 1 deletion packages/docusaurus-init/templates/facebook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@
"@docusaurus/core": "2.0.0-alpha.74",
"@docusaurus/preset-classic": "2.0.0-alpha.74",
"@mdx-js/react": "^1.6.21",
"@svgr/webpack": "^5.5.0",
"clsx": "^1.1.1",
"file-loader": "^6.2.0",
"react": "^17.0.1",
"react-dom": "^17.0.1"
"react-dom": "^17.0.1",
"url-loader": "^4.1.1"
},
"devDependencies": {
"@babel/eslint-parser": "^7.13.10",
Expand Down
4 changes: 2 additions & 2 deletions packages/docusaurus-mdx-loader/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@
"file-loader": "^6.2.0",
"fs-extra": "^9.1.0",
"github-slugger": "^1.3.0",
"loader-utils": "^2.0.0",
"gray-matter": "^4.0.2",
"mdast-util-to-string": "^2.0.0",
"remark-emoji": "^2.1.0",
"stringify-object": "^3.3.0",
"unist-util-visit": "^2.0.2",
"url-loader": "^4.1.1",
"webpack": "^4.44.1"
"webpack": "^5.28.0"
},
"devDependencies": {
"@docusaurus/types": "2.0.0-alpha.74",
Expand Down
4 changes: 2 additions & 2 deletions packages/docusaurus-mdx-loader/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* LICENSE file in the root directory of this source tree.
*/

const {getOptions} = require('loader-utils');
const {readFile} = require('fs-extra');
const mdx = require('@mdx-js/mdx');
const emoji = require('remark-emoji');
Expand All @@ -27,7 +26,8 @@ const DEFAULT_OPTIONS = {

module.exports = async function docusaurusMdxLoader(fileString) {
const callback = this.async();
const reqOptions = getOptions(this) || {};

const reqOptions = this.getOptions() || {};

const {frontMatter, content: contentWithTitle} = parseFrontMatter(fileString);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const createJSX = (node, pathUrl) => {
};

async function ensureImageFileExist(imagePath, sourceFilePath) {
const imageExists = await fs.exists(imagePath);
const imageExists = await fs.pathExists(imagePath);
if (!imageExists) {
throw new Error(
`Image ${toMessageRelativeFilePath(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const {
} = getFileLoaderUtils();

async function ensureAssetFileExist(fileSystemAssetPath, sourceFilePath) {
const assetExists = await fs.exists(fileSystemAssetPath);
const assetExists = await fs.pathExists(fileSystemAssetPath);
if (!assetExists) {
throw new Error(
`Asset ${toMessageRelativeFilePath(
Expand Down Expand Up @@ -85,12 +85,12 @@ async function convertToAssetLinkIfNeeded({node, staticDir, filePath}) {
toAssetLinkNode(fileSystemAssetPath);
} else if (path.isAbsolute(assetPath)) {
const fileSystemAssetPath = path.join(staticDir, assetPath);
if (await fs.exists(fileSystemAssetPath)) {
if (await fs.pathExists(fileSystemAssetPath)) {
toAssetLinkNode(fileSystemAssetPath);
}
} else {
const fileSystemAssetPath = path.join(path.dirname(filePath), assetPath);
if (await fs.exists(fileSystemAssetPath)) {
if (await fs.pathExists(fileSystemAssetPath)) {
toAssetLinkNode(fileSystemAssetPath);
}
}
Expand Down
4 changes: 2 additions & 2 deletions packages/docusaurus-plugin-content-blog/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@
"feed": "^4.2.2",
"fs-extra": "^9.1.0",
"globby": "^11.0.2",
"loader-utils": "^1.2.3",
"loader-utils": "^2.0.0",
"lodash": "^4.17.20",
"reading-time": "^1.3.0",
"remark-admonitions": "^1.2.1",
"tslib": "^2.1.0",
"webpack": "^4.44.1"
"webpack": "^5.28.0"
},
"peerDependencies": {
"react": "^16.8.4 || ^17.0.0",
Expand Down
9 changes: 4 additions & 5 deletions packages/docusaurus-plugin-content-blog/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import {
OptionValidationContext,
ValidationResult,
} from '@docusaurus/types';
import {Configuration, Loader} from 'webpack';
import {Configuration} from 'webpack';
import {
generateBlogFeed,
generateBlogPosts,
Expand Down Expand Up @@ -401,7 +401,7 @@ export default function pluginContentBlog(
configureWebpack(
_config: Configuration,
isServer: boolean,
{getBabelLoader, getCacheLoader}: ConfigureWebpackUtils,
{getJSLoader}: ConfigureWebpackUtils,
) {
const {
rehypePlugins,
Expand Down Expand Up @@ -441,8 +441,7 @@ export default function pluginContentBlog(
// Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
.map(addTrailingPathSeparator),
use: [
getCacheLoader(isServer),
getBabelLoader(isServer),
getJSLoader({isServer}),
{
loader: require.resolve('@docusaurus/mdx-loader'),
options: {
Expand All @@ -466,7 +465,7 @@ export default function pluginContentBlog(
loader: path.resolve(__dirname, './markdownLoader.js'),
options: markdownLoaderOptions,
},
].filter(Boolean) as Loader[],
].filter(Boolean),
},
],
},
Expand Down
17 changes: 11 additions & 6 deletions packages/docusaurus-plugin-content-blog/src/markdownLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@
* LICENSE file in the root directory of this source tree.
*/

import {loader} from 'webpack';
import {truncate, linkify} from './blogUtils';
import {parseQuery, getOptions} from 'loader-utils';
import {parseQuery} from 'loader-utils';
import {BlogMarkdownLoaderOptions} from './types';

const markdownLoader: loader.Loader = function (source) {
// TODO temporary until Webpack5 export this type
// see https://github.com/webpack/webpack/issues/11630
interface Loader extends Function {
(this: any, source: string): string | Buffer | void | undefined;
}

const markdownLoader: Loader = function (source) {
const filePath = this.resourcePath;
const fileString = source as string;
const callback = this.async();
const markdownLoaderOptions = getOptions(this) as BlogMarkdownLoaderOptions;
const markdownLoaderOptions = this.getOptions() as BlogMarkdownLoaderOptions;

// Linkify blog posts
let finalContent = linkify({
Expand All @@ -24,8 +29,8 @@ const markdownLoader: loader.Loader = function (source) {
});

// Truncate content if requested (e.g: file.md?truncated=true).
const truncated: string | undefined = this.resourceQuery
? parseQuery(this.resourceQuery).truncated
const truncated: boolean | undefined = this.resourceQuery
? !!parseQuery(this.resourceQuery).truncated
: undefined;

if (truncated) {
Expand Down
2 changes: 1 addition & 1 deletion packages/docusaurus-plugin-content-docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"shelljs": "^0.8.4",
"tslib": "^2.1.0",
"utility-types": "^3.10.0",
"webpack": "^4.44.1"
"webpack": "^5.28.0"
},
"peerDependencies": {
"react": "^16.8.4 || ^17.0.0",
Expand Down
Loading

0 comments on commit 05e7250

Please sign in to comment.