diff --git a/CHANGELOG-2.x.md b/CHANGELOG-2.x.md index fd554c9bb0..e31f86bf3b 100644 --- a/CHANGELOG-2.x.md +++ b/CHANGELOG-2.x.md @@ -8,6 +8,9 @@ - Fix `swizzle` command not being able to swizzle single js file. - Fix logo URL in footer to be appended with baseUrl automatically. - Add the option `--no-open` for `start` command. +- Set `@babel/env` useBuiltins to `usage`. This will automatically use browserlist and import polyfills required. +- Modified TerserWebpackPlugin `terserOptions` for better cross-browser compatibility. +- **BREAKING** `withBaseUrl` is renamed to `useBaseUrl` because its a React Hooks. Make sure you import/rename it correctly. Eg: `import useBaseUrl from '@docusaurus/useBaseUrl`; - Fix potential security vulnerability because we're exposing the directory structure of the host machine. ## 2.0.0-alpha.27 diff --git a/packages/docusaurus-init/templates/classic/src/pages/index.js b/packages/docusaurus-init/templates/classic/src/pages/index.js index 955aff747d..2200e35c61 100644 --- a/packages/docusaurus-init/templates/classic/src/pages/index.js +++ b/packages/docusaurus-init/templates/classic/src/pages/index.js @@ -10,7 +10,7 @@ import classnames from 'classnames'; import Layout from '@theme/Layout'; import Link from '@docusaurus/Link'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import withBaseUrl from '@docusaurus/withBaseUrl'; +import useBaseUrl from '@docusaurus/useBaseUrl'; import styles from './styles.module.css'; const features = [ @@ -46,6 +46,21 @@ const features = [ }, ]; +function Feature({imageUrl, title, description}) { + const imgUrl = useBaseUrl(imageUrl); + return ( +
+ {imgUrl && ( +
+ {title} +
+ )} +

{title}

+

{description}

+
+ ); +} + function Home() { const context = useDocusaurusContext(); const {siteConfig = {}} = context; @@ -63,7 +78,7 @@ function Home() { 'button button--outline button--secondary button--lg', styles.getStarted, )} - to={withBaseUrl('docs/doc1')}> + to={useBaseUrl('docs/doc1')}> Get Started @@ -74,22 +89,8 @@ function Home() {
- {features.map(({imageUrl, title, description}, idx) => ( -
- {imageUrl && ( -
- {title} -
- )} -

{title}

-

{description}

-
+ {features.map((props, idx) => ( + ))}
diff --git a/packages/docusaurus-theme-classic/src/theme/DocItem/index.js b/packages/docusaurus-theme-classic/src/theme/DocItem/index.js index ff4dea2dac..eeb7cfc311 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocItem/index.js +++ b/packages/docusaurus-theme-classic/src/theme/DocItem/index.js @@ -9,7 +9,7 @@ import React from 'react'; import Head from '@docusaurus/Head'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import withBaseUrl from '@docusaurus/withBaseUrl'; +import useBaseUrl from '@docusaurus/useBaseUrl'; import DocPaginator from '@theme/DocPaginator'; import styles from './styles.module.css'; @@ -45,6 +45,8 @@ function DocItem(props) { keywords, } = metadata; + const metaImageUrl = siteUrl + useBaseUrl(metaImage); + return (
@@ -56,18 +58,8 @@ function DocItem(props) { {keywords && keywords.length && ( )} - {metaImage && ( - - )} - {metaImage && ( - - )} + {metaImage && } + {metaImage && } {metaImage && ( )} diff --git a/packages/docusaurus-theme-classic/src/theme/Footer/index.js b/packages/docusaurus-theme-classic/src/theme/Footer/index.js index 506b9752f0..38ea6a0e63 100644 --- a/packages/docusaurus-theme-classic/src/theme/Footer/index.js +++ b/packages/docusaurus-theme-classic/src/theme/Footer/index.js @@ -10,7 +10,27 @@ import classnames from 'classnames'; import Link from '@docusaurus/Link'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import withBaseUrl from '@docusaurus/withBaseUrl'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +function FooterLink({item}) { + const toUrl = useBaseUrl(item.to); + return ( + + {item.label} + + ); +} function Footer() { const context = useDocusaurusContext(); @@ -18,12 +38,13 @@ function Footer() { const {themeConfig = {}} = siteConfig; const {footer} = themeConfig; + const {copyright, links = [], logo = {}} = footer || {}; + const logoUrl = useBaseUrl(logo.src); + if (!footer) { return null; } - const {copyright, links = [], logo} = footer; - return (
{linkItem.items.map(item => (
  • - - {item.label} - +
  • ))} @@ -69,11 +77,7 @@ function Footer() {
    {logo && logo.src && (
    - {logo.alt} + {logo.alt}
    )} {copyright} diff --git a/packages/docusaurus-theme-classic/src/theme/Layout/index.js b/packages/docusaurus-theme-classic/src/theme/Layout/index.js index 6032ee745a..bcba87a5e8 100644 --- a/packages/docusaurus-theme-classic/src/theme/Layout/index.js +++ b/packages/docusaurus-theme-classic/src/theme/Layout/index.js @@ -8,7 +8,7 @@ import React from 'react'; import Head from '@docusaurus/Head'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import withBaseUrl from '@docusaurus/withBaseUrl'; +import useBaseUrl from '@docusaurus/useBaseUrl'; import Navbar from '@theme/Navbar'; import Footer from '@theme/Footer'; @@ -34,6 +34,8 @@ function Layout(props) { } = props; const metaTitle = title || `${defaultTitle} · ${tagline}`; const metaImage = image || defaultImage; + const metaImageUrl = siteUrl + useBaseUrl(metaImage); + const faviconUrl = useBaseUrl(favicon); return ( @@ -42,7 +44,7 @@ function Layout(props) { {metaTitle && {metaTitle}} {metaTitle && } - {favicon && } + {favicon && } {description && } {description && ( @@ -50,18 +52,8 @@ function Layout(props) { {keywords && keywords.length && ( )} - {metaImage && ( - - )} - {metaImage && ( - - )} + {metaImage && } + {metaImage && } {metaImage && ( )} diff --git a/packages/docusaurus-theme-classic/src/theme/Navbar/index.js b/packages/docusaurus-theme-classic/src/theme/Navbar/index.js index ab463b2fbf..f60d3c331c 100644 --- a/packages/docusaurus-theme-classic/src/theme/Navbar/index.js +++ b/packages/docusaurus-theme-classic/src/theme/Navbar/index.js @@ -11,7 +11,7 @@ import Toggle from 'react-toggle'; import Link from '@docusaurus/Link'; import Head from '@docusaurus/Head'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import withBaseUrl from '@docusaurus/withBaseUrl'; +import useBaseUrl from '@docusaurus/useBaseUrl'; import SearchBar from '@theme/SearchBar'; @@ -20,6 +20,7 @@ import classnames from 'classnames'; import styles from './styles.module.css'; function NavLink(props) { + const toUrl = useBaseUrl(props.to); return ( {props.label} @@ -54,7 +55,7 @@ function Navbar() { const {siteConfig = {}} = context; const {baseUrl, themeConfig = {}} = siteConfig; const {algolia, navbar = {}} = themeConfig; - const {title, logo, links = []} = navbar; + const {title, logo = {}, links = []} = navbar; const showSidebar = useCallback(() => { setSidebarShown(true); @@ -82,6 +83,7 @@ function Navbar() { } }; + const logoUrl = useBaseUrl(logo.src); return ( @@ -120,11 +122,7 @@ function Navbar() {
    {logo != null && ( - {logo.alt} + {logo.alt} )} {title != null && ( {logo != null && ( - {logo.alt} + {logo.alt} )} {title != null && {title}} diff --git a/packages/docusaurus/src/client/exports/Noop.ts b/packages/docusaurus/src/client/exports/Noop.js similarity index 100% rename from packages/docusaurus/src/client/exports/Noop.ts rename to packages/docusaurus/src/client/exports/Noop.js diff --git a/packages/docusaurus/src/client/exports/__tests__/useBaseUrl.ts b/packages/docusaurus/src/client/exports/__tests__/useBaseUrl.ts new file mode 100644 index 0000000000..90333af495 --- /dev/null +++ b/packages/docusaurus/src/client/exports/__tests__/useBaseUrl.ts @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import useBaseUrl from '../useBaseUrl'; +import useDocusaurusContext from '../useDocusaurusContext'; +jest.mock('../useDocusaurusContext', () => jest.fn(), {virtual: true}); + +const mockedContext = useDocusaurusContext; + +describe('useBaseUrl', () => { + test('empty base URL', () => { + mockedContext.mockImplementation(() => ({ + siteConfig: { + baseUrl: '/', + }, + })); + + expect(useBaseUrl('hello')).toEqual('/hello'); + expect(useBaseUrl('/hello')).toEqual('/hello'); + expect(useBaseUrl('hello/')).toEqual('/hello/'); + expect(useBaseUrl('/hello/')).toEqual('/hello/'); + expect(useBaseUrl('hello/byebye')).toEqual('/hello/byebye'); + expect(useBaseUrl('/hello/byebye')).toEqual('/hello/byebye'); + expect(useBaseUrl('hello/byebye/')).toEqual('/hello/byebye/'); + expect(useBaseUrl('/hello/byebye/')).toEqual('/hello/byebye/'); + expect(useBaseUrl('https://github.com')).toEqual('https://github.com'); + expect(useBaseUrl('//reactjs.org')).toEqual('//reactjs.org'); + }); + + test('non-empty base URL', () => { + mockedContext.mockImplementation(() => ({ + siteConfig: { + baseUrl: '/docusaurus/', + }, + })); + + expect(useBaseUrl('hello')).toEqual('/docusaurus/hello'); + expect(useBaseUrl('/hello')).toEqual('/docusaurus/hello'); + expect(useBaseUrl('hello/')).toEqual('/docusaurus/hello/'); + expect(useBaseUrl('/hello/')).toEqual('/docusaurus/hello/'); + expect(useBaseUrl('hello/byebye')).toEqual('/docusaurus/hello/byebye'); + expect(useBaseUrl('/hello/byebye')).toEqual('/docusaurus/hello/byebye'); + expect(useBaseUrl('hello/byebye/')).toEqual('/docusaurus/hello/byebye/'); + expect(useBaseUrl('/hello/byebye/')).toEqual('/docusaurus/hello/byebye/'); + expect(useBaseUrl('https://github.com')).toEqual('https://github.com'); + expect(useBaseUrl('//reactjs.org')).toEqual('//reactjs.org'); + }); +}); diff --git a/packages/docusaurus/src/client/exports/__tests__/withBaseUrl.ts b/packages/docusaurus/src/client/exports/__tests__/withBaseUrl.ts deleted file mode 100644 index aaa6bcb141..0000000000 --- a/packages/docusaurus/src/client/exports/__tests__/withBaseUrl.ts +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import withBaseUrl from '../withBaseUrl'; -import useDocusaurusContext from '../useDocusaurusContext'; -jest.mock('../useDocusaurusContext', () => jest.fn(), {virtual: true}); - -const mockedContext = useDocusaurusContext; - -describe('withBaseUrl', () => { - test('empty base URL', () => { - mockedContext.mockImplementation(() => ({ - siteConfig: { - baseUrl: '/', - }, - })); - - expect(withBaseUrl('hello')).toEqual('/hello'); - expect(withBaseUrl('/hello')).toEqual('/hello'); - expect(withBaseUrl('hello/')).toEqual('/hello/'); - expect(withBaseUrl('/hello/')).toEqual('/hello/'); - expect(withBaseUrl('hello/byebye')).toEqual('/hello/byebye'); - expect(withBaseUrl('/hello/byebye')).toEqual('/hello/byebye'); - expect(withBaseUrl('hello/byebye/')).toEqual('/hello/byebye/'); - expect(withBaseUrl('/hello/byebye/')).toEqual('/hello/byebye/'); - expect(withBaseUrl('https://github.com')).toEqual('https://github.com'); - expect(withBaseUrl('//reactjs.org')).toEqual('//reactjs.org'); - }); - - test('non-empty base URL', () => { - mockedContext.mockImplementation(() => ({ - siteConfig: { - baseUrl: '/docusaurus/', - }, - })); - - expect(withBaseUrl('hello')).toEqual('/docusaurus/hello'); - expect(withBaseUrl('/hello')).toEqual('/docusaurus/hello'); - expect(withBaseUrl('hello/')).toEqual('/docusaurus/hello/'); - expect(withBaseUrl('/hello/')).toEqual('/docusaurus/hello/'); - expect(withBaseUrl('hello/byebye')).toEqual('/docusaurus/hello/byebye'); - expect(withBaseUrl('/hello/byebye')).toEqual('/docusaurus/hello/byebye'); - expect(withBaseUrl('hello/byebye/')).toEqual('/docusaurus/hello/byebye/'); - expect(withBaseUrl('/hello/byebye/')).toEqual('/docusaurus/hello/byebye/'); - expect(withBaseUrl('https://github.com')).toEqual('https://github.com'); - expect(withBaseUrl('//reactjs.org')).toEqual('//reactjs.org'); - }); -}); diff --git a/packages/docusaurus/src/client/exports/context.ts b/packages/docusaurus/src/client/exports/context.js similarity index 56% rename from packages/docusaurus/src/client/exports/context.ts rename to packages/docusaurus/src/client/exports/context.js index eb95258c39..044da5a1bd 100644 --- a/packages/docusaurus/src/client/exports/context.ts +++ b/packages/docusaurus/src/client/exports/context.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -import * as React from 'react'; -import {DocusaurusContext} from '@docusaurus/types'; +import React from 'react'; -export default React.createContext({}); +export default React.createContext({}); diff --git a/packages/docusaurus/src/client/exports/withBaseUrl.ts b/packages/docusaurus/src/client/exports/useBaseUrl.js similarity index 87% rename from packages/docusaurus/src/client/exports/withBaseUrl.ts rename to packages/docusaurus/src/client/exports/useBaseUrl.js index add2e06b83..4c8a6d6985 100644 --- a/packages/docusaurus/src/client/exports/withBaseUrl.ts +++ b/packages/docusaurus/src/client/exports/useBaseUrl.js @@ -7,10 +7,14 @@ import useDocusaurusContext from './useDocusaurusContext'; -function withBaseUrl(url: string): string { +export default function useBaseUrl(url) { const {siteConfig} = useDocusaurusContext(); const {baseUrl = '/'} = siteConfig || {}; + if (!url) { + return url; + } + const externalRegex = /^(https?:|\/\/)/; if (externalRegex.test(url)) { return url; @@ -20,5 +24,3 @@ function withBaseUrl(url: string): string { } return baseUrl + url; } - -export default withBaseUrl; diff --git a/packages/docusaurus/src/client/exports/useDocusaurusContext.ts b/packages/docusaurus/src/client/exports/useDocusaurusContext.js similarity index 75% rename from packages/docusaurus/src/client/exports/useDocusaurusContext.ts rename to packages/docusaurus/src/client/exports/useDocusaurusContext.js index 953cb3ff98..d91b103f2e 100644 --- a/packages/docusaurus/src/client/exports/useDocusaurusContext.ts +++ b/packages/docusaurus/src/client/exports/useDocusaurusContext.js @@ -7,9 +7,8 @@ import {useContext} from 'react'; import context from './context'; -import {DocusaurusContext} from '@docusaurus/types'; -function useDocusaurusContext(): DocusaurusContext { +function useDocusaurusContext() { return useContext(context); } diff --git a/packages/docusaurus/src/client/theme-fallback/Layout/index.js b/packages/docusaurus/src/client/theme-fallback/Layout/index.js index bd2601274c..52b04ee2de 100644 --- a/packages/docusaurus/src/client/theme-fallback/Layout/index.js +++ b/packages/docusaurus/src/client/theme-fallback/Layout/index.js @@ -8,18 +8,19 @@ import React from 'react'; import Head from '@docusaurus/Head'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import withBaseUrl from '@docusaurus/withBaseUrl'; +import useBaseUrl from '@docusaurus/useBaseUrl'; function Layout(props) { const context = useDocusaurusContext(); const {siteConfig = {}} = context; const {favicon, tagline, title: defaultTitle} = siteConfig; const {children, title, description} = props; + const faviconUrl = useBaseUrl(favicon); return ( {title && {`${title} · ${tagline}`}} - {favicon && } + {favicon && } {description && } {description && ( diff --git a/packages/docusaurus/src/webpack/base.ts b/packages/docusaurus/src/webpack/base.ts index 3771af2f03..0e1f6d2591 100644 --- a/packages/docusaurus/src/webpack/base.ts +++ b/packages/docusaurus/src/webpack/base.ts @@ -65,10 +65,27 @@ export function createBaseConfig( parallel: true, sourceMap: false, terserOptions: { - ecma: 6, - mangle: true, + parse: { + // we want uglify-js to parse ecma 8 code. However, we don't want it + // to apply any minfication steps that turns valid ecma 5 code + // into invalid ecma 5 code. This is why the 'compress' and 'output' + // sections only apply transformations that are ecma 5 safe + // https://github.com/facebook/create-react-app/pull/4234 + ecma: 8, + }, + compress: { + ecma: 5, + warnings: false, + }, + mangle: { + safari10: true, + }, output: { + ecma: 5, comments: false, + // Turned on because emoji and regex is not minified properly using default + // https://github.com/facebook/create-react-app/issues/2488 + ascii_only: true, }, }, }), diff --git a/packages/docusaurus/src/webpack/utils.ts b/packages/docusaurus/src/webpack/utils.ts index 2bacd9a794..d141d7e3fe 100644 --- a/packages/docusaurus/src/webpack/utils.ts +++ b/packages/docusaurus/src/webpack/utils.ts @@ -88,7 +88,21 @@ export function getBabelLoader(isServer: boolean, babelOptions?: {}): Loader { { babelrc: false, configFile: false, - presets: ['@babel/env', '@babel/react'], + presets: [ + [ + '@babel/env', + { + useBuiltIns: 'usage', + loose: true, + corejs: '2', + // Do not transform modules to CJS + modules: false, + // Exclude transforms that make all code slower + exclude: ['transform-typeof-symbol'], + }, + ], + '@babel/react', + ], plugins: [ isServer ? 'dynamic-import-node' : '@babel/syntax-dynamic-import', ], diff --git a/website/docs/static-assets.md b/website/docs/static-assets.md index e4f035580f..e40703d5f5 100644 --- a/website/docs/static-assets.md +++ b/website/docs/static-assets.md @@ -13,23 +13,23 @@ This means that if the site's `baseUrl` is `/`, an image in `/static/img/docusau You can reference assets from the `static` folder in your code. You could use hardcoded absolute paths, i.e. starting with a slash /, but remember to include the `baseUrl` if it is not `/`. However, this will break if you change your `baseUrl` in the config. -A better way would be to use the `withBaseUrl` utility function which appends the `baseUrl` to paths for you. +A better way would be to use the `useBaseUrl` utility function which appends the `baseUrl` to paths for you. ### JSX example ```jsx // MyComponent.js -import withBaseUrl from '@docusaurus/withBaseUrl'; +import useBaseUrl from '@docusaurus/useBaseUrl'; Docusaurus with Keytar; ``` ### Markdown example -Thanks to MDX, you can also use `withBaseUrl` utility function in Markdown files! You'd have to use `` tags instead of the Markdown image syntax though. The syntax is exactly the same as in JSX. +Thanks to MDX, you can also use `useBaseUrl` utility function in Markdown files! You'd have to use `` tags instead of the Markdown image syntax though. The syntax is exactly the same as in JSX. ```txt // my-doc.mdx @@ -38,11 +38,11 @@ id: my-doc title: My Doc --- -import withBaseUrl from '@docusaurus/withBaseUrl'; // Add to the top of the file below the front matter. +import useBaseUrl from '@docusaurus/useBaseUrl'; // Add to the top of the file below the front matter. ... -Docusaurus with Keytar; +Docusaurus with Keytar; ``` You could also just use Markdown image syntax, but you would have to manually maintain the image paths yourself and isn't recommended. diff --git a/website/src/pages/help.js b/website/src/pages/help.js index 1e1525bbad..b8f96e2cb0 100644 --- a/website/src/pages/help.js +++ b/website/src/pages/help.js @@ -9,7 +9,7 @@ import React, {useEffect} from 'react'; import Layout from '@theme/Layout'; import Link from '@docusaurus/Link'; -import withBaseUrl from '@docusaurus/withBaseUrl'; +import useBaseUrl from '@docusaurus/useBaseUrl'; function Help() { return ( @@ -27,7 +27,7 @@ function Help() {

    Browse the docs

    Learn more about Docusaurus using the{' '} - + official documentation

    diff --git a/website/src/pages/index.js b/website/src/pages/index.js index b34196d772..34d77942c4 100644 --- a/website/src/pages/index.js +++ b/website/src/pages/index.js @@ -8,7 +8,7 @@ import React from 'react'; import Link from '@docusaurus/Link'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import withBaseUrl from '@docusaurus/withBaseUrl'; +import useBaseUrl from '@docusaurus/useBaseUrl'; import Image from '@theme/IdealImage'; import Layout from '@theme/Layout'; @@ -73,7 +73,7 @@ function Home() { Docusaurus with Keytar {siteConfig.title} makes it easy to maintain{' '} Open Source{' '} @@ -82,7 +82,7 @@ function Home() {
    + to={useBaseUrl('docs/introduction')}> Get Started @@ -105,14 +105,14 @@ function Home() { Docusaurus 2 , contribute to its roadmap by suggesting features or giving feedback{' '} - here! + here!
    Coming from v1? Check out our{' '} - + v1 to v2 migration guide . @@ -125,7 +125,7 @@ function Home() { Powered by MDX

    Powered by Markdown

    @@ -139,7 +139,7 @@ function Home() { Built Using React

    Built Using React

    @@ -152,7 +152,7 @@ function Home() { Ready for Translations

    Ready for Translations

    @@ -168,7 +168,7 @@ function Home() { Document Versioning

    Document Versioning

    @@ -181,7 +181,7 @@ function Home() { Document Search

    Document Search