Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): support TypeScript + ESM configuration #9317

Merged
merged 49 commits into from
Oct 14, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
3f54f4f
feat: support typescript configuration
harryzcy Sep 17, 2023
b9db574
Apply suggestions from code review
harryzcy Sep 19, 2023
b88e1c8
fix: handle function typed config
harryzcy Sep 19, 2023
bb5b90a
Merge branch 'main' into config-in-ts
harryzcy Sep 24, 2023
0f66191
chore: remove other usage of `import-fresh`
harryzcy Sep 24, 2023
8f48f9d
chore: remove `import-fresh` in package.json
harryzcy Sep 24, 2023
138e25e
fix: fix tests related to config loading
harryzcy Sep 24, 2023
901c95e
fix: test case when config is promise
harryzcy Sep 25, 2023
3913aa8
chore: add testcase for typescript
harryzcy Sep 25, 2023
b9a12d3
Merge branch 'main' into config-in-ts
slorber Oct 12, 2023
6932057
Attempt to use TS sidebar
slorber Oct 12, 2023
201c874
Hide jiti behind Docusaurus utils loadFreshModule abstraction
slorber Oct 13, 2023
a7752ab
Merge branch 'main' into config-in-ts
slorber Oct 13, 2023
7af9f72
Add more loadSiteConfig test fixtures
slorber Oct 13, 2023
1e4d95e
scaffold loadFreshModule tests
slorber Oct 13, 2023
2c4a2e7
loadFreshModule tests for CJS / ESM
slorber Oct 13, 2023
2f522b2
add loadFreshModule tests
slorber Oct 13, 2023
5468bf9
Migrate templates to ESM
slorber Oct 13, 2023
d187645
Refactor init templates to ESM + TS
slorber Oct 13, 2023
5b120e6
add @docusaurus/types to templates by default
slorber Oct 13, 2023
80fb76d
refactor TS docs
slorber Oct 13, 2023
bad83af
update docs to ESM
slorber Oct 13, 2023
4a36942
remove useless require.resolve from docs
slorber Oct 13, 2023
81e2ec6
do not show CJS usage of remark-math plugin because it doesn't work a…
slorber Oct 13, 2023
5c764a3
docs cleanups + use consistant module quotes in docs
slorber Oct 13, 2023
4f9047c
docs cleanups
slorber Oct 13, 2023
a646e41
refactor docs pages for ESM/TS support
slorber Oct 13, 2023
9ac8565
add ts config loading test
slorber Oct 13, 2023
c94aee2
Test support for ESM / TS presets
slorber Oct 13, 2023
2b72d98
Add plugins loading ESM + TS tests
slorber Oct 13, 2023
d6ea99a
esm config
slorber Oct 13, 2023
6105396
remove useless require.resolve
slorber Oct 13, 2023
0a20fbd
migrate website config to TS
slorber Oct 13, 2023
0fe678b
migrate website config to TS
slorber Oct 13, 2023
2355ade
fix docs Joi import
slorber Oct 13, 2023
88e7d63
fix getSwizzleComponentList docs
slorber Oct 13, 2023
2cf10ee
fix ideal image type consistency
slorber Oct 13, 2023
b165e1d
migrate more website config to TS
slorber Oct 13, 2023
b9248dd
migrate more website config to TS
slorber Oct 13, 2023
71666f2
migrate more website config to TS
slorber Oct 13, 2023
047e394
migrate more website config to TS
slorber Oct 13, 2023
7c1cc5e
fix pwa error
slorber Oct 13, 2023
708c32f
fix weird changelog plugin bug due to using CJS?
slorber Oct 13, 2023
3e53198
more website config refactors
slorber Oct 13, 2023
dd40aea
lint
slorber Oct 13, 2023
729b6f8
refactor mdx plugin docs
slorber Oct 13, 2023
22b7c8c
refactor mdx plugin docs
slorber Oct 13, 2023
4f3e37b
lint
slorber Oct 14, 2023
67c333e
templates should use ESM
slorber Oct 14, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@
* LICENSE file in the root directory of this source tree.
*/

import importFresh from 'import-fresh';
import jiti from 'jiti';
import {createConfigFile} from '../index';
import type {VersionOneConfig} from '../types';

describe('create config', () => {
it('simple test', () => {
const v1Config: VersionOneConfig = importFresh(
const v1Config: VersionOneConfig = jiti(__dirname)(
`${__dirname}/__fixtures__/sourceSiteConfig.js`,
);
const siteDir = 'website';
const newDir = 'websiteMigrated';

const result = createConfigFile({v1Config, siteDir, newDir});

const output = importFresh(
const output = jiti(__dirname)(
`${__dirname}/__fixtures__/expectedSiteConfig.js`,
);
expect(result).toEqual(output);
Expand Down
2 changes: 1 addition & 1 deletion packages/docusaurus-plugin-content-docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"@types/react-router-config": "^5.0.7",
"combine-promises": "^1.1.0",
"fs-extra": "^11.1.1",
"import-fresh": "^3.3.0",
"jiti": "^1.20.0",
"js-yaml": "^4.1.0",
"lodash": "^4.17.21",
"tslib": "^2.6.0",
Expand Down
13 changes: 11 additions & 2 deletions packages/docusaurus-plugin-content-docs/src/sidebars/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import logger from '@docusaurus/logger';
import {Globby} from '@docusaurus/utils';
import Yaml from 'js-yaml';
import combinePromises from 'combine-promises';
import importFresh from 'import-fresh';
import jiti from 'jiti';
import {validateSidebars, validateCategoryMetadataFile} from './validation';
import {normalizeSidebars} from './normalization';
import {processSidebars} from './processor';
Expand Down Expand Up @@ -89,7 +89,16 @@ export async function loadSidebarsFileUnsafe(
}

// We don't want sidebars to be cached because of hot reloading.
return importFresh(sidebarFilePath);
const sidebars = jiti(__filename, {
cache: false,
interopDefault: true,
debug: true,
})(sidebarFilePath);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not look like a drop-in replacement for importFresh unfortunately.

Calling it multiple times will return the same result despite changing the underlying file.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi. You can set requireCache: false in order to disable (runtime) cache. cache option is for filesystem transform cache (and can be even kept enabled for better performance. you still will get a fresh value each time).

Please let me know if could help further on this :)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, we are working on new API jiti.import() (releasing by next week) if PR was delayed until then would be nice that you consider the migration for better future compatibility. It can bring support more native ESM compatibilities.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot @pi0 that's working. I saw requireCache in an older issue but thought it was an older removed option because it's not in v1 or v2 docs. But it's in the type and seems to work as I expect 👍

Regarding jiti.import() (unjs/jiti#174?) I assume you want to say v2.0 is being released soon?

On my side I didn't expect to migrate away from importFresh in Docusaurus v3 but as jiti seems to work that would be a awesome improvement for our users so I'm already delaying a bit our official release to incorporate this PR 😄 I'd prefer to not be an early adopter of jiti v2 this time, for timing reasons it's preferable if we upgrade for Docusaurus v4 (or in a minor version later, if not considered as a breaking change)

Copy link

@pi0 pi0 Oct 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah awesome!

jiti.import() API will be also released as a backward compatible stub for v1 for future compatibility so you can migrate earlier and only bump the major version of jiti later -- which i expect no major breaking changes. bumping to v2 is to make sure ecosystem migration is not risky. (i am on holidays with family RN but might find some time to do it earlier). v2 is not expected that soon.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thanks :)

From what I understand currently Jiti is able to load modules synchronously but import will be async so it's probably better to assume async usage in the future?


sidebarFilePath.endsWith('.ts') &&
console.log({sidebarFilePath}, JSON.stringify(sidebars, null, 2));

return sidebars;
}

export async function loadSidebars(
Expand Down
2 changes: 1 addition & 1 deletion packages/docusaurus/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
"html-minifier-terser": "^7.2.0",
"html-tags": "^3.3.1",
"html-webpack-plugin": "^5.5.3",
"import-fresh": "^3.3.0",
"jiti": "^1.20.0",
"leven": "^3.1.0",
"lodash": "^4.17.21",
"mini-css-extract-plugin": "^2.7.6",
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -258,3 +258,51 @@ exports[`loadSiteConfig website with valid siteConfig 1`] = `
"siteConfigPath": "<PROJECT_ROOT>/packages/docusaurus/src/server/__tests__/__fixtures__/simple-site/docusaurus.config.js",
}
`;

exports[`loadSiteConfig website with valid typescript config 1`] = `
{
"siteConfig": {
"baseUrl": "/",
"baseUrlIssueBanner": true,
"clientModules": [],
"customFields": {},
"headTags": [],
"i18n": {
"defaultLocale": "en",
"localeConfigs": {},
"locales": [
"en",
],
"path": "i18n",
},
"markdown": {
"format": "mdx",
"mdx1Compat": {
"admonitions": true,
"comments": true,
"headingIds": true,
},
"mermaid": false,
"preprocessor": undefined,
},
"noIndex": false,
"onBrokenLinks": "throw",
"onBrokenMarkdownLinks": "warn",
"onDuplicateRoutes": "warn",
"plugins": [],
"presets": [],
"scripts": [],
"staticDirectories": [
"static",
],
"stylesheets": [],
"tagline": "",
"themeConfig": {},
"themes": [],
"title": "title",
"titleDelimiter": "|",
"url": "https://example.com",
},
"siteConfigPath": "<PROJECT_ROOT>/packages/docusaurus/src/server/__tests__/__fixtures__/config/configTypescript.config.ts",
}
`;
9 changes: 9 additions & 0 deletions packages/docusaurus/src/server/__tests__/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ describe('loadSiteConfig', () => {
expect(config).not.toEqual({});
});

it('website with valid typescript config', async () => {
const config = await loadSiteConfig({
siteDir,
customConfigFilePath: 'configTypescript.config.ts',
});
expect(config).toMatchSnapshot();
expect(config).not.toEqual({});
});

it('website with incomplete siteConfig', async () => {
await expect(
loadSiteConfig({
Expand Down
20 changes: 14 additions & 6 deletions packages/docusaurus/src/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import path from 'path';
import fs from 'fs-extra';
import importFresh from 'import-fresh';
import jiti from 'jiti';
import logger from '@docusaurus/logger';
import {DEFAULT_CONFIG_FILE_NAME, findAsyncSequential} from '@docusaurus/utils';
import {validateConfig} from './configValidation';
Expand Down Expand Up @@ -46,12 +46,20 @@ export async function loadSiteConfig({
throw new Error(`Config file at "${siteConfigPath}" not found.`);
}

const importedConfig = importFresh(siteConfigPath);
const importedConfig = jiti(__filename, {
cache: false,
})(siteConfigPath);

const loadedConfig: unknown =
typeof importedConfig === 'function'
? await importedConfig()
: await importedConfig;
let loadedConfig: unknown;
if (typeof importedConfig === 'function') {
loadedConfig = await importedConfig();
} else if (
Object.prototype.toString.call(importedConfig) === '[object Promise]'
) {
loadedConfig = await importedConfig;
} else {
loadedConfig = importedConfig;
}

const siteConfig = validateConfig(
loadedConfig,
Expand Down
6 changes: 3 additions & 3 deletions packages/docusaurus/src/server/plugins/configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import {createRequire} from 'module';
import importFresh from 'import-fresh';
import jiti from 'jiti';
import {loadPresets} from './presets';
import {resolveModuleName} from './moduleShorthand';
import type {
Expand Down Expand Up @@ -61,7 +61,7 @@ async function normalizePluginConfig(
if (typeof pluginConfig === 'string') {
const pluginModuleImport = pluginConfig;
const pluginPath = pluginRequire.resolve(pluginModuleImport);
const pluginModule = importFresh<ImportedPluginModule>(pluginPath);
const pluginModule = jiti(__filename)(pluginPath) as ImportedPluginModule;
return {
plugin: pluginModule.default ?? pluginModule,
options: {},
Expand All @@ -88,7 +88,7 @@ async function normalizePluginConfig(
if (typeof pluginConfig[0] === 'string') {
const pluginModuleImport = pluginConfig[0];
const pluginPath = pluginRequire.resolve(pluginModuleImport);
const pluginModule = importFresh<ImportedPluginModule>(pluginPath);
const pluginModule = jiti(__dirname)(pluginPath) as ImportedPluginModule;
return {
plugin: pluginModule.default ?? pluginModule,
options: pluginConfig[1],
Expand Down
7 changes: 3 additions & 4 deletions packages/docusaurus/src/server/plugins/presets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import {createRequire} from 'module';
import importFresh from 'import-fresh';
import jiti from 'jiti';
import {resolveModuleName} from './moduleShorthand';
import type {
LoadContext,
Expand Down Expand Up @@ -49,9 +49,8 @@ export async function loadPresets(
'preset',
);

const presetModule = importFresh<ImportedPresetModule>(
presetRequire.resolve(presetName),
);
const presetPath = presetRequire.resolve(presetName);
const presetModule = jiti(__filename)(presetPath) as ImportedPresetModule;
const preset = (presetModule.default ?? presetModule)(
context,
presetOptions,
Expand Down
26 changes: 11 additions & 15 deletions project-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ cssnano
csvg
customizability
dabit
dabit
daishi
datagit
datas
Expand Down Expand Up @@ -98,20 +97,22 @@ eslintcache
estree
evaluable
execa
execa
externalwaiting
failfast
Fargate
fbid
février
fienny
flac
flightcontrol
formik
fouc
froms
funboxteam
gantt
gabrielcsapo
gantt
getopts
gifs
gitgraph
gitpod
globbing
Expand All @@ -123,6 +124,7 @@ gtag
hahaha
hamel
hardcoding
hastscript
hasura
heavener
héctor
Expand All @@ -136,6 +138,7 @@ hoverable
husain
ianad
idempotency
Iframes
immer
infima
inlines
Expand All @@ -148,6 +151,7 @@ jakepartusch
jamstack
janvier
javadoc
jiti
jmarcey
jodyheavener
joshcena
Expand Down Expand Up @@ -183,6 +187,7 @@ mathjax
maxlynch
maxresdefault
mdast
mdwn
mdxa
mdxast
mdxhast
Expand All @@ -198,9 +203,8 @@ minifier
mkcert
mkdir
mkdirs
mkdocs
mkdn
mdwn
mkdocs
mkdown
moesif
msapplication
Expand Down Expand Up @@ -273,6 +277,7 @@ prerendered
prerendering
println
prismjs
producthunt
profilo
protobuf
protobuffet
Expand Down Expand Up @@ -319,7 +324,6 @@ serializers
setaf
setext
shiki
shiki
showinfo
sida
simen
Expand All @@ -328,7 +332,6 @@ sluggified
sluggifies
sluggify
solana
solana
spâce
stackblitz
stackblitzrc
Expand Down Expand Up @@ -373,6 +376,7 @@ typecheck
typechecks
typedoc
typesense
unavatar
unflat
unist
unlinkable
Expand Down Expand Up @@ -415,11 +419,3 @@ yangshunz
zhou
zoomable
zpao
hastscript
Flightcontrol
Fargate
Flightcontrol's
producthunt
Gifs
Iframes
Unavatar
2 changes: 1 addition & 1 deletion website/docs/guides/docs/sidebar/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ A real-world example from the Docusaurus site:
import CodeBlock from '@theme/CodeBlock';

<CodeBlock language="js" title="sidebars.js">
{require('!!raw-loader!@site/sidebars.js')
{require('!!raw-loader!@site/sidebars.ts')
.default
.split('\n')
// remove comments
Expand Down
2 changes: 1 addition & 1 deletion website/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ module.exports = async function createConfigAsync() {
docs: {
// routeBasePath: '/',
path: 'docs',
sidebarPath: 'sidebars.js',
sidebarPath: 'sidebars.ts',
// sidebarCollapsible: false,
// sidebarCollapsed: true,
editUrl: ({locale, docPath}) => {
Expand Down
7 changes: 3 additions & 4 deletions website/sidebars.js → website/sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
* LICENSE file in the root directory of this source tree.
*/

// @ts-check
import type {SidebarsConfig} from '@docusaurus/plugin-content-docs';

/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
const sidebars = {
const sidebars: SidebarsConfig = {
docs: [
'introduction',
{
Expand Down Expand Up @@ -153,4 +152,4 @@ const sidebars = {
],
};

module.exports = sidebars;
export default sidebars;
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,8 @@ A real-world example from the Docusaurus site:
```mdx-code-block
import CodeBlock from '@theme/CodeBlock';

<CodeBlock language="js" title="sidebars.js">
{require('!!raw-loader!@site/sidebars.js')
<CodeBlock language="js" title="sidebars.ts">
{require('!!raw-loader!@site/sidebars.ts')
.default
.split('\n')
// remove comments
Expand Down
Loading
Loading