@docusaurus/core 0.0.0-6080 → 0.0.0-6082
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/babel/preset.d.ts +2 -2
- package/lib/babel/preset.js +10 -71
- package/lib/commands/build.js +9 -9
- package/lib/commands/start/webpack.js +5 -4
- package/lib/commands/writeHeadingIds.js +1 -2
- package/lib/commands/writeTranslations.js +6 -6
- package/lib/server/site.js +7 -1
- package/lib/server/translations/translationsExtractor.d.ts +5 -11
- package/lib/server/translations/translationsExtractor.js +8 -196
- package/lib/webpack/base.js +9 -8
- package/lib/webpack/client.js +6 -6
- package/lib/webpack/configure.d.ts +1 -2
- package/lib/webpack/configure.js +4 -5
- package/lib/webpack/plugins/ForceTerminatePlugin.js +2 -2
- package/lib/webpack/plugins/StaticDirectoriesCopyPlugin.d.ts +2 -3
- package/lib/webpack/plugins/StaticDirectoriesCopyPlugin.js +4 -4
- package/lib/webpack/server.js +5 -3
- package/lib/{server/utils.d.ts → webpack/utils/getHttpsConfig.d.ts} +4 -2
- package/lib/webpack/utils/getHttpsConfig.js +60 -0
- package/package.json +12 -37
- package/lib/faster.d.ts +0 -10
- package/lib/faster.js +0 -29
- package/lib/server/utils.js +0 -20
- package/lib/webpack/currentBundler.d.ts +0 -24
- package/lib/webpack/currentBundler.js +0 -42
- package/lib/webpack/minification.d.ts +0 -12
- package/lib/webpack/minification.js +0 -106
- package/lib/webpack/utils.d.ts +0 -38
- package/lib/webpack/utils.js +0 -227
package/lib/babel/preset.d.ts
CHANGED
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
import
|
|
8
|
-
export default
|
|
7
|
+
import BabelPreset from '@docusaurus/babel/preset';
|
|
8
|
+
export default BabelPreset;
|
package/lib/babel/preset.js
CHANGED
|
@@ -6,75 +6,14 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.default = babelPresets;
|
|
10
9
|
const tslib_1 = require("tslib");
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
require.resolve('@babel/preset-env'),
|
|
22
|
-
{
|
|
23
|
-
targets: {
|
|
24
|
-
node: 'current',
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
]
|
|
28
|
-
: [
|
|
29
|
-
require.resolve('@babel/preset-env'),
|
|
30
|
-
{
|
|
31
|
-
useBuiltIns: 'entry',
|
|
32
|
-
loose: true,
|
|
33
|
-
corejs: '3',
|
|
34
|
-
// Do not transform modules to CJS
|
|
35
|
-
modules: false,
|
|
36
|
-
// Exclude transforms that make all code slower
|
|
37
|
-
exclude: ['transform-typeof-symbol'],
|
|
38
|
-
},
|
|
39
|
-
],
|
|
40
|
-
[
|
|
41
|
-
require.resolve('@babel/preset-react'),
|
|
42
|
-
{
|
|
43
|
-
runtime: 'automatic',
|
|
44
|
-
},
|
|
45
|
-
],
|
|
46
|
-
require.resolve('@babel/preset-typescript'),
|
|
47
|
-
],
|
|
48
|
-
plugins: [
|
|
49
|
-
// Polyfills the runtime needed for async/await, generators, and friends
|
|
50
|
-
// https://babeljs.io/docs/en/babel-plugin-transform-runtime
|
|
51
|
-
[
|
|
52
|
-
require.resolve('@babel/plugin-transform-runtime'),
|
|
53
|
-
{
|
|
54
|
-
corejs: false,
|
|
55
|
-
helpers: true,
|
|
56
|
-
// By default, it assumes @babel/runtime@7.0.0. Since we use >7.0.0,
|
|
57
|
-
// better to explicitly specify the version so that it can reuse the
|
|
58
|
-
// helper better. See https://github.com/babel/babel/issues/10261
|
|
59
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires, global-require
|
|
60
|
-
version: require('@babel/runtime/package.json')
|
|
61
|
-
.version,
|
|
62
|
-
regenerator: true,
|
|
63
|
-
useESModules: true,
|
|
64
|
-
// Undocumented option that lets us encapsulate our runtime, ensuring
|
|
65
|
-
// the correct version is used
|
|
66
|
-
// https://github.com/babel/babel/blob/090c364a90fe73d36a30707fc612ce037bdbbb24/packages/babel-plugin-transform-runtime/src/index.js#L35-L42
|
|
67
|
-
absoluteRuntime: absoluteRuntimePath,
|
|
68
|
-
},
|
|
69
|
-
],
|
|
70
|
-
// Adds syntax support for import()
|
|
71
|
-
isServer
|
|
72
|
-
? require.resolve('babel-plugin-dynamic-import-node')
|
|
73
|
-
: require.resolve('@babel/plugin-syntax-dynamic-import'),
|
|
74
|
-
],
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
function babelPresets(api) {
|
|
78
|
-
const callerName = api.caller((caller) => caller?.name);
|
|
79
|
-
return getTransformOptions(callerName === 'server');
|
|
80
|
-
}
|
|
10
|
+
// TODO Docusaurus v4, do breaking change and expose babel preset cleanly
|
|
11
|
+
/*
|
|
12
|
+
this just ensure retro-compatibility with our former init template .babelrc.js:
|
|
13
|
+
|
|
14
|
+
module.exports = {
|
|
15
|
+
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
|
|
16
|
+
};
|
|
17
|
+
*/
|
|
18
|
+
const preset_1 = tslib_1.__importDefault(require("@docusaurus/babel/preset"));
|
|
19
|
+
exports.default = preset_1.default;
|
package/lib/commands/build.js
CHANGED
|
@@ -11,6 +11,7 @@ const tslib_1 = require("tslib");
|
|
|
11
11
|
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
12
12
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
13
13
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
14
|
+
const bundler_1 = require("@docusaurus/bundler");
|
|
14
15
|
const logger_1 = tslib_1.__importStar(require("@docusaurus/logger"));
|
|
15
16
|
const utils_1 = require("@docusaurus/utils");
|
|
16
17
|
const site_1 = require("../server/site");
|
|
@@ -18,7 +19,6 @@ const brokenLinks_1 = require("../server/brokenLinks");
|
|
|
18
19
|
const client_1 = require("../webpack/client");
|
|
19
20
|
const server_1 = tslib_1.__importDefault(require("../webpack/server"));
|
|
20
21
|
const configure_1 = require("../webpack/configure");
|
|
21
|
-
const utils_2 = require("../webpack/utils");
|
|
22
22
|
const i18n_1 = require("../server/i18n");
|
|
23
23
|
const ssg_1 = require("../ssg");
|
|
24
24
|
const templates_1 = require("../templates/templates");
|
|
@@ -101,7 +101,7 @@ async function buildLocale({ siteDir, locale, cliOptions, }) {
|
|
|
101
101
|
const router = siteConfig.future.experimental_router;
|
|
102
102
|
const configureWebpackUtils = await (0, configure_1.createConfigureWebpackUtils)({ siteConfig });
|
|
103
103
|
// We can build the 2 configs in parallel
|
|
104
|
-
const [{ clientConfig, clientManifestPath }, { serverConfig, serverBundlePath }] = await logger_1.PerfLogger.async('Creating
|
|
104
|
+
const [{ clientConfig, clientManifestPath }, { serverConfig, serverBundlePath }] = await logger_1.PerfLogger.async('Creating bundler configs', () => Promise.all([
|
|
105
105
|
getBuildClientConfig({
|
|
106
106
|
props,
|
|
107
107
|
cliOptions,
|
|
@@ -113,13 +113,13 @@ async function buildLocale({ siteDir, locale, cliOptions, }) {
|
|
|
113
113
|
}),
|
|
114
114
|
]));
|
|
115
115
|
// Run webpack to build JS bundle (client) and static html files (server).
|
|
116
|
-
await logger_1.PerfLogger.async(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
116
|
+
await logger_1.PerfLogger.async(`Bundling with ${configureWebpackUtils.currentBundler.name}`, () => {
|
|
117
|
+
return (0, bundler_1.compile)({
|
|
118
|
+
configs:
|
|
119
|
+
// For hash router we don't do SSG and can skip the server bundle
|
|
120
|
+
router === 'hash' ? [clientConfig] : [clientConfig, serverConfig],
|
|
121
|
+
currentBundler: configureWebpackUtils.currentBundler,
|
|
122
|
+
});
|
|
123
123
|
});
|
|
124
124
|
const { collectedData } = await logger_1.PerfLogger.async('SSG', () => executeSSG({
|
|
125
125
|
props,
|
|
@@ -11,11 +11,12 @@ const tslib_1 = require("tslib");
|
|
|
11
11
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
12
12
|
const webpack_merge_1 = tslib_1.__importDefault(require("webpack-merge"));
|
|
13
13
|
const webpack_1 = tslib_1.__importDefault(require("webpack"));
|
|
14
|
+
const bundler_1 = require("@docusaurus/bundler");
|
|
14
15
|
const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
|
|
15
16
|
const webpack_dev_server_1 = tslib_1.__importDefault(require("webpack-dev-server"));
|
|
16
17
|
const evalSourceMapMiddleware_1 = tslib_1.__importDefault(require("react-dev-utils/evalSourceMapMiddleware"));
|
|
17
18
|
const watcher_1 = require("./watcher");
|
|
18
|
-
const
|
|
19
|
+
const getHttpsConfig_1 = tslib_1.__importDefault(require("../../webpack/utils/getHttpsConfig"));
|
|
19
20
|
const configure_1 = require("../../webpack/configure");
|
|
20
21
|
const client_1 = require("../../webpack/client");
|
|
21
22
|
// E2E_TEST=true docusaurus start
|
|
@@ -23,11 +24,11 @@ const client_1 = require("../../webpack/client");
|
|
|
23
24
|
function registerWebpackE2ETestHook(compiler) {
|
|
24
25
|
compiler.hooks.done.tap('done', (stats) => {
|
|
25
26
|
const errorsWarnings = stats.toJson('errors-warnings');
|
|
26
|
-
const statsErrorMessage = (0,
|
|
27
|
+
const statsErrorMessage = (0, bundler_1.formatStatsErrorMessage)(errorsWarnings);
|
|
27
28
|
if (statsErrorMessage) {
|
|
28
29
|
console.error(statsErrorMessage);
|
|
29
30
|
}
|
|
30
|
-
(0,
|
|
31
|
+
(0, bundler_1.printStatsWarnings)(errorsWarnings);
|
|
31
32
|
if (process.env.E2E_TEST) {
|
|
32
33
|
if (stats.hasErrors()) {
|
|
33
34
|
logger_1.default.error('E2E_TEST: Project has compiler errors.');
|
|
@@ -41,7 +42,7 @@ function registerWebpackE2ETestHook(compiler) {
|
|
|
41
42
|
async function createDevServerConfig({ cliOptions, props, host, port, }) {
|
|
42
43
|
const { baseUrl, siteDir, siteConfig } = props;
|
|
43
44
|
const pollingOptions = (0, watcher_1.createPollingOptions)(cliOptions);
|
|
44
|
-
const httpsConfig = await (0,
|
|
45
|
+
const httpsConfig = await (0, getHttpsConfig_1.default)();
|
|
45
46
|
// https://webpack.js.org/configuration/dev-server
|
|
46
47
|
return {
|
|
47
48
|
hot: cliOptions.hotOnly ? 'only' : true,
|
|
@@ -13,7 +13,6 @@ const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
|
|
|
13
13
|
const utils_1 = require("@docusaurus/utils");
|
|
14
14
|
const site_1 = require("../server/site");
|
|
15
15
|
const init_1 = require("../server/plugins/init");
|
|
16
|
-
const utils_2 = require("../server/utils");
|
|
17
16
|
async function transformMarkdownFile(filepath, options) {
|
|
18
17
|
const content = await fs_extra_1.default.readFile(filepath, 'utf8');
|
|
19
18
|
const updatedContent = (0, utils_1.writeMarkdownHeadingId)(content, options);
|
|
@@ -36,7 +35,7 @@ async function getPathsToWatch(siteDir) {
|
|
|
36
35
|
}
|
|
37
36
|
async function writeHeadingIds(siteDirParam = '.', files = [], options = {}) {
|
|
38
37
|
const siteDir = await fs_extra_1.default.realpath(siteDirParam);
|
|
39
|
-
const markdownFiles = await (0,
|
|
38
|
+
const markdownFiles = await (0, utils_1.safeGlobby)(files ?? (await getPathsToWatch(siteDir)), {
|
|
40
39
|
expandDirectories: ['**/*.{md,mdx}'],
|
|
41
40
|
});
|
|
42
41
|
const result = await Promise.all(markdownFiles.map((p) => transformMarkdownFile(p, options)));
|
|
@@ -10,11 +10,11 @@ exports.writeTranslations = writeTranslations;
|
|
|
10
10
|
const tslib_1 = require("tslib");
|
|
11
11
|
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
12
12
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
13
|
+
const utils_1 = require("@docusaurus/utils");
|
|
13
14
|
const site_1 = require("../server/site");
|
|
14
15
|
const init_1 = require("../server/plugins/init");
|
|
15
16
|
const translations_1 = require("../server/translations/translations");
|
|
16
17
|
const translationsExtractor_1 = require("../server/translations/translationsExtractor");
|
|
17
|
-
const utils_1 = require("../webpack/utils");
|
|
18
18
|
function resolveThemeCommonLibDir() {
|
|
19
19
|
try {
|
|
20
20
|
return path_1.default.dirname(require.resolve('@docusaurus/theme-common'));
|
|
@@ -35,7 +35,7 @@ async function getExtraSourceCodeFilePaths() {
|
|
|
35
35
|
if (!themeCommonLibDir) {
|
|
36
36
|
return []; // User may not use a Docusaurus official theme? Quite unlikely...
|
|
37
37
|
}
|
|
38
|
-
return (0,
|
|
38
|
+
return (0, utils_1.globTranslatableSourceFiles)([themeCommonLibDir]);
|
|
39
39
|
}
|
|
40
40
|
async function writePluginTranslationFiles({ localizationDir, plugin, options, }) {
|
|
41
41
|
if (plugin.getTranslationFiles) {
|
|
@@ -67,11 +67,11 @@ async function writeTranslations(siteDirParam = '.', options = {}) {
|
|
|
67
67
|
throw new Error(`Can't write-translation for locale "${locale}" that is not in the locale configuration file.
|
|
68
68
|
Available locales are: ${context.i18n.locales.join(',')}.`);
|
|
69
69
|
}
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
const extractedCodeTranslations = await (0, translationsExtractor_1.extractSiteSourceCodeTranslations)({
|
|
71
|
+
siteDir,
|
|
72
|
+
plugins,
|
|
73
|
+
extraSourceCodeFilePaths: await getExtraSourceCodeFilePaths(),
|
|
73
74
|
});
|
|
74
|
-
const extractedCodeTranslations = await (0, translationsExtractor_1.extractSiteSourceCodeTranslations)(siteDir, plugins, babelOptions, await getExtraSourceCodeFilePaths());
|
|
75
75
|
const defaultCodeMessages = await (0, translations_1.loadPluginsDefaultCodeTranslationMessages)(plugins);
|
|
76
76
|
const codeTranslations = (0, translations_1.applyDefaultCodeTranslations)({
|
|
77
77
|
extractedCodeTranslations,
|
package/lib/server/site.js
CHANGED
|
@@ -15,6 +15,7 @@ const path_1 = tslib_1.__importDefault(require("path"));
|
|
|
15
15
|
const utils_1 = require("@docusaurus/utils");
|
|
16
16
|
const logger_1 = require("@docusaurus/logger");
|
|
17
17
|
const combine_promises_1 = tslib_1.__importDefault(require("combine-promises"));
|
|
18
|
+
const bundler_1 = require("@docusaurus/bundler");
|
|
18
19
|
const config_1 = require("./config");
|
|
19
20
|
const clientModules_1 = require("./clientModules");
|
|
20
21
|
const plugins_1 = require("./plugins/plugins");
|
|
@@ -41,6 +42,9 @@ async function loadContext(params) {
|
|
|
41
42
|
customConfigFilePath,
|
|
42
43
|
}),
|
|
43
44
|
});
|
|
45
|
+
const currentBundler = await (0, bundler_1.getCurrentBundler)({
|
|
46
|
+
siteConfig: initialSiteConfig,
|
|
47
|
+
});
|
|
44
48
|
const i18n = await (0, i18n_1.loadI18n)(initialSiteConfig, { locale });
|
|
45
49
|
const baseUrl = (0, utils_1.localizePath)({
|
|
46
50
|
path: initialSiteConfig.baseUrl,
|
|
@@ -70,11 +74,12 @@ async function loadContext(params) {
|
|
|
70
74
|
baseUrl,
|
|
71
75
|
i18n,
|
|
72
76
|
codeTranslations,
|
|
77
|
+
currentBundler,
|
|
73
78
|
};
|
|
74
79
|
}
|
|
75
80
|
function createSiteProps(params) {
|
|
76
81
|
const { plugins, routes, context } = params;
|
|
77
|
-
const { generatedFilesDir, siteDir, siteVersion, siteConfig, siteConfigPath, siteStorage, outDir, baseUrl, i18n, localizationDir, codeTranslations: siteCodeTranslations, } = context;
|
|
82
|
+
const { generatedFilesDir, siteDir, siteVersion, siteConfig, siteConfigPath, siteStorage, outDir, baseUrl, i18n, localizationDir, codeTranslations: siteCodeTranslations, currentBundler, } = context;
|
|
78
83
|
const { headTags, preBodyTags, postBodyTags } = (0, htmlTags_1.loadHtmlTags)({
|
|
79
84
|
plugins,
|
|
80
85
|
router: siteConfig.future.experimental_router,
|
|
@@ -105,6 +110,7 @@ function createSiteProps(params) {
|
|
|
105
110
|
preBodyTags,
|
|
106
111
|
postBodyTags,
|
|
107
112
|
codeTranslations,
|
|
113
|
+
currentBundler,
|
|
108
114
|
};
|
|
109
115
|
}
|
|
110
116
|
// TODO global data should be part of site props?
|
|
@@ -4,15 +4,9 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
import { type TransformOptions } from '@babel/core';
|
|
8
7
|
import type { InitializedPlugin, TranslationFileContent } from '@docusaurus/types';
|
|
9
|
-
export declare function
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
warnings: string[];
|
|
15
|
-
};
|
|
16
|
-
export declare function extractAllSourceCodeFileTranslations(sourceCodeFilePaths: string[], babelOptions: TransformOptions): Promise<SourceCodeFileTranslations[]>;
|
|
17
|
-
export declare function extractSourceCodeFileTranslations(sourceCodeFilePath: string, babelOptions: TransformOptions): Promise<SourceCodeFileTranslations>;
|
|
18
|
-
export {};
|
|
8
|
+
export declare function extractSiteSourceCodeTranslations({ siteDir, plugins, extraSourceCodeFilePaths, }: {
|
|
9
|
+
siteDir: string;
|
|
10
|
+
plugins: InitializedPlugin[];
|
|
11
|
+
extraSourceCodeFilePaths?: string[];
|
|
12
|
+
}): Promise<TranslationFileContent>;
|
|
@@ -6,33 +6,12 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.globSourceCodeFilePaths = globSourceCodeFilePaths;
|
|
10
9
|
exports.extractSiteSourceCodeTranslations = extractSiteSourceCodeTranslations;
|
|
11
|
-
exports.extractAllSourceCodeFileTranslations = extractAllSourceCodeFileTranslations;
|
|
12
|
-
exports.extractSourceCodeFileTranslations = extractSourceCodeFileTranslations;
|
|
13
10
|
const tslib_1 = require("tslib");
|
|
14
11
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
15
|
-
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
16
12
|
const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
|
|
17
|
-
const traverse_1 = tslib_1.__importDefault(require("@babel/traverse"));
|
|
18
|
-
const generator_1 = tslib_1.__importDefault(require("@babel/generator"));
|
|
19
|
-
const core_1 = require("@babel/core");
|
|
20
13
|
const utils_1 = require("@docusaurus/utils");
|
|
21
|
-
const
|
|
22
|
-
// We only support extracting source code translations from these kind of files
|
|
23
|
-
const TranslatableSourceCodeExtension = new Set([
|
|
24
|
-
'.js',
|
|
25
|
-
'.jsx',
|
|
26
|
-
'.ts',
|
|
27
|
-
'.tsx',
|
|
28
|
-
// TODO support md/mdx too? (may be overkill)
|
|
29
|
-
// need to compile the MDX to JSX first and remove front matter
|
|
30
|
-
// '.md',
|
|
31
|
-
// '.mdx',
|
|
32
|
-
]);
|
|
33
|
-
function isTranslatableSourceCodePath(filePath) {
|
|
34
|
-
return TranslatableSourceCodeExtension.has(path_1.default.extname(filePath));
|
|
35
|
-
}
|
|
14
|
+
const babel_1 = require("@docusaurus/babel");
|
|
36
15
|
function getSiteSourceCodeFilePaths(siteDir) {
|
|
37
16
|
return [path_1.default.join(siteDir, utils_1.SRC_DIR_NAME)];
|
|
38
17
|
}
|
|
@@ -49,10 +28,6 @@ function getPluginSourceCodeFilePaths(plugin) {
|
|
|
49
28
|
}
|
|
50
29
|
return codePaths.map((p) => path_1.default.resolve(plugin.path, p));
|
|
51
30
|
}
|
|
52
|
-
async function globSourceCodeFilePaths(dirPaths) {
|
|
53
|
-
const filePaths = await (0, utils_2.safeGlobby)(dirPaths);
|
|
54
|
-
return filePaths.filter(isTranslatableSourceCodePath);
|
|
55
|
-
}
|
|
56
31
|
async function getSourceCodeFilePaths(siteDir, plugins) {
|
|
57
32
|
const sitePaths = getSiteSourceCodeFilePaths(siteDir);
|
|
58
33
|
// The getPathsToWatch() generally returns the js/jsx/ts/tsx/md/mdx file paths
|
|
@@ -61,9 +36,13 @@ async function getSourceCodeFilePaths(siteDir, plugins) {
|
|
|
61
36
|
// new lifecycle method for that???
|
|
62
37
|
const pluginsPaths = plugins.flatMap(getPluginSourceCodeFilePaths);
|
|
63
38
|
const allPaths = [...sitePaths, ...pluginsPaths];
|
|
64
|
-
return
|
|
39
|
+
return (0, utils_1.globTranslatableSourceFiles)(allPaths);
|
|
65
40
|
}
|
|
66
|
-
async function extractSiteSourceCodeTranslations(siteDir, plugins,
|
|
41
|
+
async function extractSiteSourceCodeTranslations({ siteDir, plugins, extraSourceCodeFilePaths = [], }) {
|
|
42
|
+
const babelOptions = (0, babel_1.getBabelOptions)({
|
|
43
|
+
isServer: true,
|
|
44
|
+
babelOptions: await (0, babel_1.getCustomBabelConfigFilePath)(siteDir),
|
|
45
|
+
});
|
|
67
46
|
// Should we warn here if the same translation "key" is found in multiple
|
|
68
47
|
// source code files?
|
|
69
48
|
function toTranslationFileContent(sourceCodeFileTranslations) {
|
|
@@ -74,7 +53,7 @@ async function extractSiteSourceCodeTranslations(siteDir, plugins, babelOptions,
|
|
|
74
53
|
...sourceCodeFilePaths,
|
|
75
54
|
...extraSourceCodeFilePaths,
|
|
76
55
|
];
|
|
77
|
-
const sourceCodeFilesTranslations = await extractAllSourceCodeFileTranslations(allSourceCodeFilePaths, babelOptions);
|
|
56
|
+
const sourceCodeFilesTranslations = await (0, babel_1.extractAllSourceCodeFileTranslations)(allSourceCodeFilePaths, babelOptions);
|
|
78
57
|
logSourceCodeFileTranslationsWarnings(sourceCodeFilesTranslations);
|
|
79
58
|
return toTranslationFileContent(sourceCodeFilesTranslations);
|
|
80
59
|
}
|
|
@@ -85,170 +64,3 @@ function logSourceCodeFileTranslationsWarnings(sourceCodeFilesTranslations) {
|
|
|
85
64
|
}
|
|
86
65
|
});
|
|
87
66
|
}
|
|
88
|
-
async function extractAllSourceCodeFileTranslations(sourceCodeFilePaths, babelOptions) {
|
|
89
|
-
return Promise.all(sourceCodeFilePaths.flatMap((sourceFilePath) => extractSourceCodeFileTranslations(sourceFilePath, babelOptions)));
|
|
90
|
-
}
|
|
91
|
-
async function extractSourceCodeFileTranslations(sourceCodeFilePath, babelOptions) {
|
|
92
|
-
try {
|
|
93
|
-
const code = await fs_extra_1.default.readFile(sourceCodeFilePath, 'utf8');
|
|
94
|
-
const ast = (0, core_1.parse)(code, {
|
|
95
|
-
...babelOptions,
|
|
96
|
-
ast: true,
|
|
97
|
-
// filename is important, because babel does not process the same files
|
|
98
|
-
// according to their js/ts extensions.
|
|
99
|
-
// See https://x.com/NicoloRibaudo/status/1321130735605002243
|
|
100
|
-
filename: sourceCodeFilePath,
|
|
101
|
-
});
|
|
102
|
-
const translations = extractSourceCodeAstTranslations(ast, sourceCodeFilePath);
|
|
103
|
-
return translations;
|
|
104
|
-
}
|
|
105
|
-
catch (err) {
|
|
106
|
-
logger_1.default.error `Error while attempting to extract Docusaurus translations from source code file at path=${sourceCodeFilePath}.`;
|
|
107
|
-
throw err;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
/*
|
|
111
|
-
Need help understanding this?
|
|
112
|
-
|
|
113
|
-
Useful resources:
|
|
114
|
-
https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md
|
|
115
|
-
https://github.com/formatjs/formatjs/blob/main/packages/babel-plugin-formatjs/index.ts
|
|
116
|
-
https://github.com/pugjs/babel-walk
|
|
117
|
-
*/
|
|
118
|
-
function extractSourceCodeAstTranslations(ast, sourceCodeFilePath) {
|
|
119
|
-
function sourceWarningPart(node) {
|
|
120
|
-
return `File: ${sourceCodeFilePath} at line ${node.loc?.start.line ?? '?'}
|
|
121
|
-
Full code: ${(0, generator_1.default)(node).code}`;
|
|
122
|
-
}
|
|
123
|
-
const translations = {};
|
|
124
|
-
const warnings = [];
|
|
125
|
-
let translateComponentName;
|
|
126
|
-
let translateFunctionName;
|
|
127
|
-
// First pass: find import declarations of Translate / translate.
|
|
128
|
-
// If not found, don't process the rest to avoid false positives
|
|
129
|
-
(0, traverse_1.default)(ast, {
|
|
130
|
-
ImportDeclaration(path) {
|
|
131
|
-
if (path.node.importKind === 'type' ||
|
|
132
|
-
path.get('source').node.value !== '@docusaurus/Translate') {
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
const importSpecifiers = path.get('specifiers');
|
|
136
|
-
const defaultImport = importSpecifiers.find((specifier) => specifier.node.type === 'ImportDefaultSpecifier');
|
|
137
|
-
const callbackImport = importSpecifiers.find((specifier) => specifier.node.type === 'ImportSpecifier' &&
|
|
138
|
-
(specifier.get('imported')
|
|
139
|
-
.node.name === 'translate' ||
|
|
140
|
-
specifier.get('imported')
|
|
141
|
-
.node.value === 'translate'));
|
|
142
|
-
translateComponentName = defaultImport?.get('local').node.name;
|
|
143
|
-
translateFunctionName = callbackImport?.get('local').node.name;
|
|
144
|
-
},
|
|
145
|
-
});
|
|
146
|
-
(0, traverse_1.default)(ast, {
|
|
147
|
-
...(translateComponentName && {
|
|
148
|
-
JSXElement(path) {
|
|
149
|
-
if (!path
|
|
150
|
-
.get('openingElement')
|
|
151
|
-
.get('name')
|
|
152
|
-
.isJSXIdentifier({ name: translateComponentName })) {
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
function evaluateJSXProp(propName) {
|
|
156
|
-
const attributePath = path
|
|
157
|
-
.get('openingElement.attributes')
|
|
158
|
-
.find((attr) => attr.isJSXAttribute() &&
|
|
159
|
-
attr.get('name').isJSXIdentifier({ name: propName }));
|
|
160
|
-
if (attributePath) {
|
|
161
|
-
const attributeValue = attributePath.get('value');
|
|
162
|
-
const attributeValueEvaluated = attributeValue.isJSXExpressionContainer()
|
|
163
|
-
? attributeValue.get('expression').evaluate()
|
|
164
|
-
: attributeValue.evaluate();
|
|
165
|
-
if (attributeValueEvaluated.confident &&
|
|
166
|
-
typeof attributeValueEvaluated.value === 'string') {
|
|
167
|
-
return attributeValueEvaluated.value;
|
|
168
|
-
}
|
|
169
|
-
warnings.push(`<Translate> prop=${propName} should be a statically evaluable object.
|
|
170
|
-
Example: <Translate id="optional id" description="optional description">Message</Translate>
|
|
171
|
-
Dynamically constructed values are not allowed, because they prevent translations to be extracted.
|
|
172
|
-
${sourceWarningPart(path.node)}`);
|
|
173
|
-
}
|
|
174
|
-
return undefined;
|
|
175
|
-
}
|
|
176
|
-
const id = evaluateJSXProp('id');
|
|
177
|
-
const description = evaluateJSXProp('description');
|
|
178
|
-
let message;
|
|
179
|
-
const childrenPath = path.get('children');
|
|
180
|
-
// Handle empty content
|
|
181
|
-
if (!childrenPath.length) {
|
|
182
|
-
if (!id) {
|
|
183
|
-
warnings.push(`<Translate> without children must have id prop.
|
|
184
|
-
Example: <Translate id="my-id" />
|
|
185
|
-
${sourceWarningPart(path.node)}`);
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
translations[id] = {
|
|
189
|
-
message: id,
|
|
190
|
-
...(description && { description }),
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
// Handle single non-empty content
|
|
196
|
-
const singleChildren = childrenPath
|
|
197
|
-
// Remove empty/useless text nodes that might be around our
|
|
198
|
-
// translation! Makes the translation system more reliable to JSX
|
|
199
|
-
// formatting issues
|
|
200
|
-
.filter((children) => !(children.isJSXText() &&
|
|
201
|
-
children.node.value.replace('\n', '').trim() === ''))
|
|
202
|
-
.pop();
|
|
203
|
-
const isJSXText = singleChildren?.isJSXText();
|
|
204
|
-
const isJSXExpressionContainer = singleChildren?.isJSXExpressionContainer() &&
|
|
205
|
-
singleChildren.get('expression').evaluate().confident;
|
|
206
|
-
if (isJSXText || isJSXExpressionContainer) {
|
|
207
|
-
message = isJSXText
|
|
208
|
-
? singleChildren.node.value.trim().replace(/\s+/g, ' ')
|
|
209
|
-
: String(singleChildren.get('expression').evaluate().value);
|
|
210
|
-
translations[id ?? message] = {
|
|
211
|
-
message,
|
|
212
|
-
...(description && { description }),
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
else {
|
|
216
|
-
warnings.push(`Translate content could not be extracted. It has to be a static string and use optional but static props, like <Translate id="my-id" description="my-description">text</Translate>.
|
|
217
|
-
${sourceWarningPart(path.node)}`);
|
|
218
|
-
}
|
|
219
|
-
},
|
|
220
|
-
}),
|
|
221
|
-
...(translateFunctionName && {
|
|
222
|
-
CallExpression(path) {
|
|
223
|
-
if (!path.get('callee').isIdentifier({ name: translateFunctionName })) {
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
const args = path.get('arguments');
|
|
227
|
-
if (args.length === 1 || args.length === 2) {
|
|
228
|
-
const firstArgPath = args[0];
|
|
229
|
-
// translate("x" + "y"); => translate("xy");
|
|
230
|
-
const firstArgEvaluated = firstArgPath.evaluate();
|
|
231
|
-
if (firstArgEvaluated.confident &&
|
|
232
|
-
typeof firstArgEvaluated.value === 'object') {
|
|
233
|
-
const { message, id, description } = firstArgEvaluated.value;
|
|
234
|
-
translations[String(id ?? message)] = {
|
|
235
|
-
message: String(message ?? id),
|
|
236
|
-
...(Boolean(description) && { description: String(description) }),
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
else {
|
|
240
|
-
warnings.push(`translate() first arg should be a statically evaluable object.
|
|
241
|
-
Example: translate({message: "text",id: "optional.id",description: "optional description"}
|
|
242
|
-
Dynamically constructed values are not allowed, because they prevent translations to be extracted.
|
|
243
|
-
${sourceWarningPart(path.node)}`);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
else {
|
|
247
|
-
warnings.push(`translate() function only takes 1 or 2 args
|
|
248
|
-
${sourceWarningPart(path.node)}`);
|
|
249
|
-
}
|
|
250
|
-
},
|
|
251
|
-
}),
|
|
252
|
-
});
|
|
253
|
-
return { sourceCodeFilePath, translations, warnings };
|
|
254
|
-
}
|
package/lib/webpack/base.js
CHANGED
|
@@ -12,11 +12,10 @@ exports.createBaseConfig = createBaseConfig;
|
|
|
12
12
|
const tslib_1 = require("tslib");
|
|
13
13
|
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
14
14
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
15
|
+
const babel_1 = require("@docusaurus/babel");
|
|
16
|
+
const bundler_1 = require("@docusaurus/bundler");
|
|
15
17
|
const utils_1 = require("@docusaurus/utils");
|
|
16
|
-
const utils_2 = require("./utils");
|
|
17
|
-
const minification_1 = require("./minification");
|
|
18
18
|
const aliases_1 = require("./aliases");
|
|
19
|
-
const currentBundler_1 = require("./currentBundler");
|
|
20
19
|
const CSS_REGEX = /\.css$/i;
|
|
21
20
|
const CSS_MODULE_REGEX = /\.module\.css$/i;
|
|
22
21
|
exports.clientDir = path_1.default.join(__dirname, '..', 'client');
|
|
@@ -51,9 +50,9 @@ async function createBaseConfig({ props, isServer, minify, faster, configureWebp
|
|
|
51
50
|
const name = isServer ? 'server' : 'client';
|
|
52
51
|
const mode = isProd ? 'production' : 'development';
|
|
53
52
|
const themeAliases = await (0, aliases_1.loadThemeAliases)({ siteDir, plugins });
|
|
54
|
-
const createJsLoader = await (0,
|
|
55
|
-
const CSSExtractPlugin = await (0,
|
|
56
|
-
currentBundler:
|
|
53
|
+
const createJsLoader = await (0, bundler_1.createJsLoaderFactory)({ siteConfig });
|
|
54
|
+
const CSSExtractPlugin = await (0, bundler_1.getCSSExtractPlugin)({
|
|
55
|
+
currentBundler: props.currentBundler,
|
|
57
56
|
});
|
|
58
57
|
return {
|
|
59
58
|
mode,
|
|
@@ -138,7 +137,9 @@ async function createBaseConfig({ props, isServer, minify, faster, configureWebp
|
|
|
138
137
|
// Only minimize client bundle in production because server bundle is only
|
|
139
138
|
// used for static site generation
|
|
140
139
|
minimize: minimizeEnabled,
|
|
141
|
-
minimizer: minimizeEnabled
|
|
140
|
+
minimizer: minimizeEnabled
|
|
141
|
+
? await (0, bundler_1.getMinimizers)({ faster, currentBundler: props.currentBundler })
|
|
142
|
+
: undefined,
|
|
142
143
|
splitChunks: isServer
|
|
143
144
|
? false
|
|
144
145
|
: {
|
|
@@ -181,7 +182,7 @@ async function createBaseConfig({ props, isServer, minify, faster, configureWebp
|
|
|
181
182
|
use: [
|
|
182
183
|
createJsLoader({
|
|
183
184
|
isServer,
|
|
184
|
-
babelOptions: await (0,
|
|
185
|
+
babelOptions: await (0, babel_1.getCustomBabelConfigFilePath)(siteDir),
|
|
185
186
|
}),
|
|
186
187
|
],
|
|
187
188
|
},
|
package/lib/webpack/client.js
CHANGED
|
@@ -11,11 +11,10 @@ exports.createBuildClientConfig = createBuildClientConfig;
|
|
|
11
11
|
const tslib_1 = require("tslib");
|
|
12
12
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
13
13
|
const webpack_merge_1 = tslib_1.__importDefault(require("webpack-merge"));
|
|
14
|
-
const webpackbar_1 = tslib_1.__importDefault(require("webpackbar"));
|
|
15
|
-
const webpack_1 = tslib_1.__importDefault(require("webpack"));
|
|
16
14
|
const webpack_bundle_analyzer_1 = require("webpack-bundle-analyzer");
|
|
17
15
|
const react_loadable_ssr_addon_v5_slorber_1 = tslib_1.__importDefault(require("react-loadable-ssr-addon-v5-slorber"));
|
|
18
16
|
const html_webpack_plugin_1 = tslib_1.__importDefault(require("html-webpack-plugin"));
|
|
17
|
+
const bundler_1 = require("@docusaurus/bundler");
|
|
19
18
|
const base_1 = require("./base");
|
|
20
19
|
const ChunkAssetPlugin_1 = tslib_1.__importDefault(require("./plugins/ChunkAssetPlugin"));
|
|
21
20
|
const CleanWebpackPlugin_1 = tslib_1.__importDefault(require("./plugins/CleanWebpackPlugin"));
|
|
@@ -29,6 +28,9 @@ async function createBaseClientConfig({ props, hydrate, minify, faster, configur
|
|
|
29
28
|
faster,
|
|
30
29
|
configureWebpackUtils,
|
|
31
30
|
});
|
|
31
|
+
const ProgressBarPlugin = await (0, bundler_1.getProgressBarPlugin)({
|
|
32
|
+
currentBundler: configureWebpackUtils.currentBundler,
|
|
33
|
+
});
|
|
32
34
|
return (0, webpack_merge_1.default)(baseConfig, {
|
|
33
35
|
// Useless, disabled on purpose (errors on existing sites with no
|
|
34
36
|
// browserslist config)
|
|
@@ -40,17 +42,15 @@ async function createBaseClientConfig({ props, hydrate, minify, faster, configur
|
|
|
40
42
|
runtimeChunk: true,
|
|
41
43
|
},
|
|
42
44
|
plugins: [
|
|
43
|
-
new
|
|
45
|
+
new props.currentBundler.instance.DefinePlugin({
|
|
44
46
|
'process.env.HYDRATE_CLIENT_ENTRY': JSON.stringify(hydrate),
|
|
45
47
|
}),
|
|
46
48
|
new ChunkAssetPlugin_1.default(),
|
|
47
|
-
|
|
48
|
-
new webpackbar_1.default({
|
|
49
|
+
new ProgressBarPlugin({
|
|
49
50
|
name: 'Client',
|
|
50
51
|
}),
|
|
51
52
|
await (0, StaticDirectoriesCopyPlugin_1.createStaticDirectoriesCopyPlugin)({
|
|
52
53
|
props,
|
|
53
|
-
currentBundler: configureWebpackUtils.currentBundler,
|
|
54
54
|
}),
|
|
55
55
|
].filter(Boolean),
|
|
56
56
|
});
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
import { createJsLoaderFactory } from '
|
|
8
|
-
import { getCurrentBundler } from './currentBundler';
|
|
7
|
+
import { getCurrentBundler, createJsLoaderFactory } from '@docusaurus/bundler';
|
|
9
8
|
import type { Configuration } from 'webpack';
|
|
10
9
|
import type { Plugin, ConfigureWebpackUtils, LoadedPlugin } from '@docusaurus/types';
|
|
11
10
|
/**
|