mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-27 16:06:59 +02:00
fix(v2): fix Webpack persistent caching (evict on swizzle/alias/config change) (#5047)
* webpack upgrade * refactor docusaurus-utils hash fns * Fix webpack cache eviction problems on config/aliases/swizzle changes * Move/Rename InitPlugin type * fix TS typos * Add tests for webpack aliases * fix windows tests
This commit is contained in:
parent
9916a0b4a4
commit
99270dbab2
38 changed files with 274 additions and 169 deletions
|
@ -34,7 +34,7 @@
|
|||
"stringify-object": "^3.3.0",
|
||||
"unist-util-visit": "^2.0.2",
|
||||
"url-loader": "^4.1.1",
|
||||
"webpack": "^5.37.0"
|
||||
"webpack": "^5.40.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/types": "2.0.0-beta.1",
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
"reading-time": "^1.3.0",
|
||||
"remark-admonitions": "^1.2.1",
|
||||
"tslib": "^2.2.0",
|
||||
"webpack": "^5.37.0"
|
||||
"webpack": "^5.40.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.4 || ^17.0.0",
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
"shelljs": "^0.8.4",
|
||||
"tslib": "^2.2.0",
|
||||
"utility-types": "^3.10.0",
|
||||
"webpack": "^5.37.0"
|
||||
"webpack": "^5.40.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.4 || ^17.0.0",
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
"remark-admonitions": "^1.2.1",
|
||||
"slash": "^3.0.0",
|
||||
"tslib": "^2.1.0",
|
||||
"webpack": "^5.28.0"
|
||||
"webpack": "^5.40.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.4 || ^17.0.0",
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
"react-waypoint": "^10.1.0",
|
||||
"sharp": "^0.28.2",
|
||||
"tslib": "^2.1.0",
|
||||
"webpack": "^5.28.0"
|
||||
"webpack": "^5.40.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.4 || ^17.0.0",
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
"babel-loader": "^8.2.2",
|
||||
"clsx": "^1.1.1",
|
||||
"core-js": "^2.6.5",
|
||||
"terser-webpack-plugin": "^5.1.1",
|
||||
"webpack": "^5.28.0",
|
||||
"terser-webpack-plugin": "^5.1.3",
|
||||
"webpack": "^5.40.0",
|
||||
"webpack-merge": "^5.7.3",
|
||||
"workbox-build": "^6.1.1",
|
||||
"workbox-precaching": "^6.1.1",
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
"commander": "^5.1.0",
|
||||
"joi": "^17.4.0",
|
||||
"querystring": "0.2.0",
|
||||
"webpack": "^5.37.0",
|
||||
"webpack-merge": "^5.7.3"
|
||||
"webpack": "^5.40.0",
|
||||
"webpack-merge": "^5.8.0"
|
||||
}
|
||||
}
|
||||
|
|
10
packages/docusaurus-types/src/index.d.ts
vendored
10
packages/docusaurus-types/src/index.d.ts
vendored
|
@ -283,6 +283,13 @@ export interface Plugin<Content> {
|
|||
}): ThemeConfig;
|
||||
}
|
||||
|
||||
export type InitializedPlugin = Plugin<unknown> & {
|
||||
readonly options: PluginOptions;
|
||||
readonly version: DocusaurusPluginVersionInformation;
|
||||
};
|
||||
|
||||
export type LoadedPlugin = InitializedPlugin & {readonly content: unknown};
|
||||
|
||||
export type PluginModule = {
|
||||
<T, X>(context: LoadContext, options: T): Plugin<X>;
|
||||
validateOptions?<T>(data: OptionValidationContext<T>): T;
|
||||
|
@ -337,7 +344,8 @@ export interface RouteConfig {
|
|||
priority?: number;
|
||||
}
|
||||
|
||||
export interface ThemeAlias {
|
||||
// Aliases used for Webpack resolution (when using docusaurus swizzle)
|
||||
export interface ThemeAliases {
|
||||
[alias: string]: string;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,28 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {docuHash} from '../docuHash';
|
||||
import {simpleHash, docuHash} from '../hashUtils';
|
||||
|
||||
describe('hashUtils', () => {
|
||||
test('simpleHash', () => {
|
||||
const asserts: Record<string, string> = {
|
||||
'': 'd41',
|
||||
'/foo-bar': '096',
|
||||
'/foo/bar': '1df',
|
||||
'/endi/lie': '9fa',
|
||||
'/endi-lie': 'fd3',
|
||||
'/yangshun/tay': '48d',
|
||||
'/yangshun-tay': 'f3b',
|
||||
'/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar':
|
||||
'd46',
|
||||
'/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/test1-test2':
|
||||
'787',
|
||||
};
|
||||
Object.keys(asserts).forEach((str) => {
|
||||
expect(simpleHash(str, 3)).toBe(asserts[str]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('docuHash', () => {
|
||||
test('docuHash works', () => {
|
|
@ -5,28 +5,9 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {simpleHash, isNameTooLong, shortName} from '../pathUtils';
|
||||
import {isNameTooLong, shortName} from '../pathUtils';
|
||||
|
||||
describe('pathUtils', () => {
|
||||
test('simpleHash', () => {
|
||||
const asserts: Record<string, string> = {
|
||||
'': 'd41',
|
||||
'/foo-bar': '096',
|
||||
'/foo/bar': '1df',
|
||||
'/endi/lie': '9fa',
|
||||
'/endi-lie': 'fd3',
|
||||
'/yangshun/tay': '48d',
|
||||
'/yangshun-tay': 'f3b',
|
||||
'/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar':
|
||||
'd46',
|
||||
'/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/test1-test2':
|
||||
'787',
|
||||
};
|
||||
Object.keys(asserts).forEach((file) => {
|
||||
expect(simpleHash(file, 3)).toBe(asserts[file]);
|
||||
});
|
||||
});
|
||||
|
||||
test('isNameTooLong', () => {
|
||||
const asserts: Record<string, boolean> = {
|
||||
'': false,
|
||||
|
|
|
@ -5,10 +5,19 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {createHash} from 'crypto';
|
||||
import {kebabCase} from 'lodash';
|
||||
import {shortName, isNameTooLong} from './pathUtils';
|
||||
|
||||
import {shortName, isNameTooLong, simpleHash} from './pathUtils';
|
||||
export function md5Hash(str: string): string {
|
||||
return createHash('md5').update(str).digest('hex');
|
||||
}
|
||||
|
||||
export function simpleHash(str: string, length: number): string {
|
||||
return md5Hash(str).substr(0, length);
|
||||
}
|
||||
|
||||
// Based on https://github.com/gatsbyjs/gatsby/pull/21518/files
|
||||
/**
|
||||
* Given an input string, convert to kebab-case and append a hash.
|
||||
* Avoid str collision.
|
|
@ -22,8 +22,7 @@ import {
|
|||
import resolvePathnameUnsafe from 'resolve-pathname';
|
||||
|
||||
import {posixPath as posixPathImport} from './posixPath';
|
||||
import {simpleHash} from './pathUtils';
|
||||
import {docuHash} from './docuHash';
|
||||
import {simpleHash, docuHash} from './hashUtils';
|
||||
|
||||
export const posixPath = posixPathImport;
|
||||
|
||||
|
@ -32,8 +31,7 @@ export * from './codeTranslationsUtils';
|
|||
export * from './markdownParser';
|
||||
export * from './markdownLinks';
|
||||
export * from './escapePath';
|
||||
export * from './docuHash';
|
||||
export {simpleHash} from './pathUtils';
|
||||
export {md5Hash, simpleHash, docuHash} from './hashUtils';
|
||||
|
||||
const fileHash = new Map();
|
||||
export async function generate(
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
|
||||
// Based on https://github.com/gatsbyjs/gatsby/pull/21518/files
|
||||
|
||||
import {createHash} from 'crypto';
|
||||
|
||||
// MacOS (APFS) and Windows (NTFS) filename length limit = 255 chars, Others = 255 bytes
|
||||
const MAX_PATH_SEGMENT_CHARS = 255;
|
||||
const MAX_PATH_SEGMENT_BYTES = 255;
|
||||
|
@ -42,7 +40,3 @@ export const shortName = (str: string): string => {
|
|||
)
|
||||
.toString();
|
||||
};
|
||||
|
||||
export function simpleHash(str: string, length: number): string {
|
||||
return createHash('md5').update(str).digest('hex').substr(0, length);
|
||||
}
|
||||
|
|
|
@ -63,10 +63,10 @@
|
|||
"chokidar": "^3.5.1",
|
||||
"clean-css": "^5.1.2",
|
||||
"commander": "^5.1.0",
|
||||
"copy-webpack-plugin": "^8.1.1",
|
||||
"copy-webpack-plugin": "^9.0.0",
|
||||
"core-js": "^3.9.1",
|
||||
"css-loader": "^5.1.1",
|
||||
"css-minimizer-webpack-plugin": "^2.0.0",
|
||||
"css-minimizer-webpack-plugin": "^3.0.1",
|
||||
"cssnano": "^5.0.4",
|
||||
"del": "^6.0.0",
|
||||
"detect-port": "^1.3.0",
|
||||
|
@ -79,7 +79,7 @@
|
|||
"globby": "^11.0.2",
|
||||
"html-minifier-terser": "^5.1.1",
|
||||
"html-tags": "^3.1.0",
|
||||
"html-webpack-plugin": "^5.3.1",
|
||||
"html-webpack-plugin": "^5.3.2",
|
||||
"import-fresh": "^3.3.0",
|
||||
"is-root": "^2.1.0",
|
||||
"leven": "^3.1.0",
|
||||
|
@ -105,15 +105,15 @@
|
|||
"shelljs": "^0.8.4",
|
||||
"std-env": "^2.2.1",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"terser-webpack-plugin": "^5.1.2",
|
||||
"terser-webpack-plugin": "^5.1.3",
|
||||
"tslib": "^2.2.0",
|
||||
"update-notifier": "^5.1.0",
|
||||
"url-loader": "^4.1.1",
|
||||
"wait-on": "^5.3.0",
|
||||
"webpack": "^5.37.0",
|
||||
"webpack": "^5.40.0",
|
||||
"webpack-bundle-analyzer": "^4.4.2",
|
||||
"webpack-dev-server": "^3.11.2",
|
||||
"webpack-merge": "^5.7.3",
|
||||
"webpack-merge": "^5.8.0",
|
||||
"webpackbar": "^5.0.0-3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
import {ConfigOptions} from '@docusaurus/types';
|
||||
import {ConfigOptions, InitializedPlugin} from '@docusaurus/types';
|
||||
import {loadContext, loadPluginConfigs} from '../server';
|
||||
import initPlugins, {InitPlugin} from '../server/plugins/init';
|
||||
import initPlugins from '../server/plugins/init';
|
||||
|
||||
import {
|
||||
writePluginTranslations,
|
||||
|
@ -25,7 +25,7 @@ async function writePluginTranslationFiles({
|
|||
options,
|
||||
}: {
|
||||
siteDir: string;
|
||||
plugin: InitPlugin;
|
||||
plugin: InitializedPlugin;
|
||||
locale: string;
|
||||
options: WriteTranslationsOptions;
|
||||
}) {
|
||||
|
|
|
@ -6,8 +6,12 @@
|
|||
*/
|
||||
|
||||
import htmlTagObjectToString from './htmlTags';
|
||||
import {InjectedHtmlTags, HtmlTagObject, HtmlTags} from '@docusaurus/types';
|
||||
import {LoadedPlugin} from '../plugins';
|
||||
import {
|
||||
InjectedHtmlTags,
|
||||
HtmlTagObject,
|
||||
HtmlTags,
|
||||
LoadedPlugin,
|
||||
} from '@docusaurus/types';
|
||||
|
||||
function toString(val: string | HtmlTagObject): string {
|
||||
return typeof val === 'string' ? val : htmlTagObjectToString(val);
|
||||
|
|
|
@ -13,14 +13,12 @@ import {
|
|||
DEFAULT_BUILD_DIR_NAME,
|
||||
DEFAULT_CONFIG_FILE_NAME,
|
||||
GENERATED_FILES_DIR_NAME,
|
||||
THEME_PATH,
|
||||
} from '../constants';
|
||||
import loadClientModules from './client-modules';
|
||||
import loadConfig from './config';
|
||||
import {loadPlugins} from './plugins';
|
||||
import loadPresets from './presets';
|
||||
import loadRoutes from './routes';
|
||||
import loadThemeAlias from './themes';
|
||||
import {
|
||||
DocusaurusConfig,
|
||||
DocusaurusSiteMetadata,
|
||||
|
@ -178,14 +176,6 @@ export async function load(
|
|||
`export default ${JSON.stringify(siteConfig, null, 2)};`,
|
||||
);
|
||||
|
||||
// Themes.
|
||||
const fallbackTheme = path.resolve(__dirname, '../client/theme-fallback');
|
||||
const pluginThemes: string[] = plugins
|
||||
.map((plugin) => plugin.getThemePath && plugin.getThemePath())
|
||||
.filter((x): x is string => Boolean(x));
|
||||
const userTheme = path.resolve(siteDir, THEME_PATH);
|
||||
const alias = loadThemeAlias([fallbackTheme, ...pluginThemes], [userTheme]);
|
||||
|
||||
// Make a fake plugin to:
|
||||
// - Resolve aliased theme components
|
||||
// - Inject scripts/stylesheets
|
||||
|
@ -202,11 +192,6 @@ export async function load(
|
|||
getClientModules() {
|
||||
return siteConfigClientModules;
|
||||
},
|
||||
configureWebpack: () => ({
|
||||
resolve: {
|
||||
alias,
|
||||
},
|
||||
}),
|
||||
injectHtmlTags: () => {
|
||||
const stylesheetsTags = stylesheets.map((source) =>
|
||||
typeof source === 'string'
|
||||
|
|
|
@ -5,11 +5,10 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {InitializedPlugin} from '@docusaurus/types';
|
||||
import {ensureUniquePluginInstanceIds} from '../pluginIds';
|
||||
|
||||
import {InitPlugin} from '../init';
|
||||
|
||||
function createTestPlugin(name: string, id?: string): InitPlugin {
|
||||
function createTestPlugin(name: string, id?: string): InitializedPlugin {
|
||||
// @ts-expect-error: good enough for tests
|
||||
return {
|
||||
name,
|
||||
|
|
|
@ -16,8 +16,10 @@ import {
|
|||
AllContent,
|
||||
TranslationFiles,
|
||||
ThemeConfig,
|
||||
LoadedPlugin,
|
||||
InitializedPlugin,
|
||||
} from '@docusaurus/types';
|
||||
import initPlugins, {InitPlugin} from './init';
|
||||
import initPlugins from './init';
|
||||
import chalk from 'chalk';
|
||||
import {DEFAULT_PLUGIN_ID} from '../../constants';
|
||||
import {chain} from 'lodash';
|
||||
|
@ -53,8 +55,6 @@ export function sortConfig(routeConfigs: RouteConfig[]): void {
|
|||
});
|
||||
}
|
||||
|
||||
export type LoadedPlugin = InitPlugin & {content: unknown};
|
||||
|
||||
export async function loadPlugins({
|
||||
pluginConfigs,
|
||||
context,
|
||||
|
@ -68,7 +68,7 @@ export async function loadPlugins({
|
|||
themeConfigTranslated: ThemeConfig;
|
||||
}> {
|
||||
// 1. Plugin Lifecycle - Initialization/Constructor.
|
||||
const plugins: InitPlugin[] = initPlugins({
|
||||
const plugins: InitializedPlugin[] = initPlugins({
|
||||
pluginConfigs,
|
||||
context,
|
||||
});
|
||||
|
|
|
@ -12,9 +12,9 @@ import {
|
|||
ImportedPluginModule,
|
||||
LoadContext,
|
||||
PluginModule,
|
||||
Plugin,
|
||||
PluginConfig,
|
||||
PluginOptions,
|
||||
InitializedPlugin,
|
||||
} from '@docusaurus/types';
|
||||
import {DEFAULT_PLUGIN_ID} from '../../constants';
|
||||
import {getPluginVersion} from '../versions';
|
||||
|
@ -124,18 +124,13 @@ function getThemeValidationFunction(
|
|||
}
|
||||
}
|
||||
|
||||
export type InitPlugin = Plugin<unknown> & {
|
||||
readonly options: PluginOptions;
|
||||
readonly version: DocusaurusPluginVersionInformation;
|
||||
};
|
||||
|
||||
export default function initPlugins({
|
||||
pluginConfigs,
|
||||
context,
|
||||
}: {
|
||||
pluginConfigs: PluginConfig[];
|
||||
context: LoadContext;
|
||||
}): InitPlugin[] {
|
||||
}): InitializedPlugin[] {
|
||||
// We need to resolve plugins from the perspective of the siteDir, since the siteDir's package.json
|
||||
// declares the dependency on these plugins.
|
||||
// We need to fallback to createRequireFromPath since createRequire is only available in node v12.
|
||||
|
@ -192,7 +187,7 @@ export default function initPlugins({
|
|||
}
|
||||
}
|
||||
|
||||
const plugins: InitPlugin[] = pluginConfigs
|
||||
const plugins: InitializedPlugin[] = pluginConfigs
|
||||
.map((pluginConfig) => {
|
||||
if (!pluginConfig) {
|
||||
return null;
|
||||
|
|
|
@ -6,12 +6,14 @@
|
|||
*/
|
||||
|
||||
import {groupBy} from 'lodash';
|
||||
import {InitPlugin} from './init';
|
||||
import {DEFAULT_PLUGIN_ID} from '../../constants';
|
||||
import {InitializedPlugin} from '@docusaurus/types';
|
||||
|
||||
// It is forbidden to have 2 plugins of the same name sharing the same id
|
||||
// this is required to support multi-instance plugins without conflict
|
||||
export function ensureUniquePluginInstanceIds(plugins: InitPlugin[]): void {
|
||||
export function ensureUniquePluginInstanceIds(
|
||||
plugins: InitializedPlugin[],
|
||||
): void {
|
||||
const pluginsByName = groupBy(plugins, (p) => p.name);
|
||||
Object.entries(pluginsByName).forEach(([pluginName, pluginInstances]) => {
|
||||
const pluginInstancesById = groupBy(
|
||||
|
|
|
@ -6,15 +6,15 @@
|
|||
*/
|
||||
|
||||
import path from 'path';
|
||||
import loadThemeAlias from '../index';
|
||||
import {loadThemeAliases} from '../index';
|
||||
|
||||
describe('loadThemeAlias', () => {
|
||||
describe('loadThemeAliases', () => {
|
||||
test('next alias can override the previous alias', () => {
|
||||
const fixtures = path.join(__dirname, '__fixtures__');
|
||||
const theme1Path = path.join(fixtures, 'theme-1');
|
||||
const theme2Path = path.join(fixtures, 'theme-2');
|
||||
|
||||
const alias = loadThemeAlias([theme1Path, theme2Path]);
|
||||
const alias = loadThemeAliases([theme1Path, theme2Path]);
|
||||
expect(alias).toEqual({
|
||||
'@theme-init/Layout': path.join(theme1Path, 'Layout.js'), // TODO: Write separate test case for this?
|
||||
'@theme/Footer': path.join(theme1Path, 'Footer/index.js'),
|
||||
|
|
|
@ -9,13 +9,14 @@ import globby from 'globby';
|
|||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import {fileToPath, posixPath, normalizeUrl} from '@docusaurus/utils';
|
||||
import {ThemeAlias} from '@docusaurus/types';
|
||||
import {ThemeAliases} from '@docusaurus/types';
|
||||
import {sortBy} from 'lodash';
|
||||
|
||||
// TODO make async
|
||||
export default function themeAlias(
|
||||
themePath: string,
|
||||
addOriginalAlias: boolean,
|
||||
): ThemeAlias {
|
||||
): ThemeAliases {
|
||||
if (!fs.pathExistsSync(themePath)) {
|
||||
return {};
|
||||
}
|
||||
|
@ -30,7 +31,7 @@ export default function themeAlias(
|
|||
file.endsWith('/index.js'),
|
||||
);
|
||||
|
||||
const aliases: ThemeAlias = {};
|
||||
const aliases: ThemeAliases = {};
|
||||
|
||||
sortedThemeComponentFiles.forEach((relativeSource) => {
|
||||
const filePath = path.join(themePath, relativeSource);
|
||||
|
|
|
@ -5,13 +5,17 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {ThemeAlias} from '@docusaurus/types';
|
||||
import {ThemeAliases, LoadedPlugin} from '@docusaurus/types';
|
||||
import path from 'path';
|
||||
import {THEME_PATH} from '../../constants';
|
||||
import themeAlias from './alias';
|
||||
|
||||
const ThemeFallbackDir = path.resolve(__dirname, '../../client/theme-fallback');
|
||||
|
||||
function buildThemeAliases(
|
||||
themeAliases: ThemeAlias,
|
||||
aliases: ThemeAlias = {},
|
||||
): ThemeAlias {
|
||||
themeAliases: ThemeAliases,
|
||||
aliases: ThemeAliases = {},
|
||||
): ThemeAliases {
|
||||
Object.keys(themeAliases).forEach((aliasKey) => {
|
||||
if (aliasKey in aliases) {
|
||||
const componentName = aliasKey.substring(aliasKey.indexOf('/') + 1);
|
||||
|
@ -24,11 +28,11 @@ function buildThemeAliases(
|
|||
return aliases;
|
||||
}
|
||||
|
||||
export default function loadThemeAlias(
|
||||
export function loadThemeAliases(
|
||||
themePaths: string[],
|
||||
userThemePaths: string[] = [],
|
||||
): ThemeAlias {
|
||||
let aliases = {};
|
||||
): ThemeAliases {
|
||||
let aliases = {}; // TODO refactor, inelegant side-effect
|
||||
|
||||
themePaths.forEach((themePath) => {
|
||||
const themeAliases = themeAlias(themePath, true);
|
||||
|
@ -42,3 +46,17 @@ export default function loadThemeAlias(
|
|||
|
||||
return aliases;
|
||||
}
|
||||
|
||||
export function loadPluginsThemeAliases({
|
||||
siteDir,
|
||||
plugins,
|
||||
}: {
|
||||
siteDir: string;
|
||||
plugins: LoadedPlugin[];
|
||||
}): ThemeAliases {
|
||||
const pluginThemes: string[] = plugins
|
||||
.map((plugin) => (plugin.getThemePath ? plugin.getThemePath() : undefined))
|
||||
.filter((x): x is string => Boolean(x));
|
||||
const userTheme = path.resolve(siteDir, THEME_PATH);
|
||||
return loadThemeAliases([ThemeFallbackDir, ...pluginThemes], [userTheme]);
|
||||
}
|
||||
|
|
|
@ -17,9 +17,12 @@ import {
|
|||
} from '../translations';
|
||||
import fs from 'fs-extra';
|
||||
import tmp from 'tmp-promise';
|
||||
import {TranslationFile, TranslationFileContent} from '@docusaurus/types';
|
||||
import {
|
||||
InitializedPlugin,
|
||||
TranslationFile,
|
||||
TranslationFileContent,
|
||||
} from '@docusaurus/types';
|
||||
import path from 'path';
|
||||
import {InitPlugin} from '../../plugins/init';
|
||||
|
||||
async function createTmpSiteDir() {
|
||||
const {path: siteDirPath} = await tmp.dir({
|
||||
|
@ -467,27 +470,27 @@ describe('localizePluginTranslationFile', () => {
|
|||
|
||||
describe('getPluginsDefaultCodeTranslationMessages', () => {
|
||||
function createTestPlugin(
|
||||
fn: InitPlugin['getDefaultCodeTranslationMessages'],
|
||||
): InitPlugin {
|
||||
return {getDefaultCodeTranslationMessages: fn} as InitPlugin;
|
||||
fn: InitializedPlugin['getDefaultCodeTranslationMessages'],
|
||||
): InitializedPlugin {
|
||||
return {getDefaultCodeTranslationMessages: fn} as InitializedPlugin;
|
||||
}
|
||||
|
||||
test('for empty plugins', async () => {
|
||||
const plugins: InitPlugin[] = [];
|
||||
const plugins: InitializedPlugin[] = [];
|
||||
await expect(
|
||||
getPluginsDefaultCodeTranslationMessages(plugins),
|
||||
).resolves.toEqual({});
|
||||
});
|
||||
|
||||
test('for 1 plugin without lifecycle', async () => {
|
||||
const plugins: InitPlugin[] = [createTestPlugin(undefined)];
|
||||
const plugins: InitializedPlugin[] = [createTestPlugin(undefined)];
|
||||
await expect(
|
||||
getPluginsDefaultCodeTranslationMessages(plugins),
|
||||
).resolves.toEqual({});
|
||||
});
|
||||
|
||||
test('for 1 plugin with lifecycle', async () => {
|
||||
const plugins: InitPlugin[] = [
|
||||
const plugins: InitializedPlugin[] = [
|
||||
createTestPlugin(async () => ({
|
||||
a: '1',
|
||||
b: '2',
|
||||
|
@ -502,7 +505,7 @@ describe('getPluginsDefaultCodeTranslationMessages', () => {
|
|||
});
|
||||
|
||||
test('for 2 plugins with lifecycles', async () => {
|
||||
const plugins: InitPlugin[] = [
|
||||
const plugins: InitializedPlugin[] = [
|
||||
createTestPlugin(async () => ({
|
||||
a: '1',
|
||||
b: '2',
|
||||
|
@ -523,7 +526,7 @@ describe('getPluginsDefaultCodeTranslationMessages', () => {
|
|||
});
|
||||
|
||||
test('for realistic use-case', async () => {
|
||||
const plugins: InitPlugin[] = [
|
||||
const plugins: InitializedPlugin[] = [
|
||||
createTestPlugin(undefined),
|
||||
createTestPlugin(async () => ({
|
||||
a: '1',
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
} from '../translationsExtractor';
|
||||
import {getBabelOptions} from '../../../webpack/utils';
|
||||
import path from 'path';
|
||||
import {InitPlugin} from '../../plugins/init';
|
||||
import {InitializedPlugin} from '@docusaurus/types';
|
||||
import {SRC_DIR_NAME} from '../../../constants';
|
||||
|
||||
const TestBabelOptions = getBabelOptions({
|
||||
|
@ -258,7 +258,7 @@ export default function MySiteComponent1() {
|
|||
`,
|
||||
);
|
||||
|
||||
function createTestPlugin(pluginDir: string): InitPlugin {
|
||||
function createTestPlugin(pluginDir: string): InitializedPlugin {
|
||||
// @ts-expect-error: good enough for this test
|
||||
return {
|
||||
name: 'abc',
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
*/
|
||||
import path from 'path';
|
||||
import fs from 'fs-extra';
|
||||
import {InitPlugin} from '../plugins/init';
|
||||
import {mapValues, difference} from 'lodash';
|
||||
import {
|
||||
TranslationFileContent,
|
||||
TranslationFile,
|
||||
TranslationMessage,
|
||||
InitializedPlugin,
|
||||
} from '@docusaurus/types';
|
||||
import {getPluginI18nPath, toMessageRelativeFilePath} from '@docusaurus/utils';
|
||||
import {Joi} from '@docusaurus/utils-validation';
|
||||
|
@ -193,7 +193,7 @@ function getPluginTranslationFilePath({
|
|||
locale,
|
||||
translationFilePath,
|
||||
}: TranslationContext & {
|
||||
plugin: InitPlugin;
|
||||
plugin: InitializedPlugin;
|
||||
translationFilePath: string;
|
||||
}): string {
|
||||
const dirPath = getPluginI18nPath({
|
||||
|
@ -213,7 +213,7 @@ export async function writePluginTranslations({
|
|||
translationFile,
|
||||
options,
|
||||
}: TranslationContext & {
|
||||
plugin: InitPlugin;
|
||||
plugin: InitializedPlugin;
|
||||
translationFile: TranslationFile;
|
||||
options?: WriteTranslationsOptions;
|
||||
}): Promise<void> {
|
||||
|
@ -236,7 +236,7 @@ export async function localizePluginTranslationFile({
|
|||
locale,
|
||||
translationFile,
|
||||
}: TranslationContext & {
|
||||
plugin: InitPlugin;
|
||||
plugin: InitializedPlugin;
|
||||
translationFile: TranslationFile;
|
||||
}): Promise<TranslationFile> {
|
||||
const filePath = getPluginTranslationFilePath({
|
||||
|
@ -263,7 +263,7 @@ export async function localizePluginTranslationFile({
|
|||
}
|
||||
|
||||
export async function getPluginsDefaultCodeTranslationMessages(
|
||||
plugins: InitPlugin[],
|
||||
plugins: InitializedPlugin[],
|
||||
): Promise<Record<string, string>> {
|
||||
const pluginsMessages = await Promise.all(
|
||||
plugins.map((plugin) => plugin.getDefaultCodeTranslationMessages?.() ?? {}),
|
||||
|
|
|
@ -10,9 +10,12 @@ import generate from '@babel/generator';
|
|||
import chalk from 'chalk';
|
||||
import {parse, types as t, NodePath, TransformOptions} from '@babel/core';
|
||||
import {flatten} from 'lodash';
|
||||
import {TranslationFileContent, TranslationMessage} from '@docusaurus/types';
|
||||
import {
|
||||
InitializedPlugin,
|
||||
TranslationFileContent,
|
||||
TranslationMessage,
|
||||
} from '@docusaurus/types';
|
||||
import nodePath from 'path';
|
||||
import {InitPlugin} from '../plugins/init';
|
||||
import {SRC_DIR_NAME} from '../../constants';
|
||||
import {safeGlobby} from '../utils';
|
||||
|
||||
|
@ -35,7 +38,7 @@ function getSiteSourceCodeFilePaths(siteDir: string): string[] {
|
|||
return [nodePath.join(siteDir, SRC_DIR_NAME)];
|
||||
}
|
||||
|
||||
function getPluginSourceCodeFilePaths(plugin: InitPlugin): string[] {
|
||||
function getPluginSourceCodeFilePaths(plugin: InitializedPlugin): string[] {
|
||||
// The getPathsToWatch() generally returns the js/jsx/ts/tsx/md/mdx file paths
|
||||
// We can use this method as well to know which folders we should try to extract translations from
|
||||
// Hacky/implicit, but do we want to introduce a new lifecycle method just for that???
|
||||
|
@ -59,7 +62,7 @@ export async function globSourceCodeFilePaths(
|
|||
|
||||
async function getSourceCodeFilePaths(
|
||||
siteDir: string,
|
||||
plugins: InitPlugin[],
|
||||
plugins: InitializedPlugin[],
|
||||
): Promise<string[]> {
|
||||
const sitePaths = getSiteSourceCodeFilePaths(siteDir);
|
||||
|
||||
|
@ -75,7 +78,7 @@ async function getSourceCodeFilePaths(
|
|||
|
||||
export async function extractSiteSourceCodeTranslations(
|
||||
siteDir: string,
|
||||
plugins: InitPlugin[],
|
||||
plugins: InitializedPlugin[],
|
||||
babelOptions: TransformOptions,
|
||||
): Promise<TranslationFileContent> {
|
||||
// Should we warn here if the same translation "key" is found in multiple source code files?
|
||||
|
|
|
@ -1,5 +1,46 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`base webpack config should create webpack aliases 1`] = `
|
||||
Object {
|
||||
"@docusaurus/BrowserOnly": "../../../../client/exports/BrowserOnly.tsx",
|
||||
"@docusaurus/ComponentCreator": "../../../../client/exports/ComponentCreator.tsx",
|
||||
"@docusaurus/ExecutionEnvironment": "../../../../client/exports/ExecutionEnvironment.ts",
|
||||
"@docusaurus/Head": "../../../../client/exports/Head.tsx",
|
||||
"@docusaurus/Interpolate": "../../../../client/exports/Interpolate.tsx",
|
||||
"@docusaurus/Link": "../../../../client/exports/Link.tsx",
|
||||
"@docusaurus/Noop": "../../../../client/exports/Noop.ts",
|
||||
"@docusaurus/Translate": "../../../../client/exports/Translate.tsx",
|
||||
"@docusaurus/constants": "../../../../client/exports/constants.ts",
|
||||
"@docusaurus/context": "../../../../client/exports/context.ts",
|
||||
"@docusaurus/isInternalUrl": "../../../../client/exports/isInternalUrl.ts",
|
||||
"@docusaurus/renderRoutes": "../../../../client/exports/renderRoutes.ts",
|
||||
"@docusaurus/router": "../../../../client/exports/router.ts",
|
||||
"@docusaurus/useBaseUrl": "../../../../client/exports/useBaseUrl.ts",
|
||||
"@docusaurus/useDocusaurusContext": "../../../../client/exports/useDocusaurusContext.ts",
|
||||
"@docusaurus/useGlobalData": "../../../../client/exports/useGlobalData.ts",
|
||||
"@generated": "../../../../../../..",
|
||||
"@site": "",
|
||||
"@theme-init/PluginThemeComponentOverridden": "pluginThemeFolder/PluginThemeComponentOverridden.js",
|
||||
"@theme-original/Layout": "../../../../client/theme-fallback/Layout/index.js",
|
||||
"@theme-original/Loading": "../../../../client/theme-fallback/Loading/index.js",
|
||||
"@theme-original/NotFound": "../../../../client/theme-fallback/NotFound/index.js",
|
||||
"@theme-original/PluginThemeComponent1": "pluginThemeFolder/PluginThemeComponent1.js",
|
||||
"@theme-original/PluginThemeComponentOverridden": "pluginThemeFolder/PluginThemeComponentOverridden.js",
|
||||
"@theme-original/Root": "../../../../client/theme-fallback/Root/index.js",
|
||||
"@theme-original/subfolder/PluginThemeComponent2": "pluginThemeFolder/subfolder/PluginThemeComponent2.js",
|
||||
"@theme/Layout": "../../../../client/theme-fallback/Layout/index.js",
|
||||
"@theme/Loading": "../../../../client/theme-fallback/Loading/index.js",
|
||||
"@theme/NotFound": "../../../../client/theme-fallback/NotFound/index.js",
|
||||
"@theme/PluginThemeComponent1": "pluginThemeFolder/PluginThemeComponent1.js",
|
||||
"@theme/PluginThemeComponentOverridden": "src/theme/PluginThemeComponentOverridden.js",
|
||||
"@theme/Root": "../../../../client/theme-fallback/Root/index.js",
|
||||
"@theme/UserThemeComponent1": "src/theme/UserThemeComponent1.js",
|
||||
"@theme/subfolder/PluginThemeComponent2": "pluginThemeFolder/subfolder/PluginThemeComponent2.js",
|
||||
"@theme/subfolder/UserThemeComponent2": "src/theme/subfolder/UserThemeComponent2.js",
|
||||
"react-loadable": "../../../../../../../@docusaurus/react-loadable",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`getDocusaurusAliases() return appropriate webpack aliases 1`] = `
|
||||
Object {
|
||||
"@docusaurus/BrowserOnly": "../../client/exports/BrowserOnly.tsx",
|
||||
|
|
|
@ -16,6 +16,7 @@ import {
|
|||
import * as utils from '../utils';
|
||||
import {mapValues} from 'lodash';
|
||||
import {posixPath} from '@docusaurus/utils';
|
||||
import {Props, ThemeAliases} from '@docusaurus/types';
|
||||
|
||||
describe('babel transpilation exclude logic', () => {
|
||||
test('always transpile client dir files', () => {
|
||||
|
@ -78,9 +79,9 @@ describe('getDocusaurusAliases()', () => {
|
|||
});
|
||||
|
||||
describe('base webpack config', () => {
|
||||
const props = {
|
||||
const props: Props = {
|
||||
outDir: '',
|
||||
siteDir: '',
|
||||
siteDir: path.resolve(__dirname, '__fixtures__', 'base_test_site'),
|
||||
siteConfig: {},
|
||||
baseUrl: '',
|
||||
generatedFilesDir: '',
|
||||
|
@ -91,12 +92,35 @@ describe('base webpack config', () => {
|
|||
siteMetadata: {
|
||||
docusaurusVersion: '2.0.0-alpha.70',
|
||||
},
|
||||
plugins: [
|
||||
{
|
||||
getThemePath() {
|
||||
return path.resolve(
|
||||
__dirname,
|
||||
'__fixtures__',
|
||||
'base_test_site',
|
||||
'pluginThemeFolder',
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
test('should create webpack aliases', () => {
|
||||
// @ts-expect-error: Docusaurus webpack alias is always an object
|
||||
const aliases: ThemeAliases =
|
||||
createBaseConfig(props, true).resolve?.alias ?? {};
|
||||
// Make aliases relative so that test work on all computers
|
||||
const relativeAliases = mapValues(aliases, (a) =>
|
||||
posixPath(path.relative(props.siteDir, a)),
|
||||
);
|
||||
expect(relativeAliases).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should use svg rule', () => {
|
||||
const fileLoaderUtils = utils.getFileLoaderUtils();
|
||||
const mockSvg = jest.spyOn(fileLoaderUtils.rules, 'svg');
|
||||
|
|
|
@ -19,6 +19,8 @@ import {
|
|||
} from './utils';
|
||||
import {STATIC_DIR_NAME} from '../constants';
|
||||
import SharedModuleAliases from './sharedModuleAliases';
|
||||
import {loadPluginsThemeAliases} from '../server/themes';
|
||||
import {md5Hash} from '@docusaurus/utils';
|
||||
|
||||
const CSS_REGEX = /\.css$/;
|
||||
const CSS_MODULE_REGEX = /\.module\.css$/;
|
||||
|
@ -74,10 +76,12 @@ export function createBaseConfig(
|
|||
outDir,
|
||||
siteDir,
|
||||
siteConfig,
|
||||
siteConfigPath,
|
||||
baseUrl,
|
||||
generatedFilesDir,
|
||||
routesPaths,
|
||||
siteMetadata,
|
||||
plugins,
|
||||
} = props;
|
||||
const totalPages = routesPaths.length;
|
||||
const isProd = process.env.NODE_ENV === 'production';
|
||||
|
@ -89,25 +93,32 @@ export function createBaseConfig(
|
|||
const name = isServer ? 'server' : 'client';
|
||||
const mode = isProd ? 'production' : 'development';
|
||||
|
||||
const themeAliases = loadPluginsThemeAliases({siteDir, plugins});
|
||||
|
||||
return {
|
||||
mode,
|
||||
name,
|
||||
cache: {
|
||||
// TODO temporary env variable to reduce risk of Webpack 5 release
|
||||
// maybe expose an official api, once this is solved? https://github.com/webpack/webpack/issues/13034
|
||||
type:
|
||||
(process.env.DOCUSAURUS_WEBPACK_CACHE_TYPE as 'filesystem') ||
|
||||
'filesystem',
|
||||
type: 'filesystem',
|
||||
// Can we share the same cache across locales?
|
||||
// Exploring that question at https://github.com/webpack/webpack/issues/13034
|
||||
// name: `${name}-${mode}`,
|
||||
name: `${name}-${mode}-${props.i18n.currentLocale}`,
|
||||
version: siteMetadata.docusaurusVersion,
|
||||
// When version string changes, cache is evicted
|
||||
version: [
|
||||
siteMetadata.docusaurusVersion,
|
||||
// Webpack does not evict the cache correctly on alias/swizzle change, so we force eviction.
|
||||
// See https://github.com/webpack/webpack/issues/13627
|
||||
md5Hash(JSON.stringify(themeAliases)),
|
||||
].join('-'),
|
||||
// When one of those modules/dependencies change (including transitive deps), cache is invalidated
|
||||
buildDependencies: {
|
||||
// When one of dependencies change, cache is invalidated
|
||||
config: [
|
||||
__filename,
|
||||
path.join(__dirname, isServer ? 'server.js' : 'client.js'),
|
||||
// Docusaurus config changes can affect MDX/JSX compilation, so we'd rather evict the cache.
|
||||
// See https://github.com/questdb/questdb.io/issues/493
|
||||
siteConfigPath,
|
||||
],
|
||||
},
|
||||
},
|
||||
|
@ -147,6 +158,7 @@ export function createBaseConfig(
|
|||
// so we use fine-grained aliases instead
|
||||
// '@docusaurus': path.resolve(__dirname, '../client/exports'),
|
||||
...getDocusaurusAliases(),
|
||||
...themeAliases,
|
||||
},
|
||||
// This allows you to set a fallback for where Webpack should look for modules.
|
||||
// We want `@docusaurus/core` own dependencies/`node_modules` to "win" if there is conflict
|
||||
|
|
87
yarn.lock
87
yarn.lock
|
@ -6716,13 +6716,13 @@ copy-text-to-clipboard@^3.0.1:
|
|||
resolved "https://registry.yarnpkg.com/copy-text-to-clipboard/-/copy-text-to-clipboard-3.0.1.tgz#8cbf8f90e0a47f12e4a24743736265d157bce69c"
|
||||
integrity sha512-rvVsHrpFcL4F2P8ihsoLdFHmd404+CMg71S756oRSeQgqk51U3kicGdnvfkrxva0xXH92SjGS62B0XIJsbh+9Q==
|
||||
|
||||
copy-webpack-plugin@^8.1.1:
|
||||
version "8.1.1"
|
||||
resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-8.1.1.tgz#3f697e162764925c2f0d235f380676125508fd26"
|
||||
integrity sha512-rYM2uzRxrLRpcyPqGceRBDpxxUV8vcDqIKxAUKfcnFpcrPxT5+XvhTxv7XLjo5AvEJFPdAE3zCogG2JVahqgSQ==
|
||||
copy-webpack-plugin@^9.0.0:
|
||||
version "9.0.0"
|
||||
resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-9.0.0.tgz#2bf592785d2fcdde9342dfed3676490fe0aa7ce8"
|
||||
integrity sha512-k8UB2jLIb1Jip2nZbCz83T/XfhfjX6mB1yLJNYKrpYi7FQimfOoFv/0//iT6HV1K8FwUB5yUbCcnpLebJXJTug==
|
||||
dependencies:
|
||||
fast-glob "^3.2.5"
|
||||
glob-parent "^5.1.1"
|
||||
glob-parent "^6.0.0"
|
||||
globby "^11.0.3"
|
||||
normalize-path "^3.0.0"
|
||||
p-limit "^3.1.0"
|
||||
|
@ -6941,13 +6941,13 @@ css-loader@^5.1.1:
|
|||
schema-utils "^3.0.0"
|
||||
semver "^7.3.5"
|
||||
|
||||
css-minimizer-webpack-plugin@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-2.0.0.tgz#3c42f6624ed4cf4780dd963e23ee649e5a25c1a8"
|
||||
integrity sha512-cG/uc94727tx5pBNtb1Sd7gvUPzwmcQi1lkpfqTpdkuNq75hJCw7bIVsCNijLm4dhDcr1atvuysl2rZqOG8Txw==
|
||||
css-minimizer-webpack-plugin@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.0.1.tgz#2f866079411d42309a485512642c0cb08b5468ae"
|
||||
integrity sha512-RGFIv6iZWUPO2T1vE5+5pNCSs2H2xtHYRdfZPiiNH8Of6QOn9BeFnZSoHiQMkmsxOO/JkPe4BpKfs7slFIWcTA==
|
||||
dependencies:
|
||||
cssnano "^5.0.0"
|
||||
jest-worker "^26.3.0"
|
||||
jest-worker "^27.0.2"
|
||||
p-limit "^3.0.2"
|
||||
postcss "^8.2.9"
|
||||
schema-utils "^3.0.0"
|
||||
|
@ -8008,10 +8008,10 @@ es-abstract@^1.17.2, es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-
|
|||
string.prototype.trimstart "^1.0.4"
|
||||
unbox-primitive "^1.0.1"
|
||||
|
||||
es-module-lexer@^0.4.0:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.4.1.tgz#dda8c6a14d8f340a24e34331e0fab0cb50438e0e"
|
||||
integrity sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==
|
||||
es-module-lexer@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.6.0.tgz#e72ab05b7412e62b9be37c37a09bdb6000d706f0"
|
||||
integrity sha512-f8kcHX1ArhllUtb/wVSyvygoKCznIjnxhLxy7TCvIiMdT7fL4ZDTIKaadMe6eLvOXg6Wk02UeoFgUoZ2EKZZUA==
|
||||
|
||||
es-to-primitive@^1.2.1:
|
||||
version "1.2.1"
|
||||
|
@ -9480,13 +9480,20 @@ glob-parent@^3.1.0:
|
|||
is-glob "^3.1.0"
|
||||
path-dirname "^1.0.0"
|
||||
|
||||
glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@^5.1.1, glob-parent@^5.1.2, glob-parent@~5.1.0:
|
||||
glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@^5.1.2, glob-parent@~5.1.0:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
||||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
glob-parent@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.0.tgz#f851b59b388e788f3a44d63fab50382b2859c33c"
|
||||
integrity sha512-Hdd4287VEJcZXUwv1l8a+vXC1GjOQqXe+VS30w/ypihpcnu9M1n3xeYeJu5CBpeEQj2nAab2xxz28GuA3vp4Ww==
|
||||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
glob-to-regexp@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab"
|
||||
|
@ -10107,15 +10114,15 @@ html-void-elements@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483"
|
||||
integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==
|
||||
|
||||
html-webpack-plugin@^5.3.1:
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.3.1.tgz#8797327548e3de438e3494e0c6d06f181a7f20d1"
|
||||
integrity sha512-rZsVvPXUYFyME0cuGkyOHfx9hmkFa4pWfxY/mdY38PsBEaVNsRoA+Id+8z6DBDgyv3zaw6XQszdF8HLwfQvcdQ==
|
||||
html-webpack-plugin@^5.3.2:
|
||||
version "5.3.2"
|
||||
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.3.2.tgz#7b04bf80b1f6fe84a6d3f66c8b79d64739321b08"
|
||||
integrity sha512-HvB33boVNCz2lTyBsSiMffsJ+m0YLIQ+pskblXgN9fnjS1BgEcuAfdInfXfGrkdXV406k9FiDi86eVCDBgJOyQ==
|
||||
dependencies:
|
||||
"@types/html-minifier-terser" "^5.0.0"
|
||||
html-minifier-terser "^5.0.1"
|
||||
lodash "^4.17.20"
|
||||
pretty-error "^2.1.1"
|
||||
lodash "^4.17.21"
|
||||
pretty-error "^3.0.4"
|
||||
tapable "^2.0.0"
|
||||
|
||||
htmlparser2@^3.10.0, htmlparser2@^3.9.1:
|
||||
|
@ -11568,7 +11575,7 @@ jest-watcher@^26.6.2:
|
|||
jest-util "^26.6.2"
|
||||
string-length "^4.0.1"
|
||||
|
||||
jest-worker@^26.2.1, jest-worker@^26.3.0, jest-worker@^26.6.2:
|
||||
jest-worker@^26.2.1, jest-worker@^26.6.2:
|
||||
version "26.6.2"
|
||||
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed"
|
||||
integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==
|
||||
|
@ -15156,13 +15163,13 @@ pretty-bytes@^5.3.0:
|
|||
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
|
||||
integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==
|
||||
|
||||
pretty-error@^2.1.1:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.2.tgz#be89f82d81b1c86ec8fdfbc385045882727f93b6"
|
||||
integrity sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==
|
||||
pretty-error@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-3.0.4.tgz#94b1d54f76c1ed95b9c604b9de2194838e5b574e"
|
||||
integrity sha512-ytLFLfv1So4AO1UkoBF6GXQgJRaKbiSiGFICaOPNwQ3CMvBvXpLRubeQWyPGnsbV/t9ml9qto6IeCsho0aEvwQ==
|
||||
dependencies:
|
||||
lodash "^4.17.20"
|
||||
renderkid "^2.0.4"
|
||||
renderkid "^2.0.6"
|
||||
|
||||
pretty-format@^24.9.0:
|
||||
version "24.9.0"
|
||||
|
@ -16276,16 +16283,16 @@ remove-trailing-separator@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
|
||||
integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8=
|
||||
|
||||
renderkid@^2.0.4:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.6.tgz#aaf875a67f2d1705821a22b64515db6d9e025fd2"
|
||||
integrity sha512-GIis2GBr/ho0pFNf57D4XM4+PgnQuTii0WCPjEZmZfKivzUfGuRdjN2aQYtYMiNggHmNyBve+thFnNR1iBRcKg==
|
||||
renderkid@^2.0.6:
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.7.tgz#464f276a6bdcee606f4a15993f9b29fc74ca8609"
|
||||
integrity sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==
|
||||
dependencies:
|
||||
css-select "^4.1.3"
|
||||
dom-converter "^0.2.0"
|
||||
htmlparser2 "^6.1.0"
|
||||
lodash "^4.17.21"
|
||||
strip-ansi "^6.0.0"
|
||||
strip-ansi "^3.0.1"
|
||||
|
||||
repeat-element@^1.1.2:
|
||||
version "1.1.4"
|
||||
|
@ -17982,7 +17989,7 @@ terminal-link@^2.0.0:
|
|||
ansi-escapes "^4.2.1"
|
||||
supports-hyperlinks "^2.0.0"
|
||||
|
||||
terser-webpack-plugin@^5.1.1, terser-webpack-plugin@^5.1.2:
|
||||
terser-webpack-plugin@^5.1.3:
|
||||
version "5.1.3"
|
||||
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.1.3.tgz#30033e955ca28b55664f1e4b30a1347e61aa23af"
|
||||
integrity sha512-cxGbMqr6+A2hrIB5ehFIF+F/iST5ZOxvOmy9zih9ySbP1C2oEWQSOUS+2SNBTjzx5xLKO4xnod9eywdfq1Nb9A==
|
||||
|
@ -19218,7 +19225,7 @@ webpack-log@^2.0.0:
|
|||
ansi-colors "^3.0.0"
|
||||
uuid "^3.3.2"
|
||||
|
||||
webpack-merge@^5.7.3:
|
||||
webpack-merge@^5.7.3, webpack-merge@^5.8.0:
|
||||
version "5.8.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61"
|
||||
integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==
|
||||
|
@ -19242,10 +19249,10 @@ webpack-sources@^2.2.0, webpack-sources@^2.3.0:
|
|||
source-list-map "^2.0.1"
|
||||
source-map "^0.6.1"
|
||||
|
||||
webpack@^5.28.0, webpack@^5.37.0:
|
||||
version "5.38.1"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.38.1.tgz#5224c7f24c18e729268d3e3bc97240d6e880258e"
|
||||
integrity sha512-OqRmYD1OJbHZph6RUMD93GcCZy4Z4wC0ele4FXyYF0J6AxO1vOSuIlU1hkS/lDlR9CDYBz64MZRmdbdnFFoT2g==
|
||||
webpack@^5.40.0:
|
||||
version "5.40.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.40.0.tgz#3182cfd324759d715252cf541901a226e57b5061"
|
||||
integrity sha512-c7f5e/WWrxXWUzQqTBg54vBs5RgcAgpvKE4F4VegVgfo4x660ZxYUF2/hpMkZUnLjgytVTitjeXaN4IPlXCGIw==
|
||||
dependencies:
|
||||
"@types/eslint-scope" "^3.7.0"
|
||||
"@types/estree" "^0.0.47"
|
||||
|
@ -19256,7 +19263,7 @@ webpack@^5.28.0, webpack@^5.37.0:
|
|||
browserslist "^4.14.5"
|
||||
chrome-trace-event "^1.0.2"
|
||||
enhanced-resolve "^5.8.0"
|
||||
es-module-lexer "^0.4.0"
|
||||
es-module-lexer "^0.6.0"
|
||||
eslint-scope "5.1.1"
|
||||
events "^3.2.0"
|
||||
glob-to-regexp "^0.4.1"
|
||||
|
@ -19267,7 +19274,7 @@ webpack@^5.28.0, webpack@^5.37.0:
|
|||
neo-async "^2.6.2"
|
||||
schema-utils "^3.0.0"
|
||||
tapable "^2.1.1"
|
||||
terser-webpack-plugin "^5.1.1"
|
||||
terser-webpack-plugin "^5.1.3"
|
||||
watchpack "^2.2.0"
|
||||
webpack-sources "^2.3.0"
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue