Skip to content

Commit

Permalink
backward compatible for loader and support import client component fo…
Browse files Browse the repository at this point in the history
…r server component
  • Loading branch information
huozhi committed Dec 6, 2022
1 parent 3735799 commit d217c24
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 56 deletions.
11 changes: 10 additions & 1 deletion packages/next/shared/lib/dynamic.tsx
Expand Up @@ -88,7 +88,7 @@ export default function dynamic<P = {}>(
// A loading component is not required, so we default it
loading: ({ error, isLoading, pastDelay }) => {
if (!pastDelay) return null
if (process.env.NODE_ENV === 'development') {
if (process.env.NODE_ENV !== 'production') {
if (isLoading) {
return null
}
Expand Down Expand Up @@ -123,6 +123,15 @@ export default function dynamic<P = {}>(
// Support for passing options, eg: dynamic(import('../hello-world'), {loading: () => <p>Loading something</p>})
loadableOptions = { ...loadableOptions, ...options }

const loader = loadableOptions.loader as Loader<P>

// Normalize loader to return the module as form { default: Component } for `React.lazy`.
// Also for backward compatible since next/dynamic allows to resolve a component directly with loader
loadableOptions.loader = () =>
loader().then((mod) => {
return { default: mod.default || mod }
})

// coming from build/babel/plugins/react-loadable-plugin.js
if (loadableOptions.loadableGenerated) {
loadableOptions = {
Expand Down
@@ -1,11 +1,8 @@
import dynamic from 'next/dynamic'

const BrowserLoaded = dynamic(
async () => ({ default: () => <div>Browser hydrated</div> }),
{
ssr: false,
}
)
const BrowserLoaded = dynamic(async () => () => <div>Browser hydrated</div>, {
ssr: false,
})

export default () => (
<div>
Expand Down
40 changes: 19 additions & 21 deletions test/development/basic-basepath/next-dynamic/pages/dynamic/head.js
Expand Up @@ -3,27 +3,25 @@ import Head from 'next/head'

const Test = dynamic({
loader: async () => {
// component module
return {
default: () => {
return (
<div className="dynamic-style">
<Head>
<style
dangerouslySetInnerHTML={{
__html: `
.dynamic-style {
background-color: green;
height: 200px;
}
`,
}}
/>
</Head>
test
</div>
)
},
// component
return () => {
return (
<div className="dynamic-style">
<Head>
<style
dangerouslySetInnerHTML={{
__html: `
.dynamic-style {
background-color: green;
height: 200px;
}
`,
}}
/>
</Head>
test
</div>
)
}
},
ssr: false,
Expand Down
9 changes: 3 additions & 6 deletions test/development/basic/next-dynamic/components/nested2.js
@@ -1,12 +1,9 @@
// import { lazy } from 'react'
import dynamic from 'next/dynamic'

const BrowserLoaded = dynamic(
async () => ({ default: () => <div>Browser hydrated</div> }),
{
ssr: false,
}
)
const BrowserLoaded = dynamic(async () => () => <div>Browser hydrated</div>, {
ssr: false,
})

export default () => (
<div>
Expand Down
40 changes: 19 additions & 21 deletions test/development/basic/next-dynamic/pages/dynamic/head.js
Expand Up @@ -3,27 +3,25 @@ import Head from 'next/head'

const Test = dynamic({
loader: async () => {
// component module
return {
default: () => {
return (
<div className="dynamic-style">
<Head>
<style
dangerouslySetInnerHTML={{
__html: `
.dynamic-style {
background-color: green;
height: 200px;
}
`,
}}
/>
</Head>
test
</div>
)
},
// component
return () => {
return (
<div className="dynamic-style">
<Head>
<style
dangerouslySetInnerHTML={{
__html: `
.dynamic-style {
background-color: green;
height: 200px;
}
`,
}}
/>
</Head>
test
</div>
)
}
},
ssr: false,
Expand Down
@@ -0,0 +1,7 @@
import dynamic from 'next/dynamic'

const Dynamic = dynamic(() => import('../text-dynamic-server-import-client'))

export function NextDynamicServerImportClientComponent() {
return <Dynamic />
}
@@ -1,6 +1,7 @@
import dynamic from 'next/dynamic'

const Dynamic = dynamic(() => import('../text-dynamic-server'), {
// This ssr option will be ignored in server component
ssr: false,
})

Expand Down
Expand Up @@ -2,7 +2,7 @@

import { useState, lazy } from 'react'

const Lazy = lazy(() => import('../text-lazy-client.js'))
const Lazy = lazy(() => import('../text-lazy-client'))

export function LazyClientComponent() {
let [state] = useState('use client')
Expand Down
2 changes: 2 additions & 0 deletions test/e2e/app-dir/app/app/dashboard/index/page.js
@@ -1,6 +1,7 @@
import { LazyClientComponent } from './dynamic-imports/react-lazy-client'
import { NextDynamicServerComponent } from './dynamic-imports/dynamic-server'
import { NextDynamicClientComponent } from './dynamic-imports/dynamic-client'
import { NextDynamicServerImportClientComponent } from './dynamic-imports/dynamic-server-import-client'

export default function DashboardIndexPage() {
return (
Expand All @@ -9,6 +10,7 @@ export default function DashboardIndexPage() {
<NextDynamicServerComponent />
<NextDynamicClientComponent />
<LazyClientComponent />
<NextDynamicServerImportClientComponent />
</>
)
}
@@ -0,0 +1,9 @@
'use client'

export default function ClientImportedByServer() {
return (
<p id="text-dynamic-server-import-client">
hello from server import client
</p>
)
}
1 change: 1 addition & 0 deletions test/e2e/app-dir/index.test.ts
Expand Up @@ -143,6 +143,7 @@ describe('app dir', () => {
// should support `dynamic` in both server and client components
expect(html).toContain('hello from dynamic on server')
expect(html).toContain('hello from dynamic on client')
expect(html).toContain('hello from server import client')
})

it('should serve polyfills for browsers that do not support modules', async () => {
Expand Down

0 comments on commit d217c24

Please sign in to comment.