docusaurus/packages/docusaurus-mdx-loader/src/remark/transformImage/index.js
Reece Dunham 05e7250c08
feat(v2): Webpack 5, PostCSS 8 (#4089)
* 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: https://github.com/facebook/docusaurus/pull/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>
2021-04-30 18:06:53 +02:00

100 lines
3.1 KiB
JavaScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const visit = require('unist-util-visit');
const path = require('path');
const url = require('url');
const fs = require('fs-extra');
const escapeHtml = require('escape-html');
const {getFileLoaderUtils} = require('@docusaurus/core/lib/webpack/utils');
const {posixPath, toMessageRelativeFilePath} = require('@docusaurus/utils');
const {
loaders: {inlineMarkdownImageFileLoader},
} = getFileLoaderUtils();
const createJSX = (node, pathUrl) => {
const jsxNode = node;
jsxNode.type = 'jsx';
jsxNode.value = `<img ${node.alt ? `alt={"${escapeHtml(node.alt)}"} ` : ''}${
node.url
? `src={require("${inlineMarkdownImageFileLoader}${pathUrl}").default}`
: ''
}${node.title ? ` title="${escapeHtml(node.title)}"` : ''} />`;
if (jsxNode.url) {
delete jsxNode.url;
}
if (jsxNode.alt) {
delete jsxNode.alt;
}
if (jsxNode.title) {
delete jsxNode.title;
}
};
async function ensureImageFileExist(imagePath, sourceFilePath) {
const imageExists = await fs.pathExists(imagePath);
if (!imageExists) {
throw new Error(
`Image ${toMessageRelativeFilePath(
imagePath,
)} used in ${toMessageRelativeFilePath(sourceFilePath)} not found.`,
);
}
}
async function processImageNode(node, {filePath, staticDir}) {
if (!node.url) {
throw new Error(
`Markdown image url is mandatory. filePath=${toMessageRelativeFilePath(
filePath,
)}`,
);
}
const parsedUrl = url.parse(node.url);
if (parsedUrl.protocol) {
// pathname:// is an escape hatch,
// in case user does not want his images to be converted to require calls going through webpack loader
// we don't have to document this for now,
// it's mostly to make next release less risky (2.0.0-alpha.59)
if (parsedUrl.protocol === 'pathname:') {
node.url = node.url.replace('pathname://', '');
} else {
// noop
}
}
// images without protocol
else if (path.isAbsolute(node.url)) {
// absolute paths are expected to exist in the static folder
const expectedImagePath = path.join(staticDir, node.url);
await ensureImageFileExist(expectedImagePath, filePath);
createJSX(node, posixPath(expectedImagePath));
}
// We try to convert image urls without protocol to images with require calls
// going through webpack ensures that image assets exist at build time
else {
// relative paths are resolved against the source file's folder
const expectedImagePath = path.join(path.dirname(filePath), node.url);
await ensureImageFileExist(expectedImagePath, filePath);
createJSX(node, node.url.startsWith('./') ? node.url : `./${node.url}`);
}
}
const plugin = (options) => {
const transformer = async (root) => {
const promises = [];
visit(root, 'image', (node) => {
promises.push(processImageNode(node, options));
});
await Promise.all(promises);
};
return transformer;
};
module.exports = plugin;