mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-12 00:27:21 +02:00
fix: make Docusaurus PnP strict mode compatible (#6047)
Co-authored-by: Kristoffer K. <merceyz@users.noreply.github.com>
This commit is contained in:
parent
68b75bf855
commit
e07ebadf6c
65 changed files with 304 additions and 269 deletions
33
packages/docusaurus-utils/src/__tests__/webpackUtils.test.ts
Normal file
33
packages/docusaurus-utils/src/__tests__/webpackUtils.test.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import {getFileLoaderUtils} from '../webpackUtils';
|
||||
|
||||
describe('getFileLoaderUtils()', () => {
|
||||
test('plugin svgo/removeViewBox should be disabled', () => {
|
||||
const {oneOf} = getFileLoaderUtils().rules.svg();
|
||||
expect(oneOf[0].use).toContainEqual(
|
||||
expect.objectContaining({
|
||||
loader: require.resolve('@svgr/webpack'),
|
||||
options: expect.objectContaining({
|
||||
svgoConfig: {
|
||||
plugins: [
|
||||
{
|
||||
name: 'preset-default',
|
||||
params: {
|
||||
overrides: {
|
||||
removeViewBox: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
38
packages/docusaurus-utils/src/constants.ts
Normal file
38
packages/docusaurus-utils/src/constants.ts
Normal file
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export const NODE_MAJOR_VERSION = parseInt(
|
||||
process.versions.node.split('.')[0],
|
||||
10,
|
||||
);
|
||||
export const NODE_MINOR_VERSION = parseInt(
|
||||
process.versions.node.split('.')[1],
|
||||
10,
|
||||
);
|
||||
|
||||
// Can be overridden with cli option --out-dir
|
||||
export const DEFAULT_BUILD_DIR_NAME = 'build';
|
||||
|
||||
// Can be overridden with cli option --config
|
||||
export const DEFAULT_CONFIG_FILE_NAME = 'docusaurus.config.js';
|
||||
|
||||
export const BABEL_CONFIG_FILE_NAME =
|
||||
process.env.DOCUSAURUS_BABEL_CONFIG_FILE_NAME || 'babel.config.js';
|
||||
|
||||
export const GENERATED_FILES_DIR_NAME =
|
||||
process.env.DOCUSAURUS_GENERATED_FILES_DIR_NAME || '.docusaurus';
|
||||
|
||||
export const SRC_DIR_NAME = 'src';
|
||||
export const STATIC_DIR_NAME = 'static';
|
||||
export const OUTPUT_STATIC_ASSETS_DIR_NAME = 'assets'; // files handled by webpack, hashed (can be cached aggressively)
|
||||
export const THEME_PATH = `${SRC_DIR_NAME}/theme`;
|
||||
export const DEFAULT_PORT = 3000;
|
||||
export const DEFAULT_PLUGIN_ID = 'default';
|
||||
|
||||
// Temporary fix for https://github.com/facebook/docusaurus/issues/5493
|
||||
export const WEBPACK_URL_LOADER_LIMIT =
|
||||
process.env.WEBPACK_URL_LOADER_LIMIT ?? 10000;
|
|
@ -23,7 +23,9 @@ import resolvePathnameUnsafe from 'resolve-pathname';
|
|||
import {posixPath as posixPathImport} from './posixPath';
|
||||
import {simpleHash, docuHash} from './hashUtils';
|
||||
import {normalizeUrl} from './normalizeUrl';
|
||||
import {DEFAULT_PLUGIN_ID} from './constants';
|
||||
|
||||
export * from './constants';
|
||||
export * from './mdxUtils';
|
||||
export * from './normalizeUrl';
|
||||
export * from './tags';
|
||||
|
@ -41,6 +43,7 @@ export {
|
|||
createMatcher,
|
||||
createAbsoluteFilePathMatcher,
|
||||
} from './globUtils';
|
||||
export * from './webpackUtils';
|
||||
|
||||
const fileHash = new Map();
|
||||
export async function generate(
|
||||
|
@ -282,7 +285,7 @@ export function getPluginI18nPath({
|
|||
siteDir,
|
||||
locale,
|
||||
pluginName,
|
||||
pluginId = 'default', // TODO duplicated constant
|
||||
pluginId = DEFAULT_PLUGIN_ID,
|
||||
subPaths = [],
|
||||
}: {
|
||||
siteDir: string;
|
||||
|
@ -298,10 +301,7 @@ export function getPluginI18nPath({
|
|||
locale,
|
||||
// Make it convenient to use for single-instance
|
||||
// ie: return "docs", not "docs-default" nor "docs/default"
|
||||
`${pluginName}${
|
||||
// TODO duplicate constant :(
|
||||
pluginId === 'default' ? '' : `-${pluginId}`
|
||||
}`,
|
||||
`${pluginName}${pluginId === DEFAULT_PLUGIN_ID ? '' : `-${pluginId}`}`,
|
||||
...subPaths,
|
||||
);
|
||||
}
|
||||
|
|
144
packages/docusaurus-utils/src/webpackUtils.ts
Normal file
144
packages/docusaurus-utils/src/webpackUtils.ts
Normal file
|
@ -0,0 +1,144 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import type {RuleSetRule} from 'webpack';
|
||||
import path from 'path';
|
||||
import {posixPath} from './posixPath';
|
||||
import {
|
||||
WEBPACK_URL_LOADER_LIMIT,
|
||||
OUTPUT_STATIC_ASSETS_DIR_NAME,
|
||||
} from './constants';
|
||||
|
||||
type AssetFolder = 'images' | 'files' | 'fonts' | 'medias';
|
||||
|
||||
type FileLoaderUtils = {
|
||||
loaders: {
|
||||
file: (options: {folder: AssetFolder}) => RuleSetRule;
|
||||
url: (options: {folder: AssetFolder}) => RuleSetRule;
|
||||
inlineMarkdownImageFileLoader: string;
|
||||
inlineMarkdownLinkFileLoader: string;
|
||||
};
|
||||
rules: {
|
||||
images: () => RuleSetRule;
|
||||
fonts: () => RuleSetRule;
|
||||
media: () => RuleSetRule;
|
||||
svg: () => RuleSetRule;
|
||||
otherAssets: () => RuleSetRule;
|
||||
};
|
||||
};
|
||||
|
||||
// Inspired by https://github.com/gatsbyjs/gatsby/blob/8e6e021014da310b9cc7d02e58c9b3efe938c665/packages/gatsby/src/utils/webpack-utils.ts#L447
|
||||
export function getFileLoaderUtils(): FileLoaderUtils {
|
||||
// files/images < urlLoaderLimit will be inlined as base64 strings directly in the html
|
||||
const urlLoaderLimit = WEBPACK_URL_LOADER_LIMIT;
|
||||
|
||||
// defines the path/pattern of the assets handled by webpack
|
||||
const fileLoaderFileName = (folder: AssetFolder) =>
|
||||
`${OUTPUT_STATIC_ASSETS_DIR_NAME}/${folder}/[name]-[hash].[ext]`;
|
||||
|
||||
const loaders: FileLoaderUtils['loaders'] = {
|
||||
file: (options: {folder: AssetFolder}) => ({
|
||||
loader: require.resolve(`file-loader`),
|
||||
options: {
|
||||
name: fileLoaderFileName(options.folder),
|
||||
},
|
||||
}),
|
||||
url: (options: {folder: AssetFolder}) => ({
|
||||
loader: require.resolve('url-loader'),
|
||||
options: {
|
||||
limit: urlLoaderLimit,
|
||||
name: fileLoaderFileName(options.folder),
|
||||
fallback: require.resolve('file-loader'),
|
||||
},
|
||||
}),
|
||||
|
||||
// TODO find a better solution to avoid conflicts with the ideal-image plugin
|
||||
// TODO this may require a little breaking change for ideal-image users?
|
||||
// Maybe with the ideal image plugin, all md images should be "ideal"?
|
||||
// This is used to force url-loader+file-loader on markdown images
|
||||
// https://webpack.js.org/concepts/loaders/#inline
|
||||
inlineMarkdownImageFileLoader: `!${posixPath(
|
||||
require.resolve('url-loader'),
|
||||
)}?limit=${urlLoaderLimit}&name=${fileLoaderFileName(
|
||||
'images',
|
||||
)}&fallback=${posixPath(require.resolve('file-loader'))}!`,
|
||||
inlineMarkdownLinkFileLoader: `!${posixPath(
|
||||
require.resolve('file-loader'),
|
||||
)}?name=${fileLoaderFileName('files')}!`,
|
||||
};
|
||||
|
||||
const rules: FileLoaderUtils['rules'] = {
|
||||
/**
|
||||
* Loads image assets, inlines images via a data URI if they are below
|
||||
* the size threshold
|
||||
*/
|
||||
images: () => ({
|
||||
use: [loaders.url({folder: 'images'})],
|
||||
test: /\.(ico|jpg|jpeg|png|gif|webp)(\?.*)?$/,
|
||||
}),
|
||||
|
||||
fonts: () => ({
|
||||
use: [loaders.url({folder: 'fonts'})],
|
||||
test: /\.(woff|woff2|eot|ttf|otf)$/,
|
||||
}),
|
||||
|
||||
/**
|
||||
* Loads audio and video and inlines them via a data URI if they are below
|
||||
* the size threshold
|
||||
*/
|
||||
media: () => ({
|
||||
use: [loaders.url({folder: 'medias'})],
|
||||
test: /\.(mp4|webm|ogv|wav|mp3|m4a|aac|oga|flac)$/,
|
||||
}),
|
||||
|
||||
svg: () => ({
|
||||
test: /\.svg?$/,
|
||||
oneOf: [
|
||||
{
|
||||
use: [
|
||||
{
|
||||
loader: require.resolve('@svgr/webpack'),
|
||||
options: {
|
||||
prettier: false,
|
||||
svgo: true,
|
||||
svgoConfig: {
|
||||
plugins: [
|
||||
{
|
||||
name: 'preset-default',
|
||||
params: {
|
||||
overrides: {
|
||||
removeViewBox: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
titleProp: true,
|
||||
ref: ![path],
|
||||
},
|
||||
},
|
||||
],
|
||||
// We don't want to use SVGR loader for non-React source code
|
||||
// ie we don't want to use SVGR for CSS files...
|
||||
issuer: {
|
||||
and: [/\.(ts|tsx|js|jsx|md|mdx)$/],
|
||||
},
|
||||
},
|
||||
{
|
||||
use: [loaders.url({folder: 'images'})],
|
||||
},
|
||||
],
|
||||
}),
|
||||
|
||||
otherAssets: () => ({
|
||||
use: [loaders.file({folder: 'files'})],
|
||||
test: /\.(pdf|doc|docx|xls|xlsx|zip|rar)$/,
|
||||
}),
|
||||
};
|
||||
|
||||
return {loaders, rules};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue