Skip to content

Commit

Permalink
Use import to load page and layout (#42325)
Browse files Browse the repository at this point in the history
Fixes #42534

* Use eager `import()` to load page/layout to avoid esm module resolution error, eager is to make sure all the sub resources like css are also included
* Fix layer detection, should use `module.layer` directly since `module.resourceResolveData` is not alway presented. It lost when switching from `require()` to `import()` for page/layout component

## Bug

- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have a helpful link attached, see `contributing.md`
  • Loading branch information
huozhi committed Nov 10, 2022
1 parent e0b946a commit 05bdd71
Show file tree
Hide file tree
Showing 7 changed files with 22 additions and 22 deletions.
6 changes: 1 addition & 5 deletions packages/next/build/webpack-config.ts
Expand Up @@ -921,11 +921,7 @@ export default async function getBaseWebpackConfig(
...customRootAliases,

...(pagesDir ? { [PAGES_DIR_ALIAS]: pagesDir } : {}),
...(appDir
? {
[APP_DIR_ALIAS]: appDir,
}
: {}),
...(appDir ? { [APP_DIR_ALIAS]: appDir } : {}),
[ROOT_DIR_ALIAS]: dir,
[DOT_NEXT_ALIAS]: distDir,
...(isClient || isEdgeServer ? getOptimizedAliases() : {}),
Expand Down
20 changes: 10 additions & 10 deletions packages/next/build/webpack/loaders/next-app-loader.ts
Expand Up @@ -8,7 +8,7 @@ import { verifyRootLayout } from '../../../lib/verifyRootLayout'
import * as Log from '../../../build/output/log'
import { APP_DIR_ALIAS } from '../../../lib/constants'

export const FILE_TYPES = {
const FILE_TYPES = {
layout: 'layout',
template: 'template',
error: 'error',
Expand Down Expand Up @@ -68,7 +68,7 @@ async function createTreeCodeFromPath({

// Use '' for segment as it's the page. There can't be a segment called '' so this is the safest way to add it.
props[parallelKey] = `['', {}, {
page: [() => require(${JSON.stringify(
page: [() => import(/* webpackMode: "eager" */ ${JSON.stringify(
resolvedPagePath
)}), ${JSON.stringify(resolvedPagePath)}]}]`
continue
Expand Down Expand Up @@ -106,7 +106,7 @@ async function createTreeCodeFromPath({
if (filePath === undefined) {
return ''
}
return `'${file}': [() => require(${JSON.stringify(
return `'${file}': [() => import(/* webpackMode: "eager" */ ${JSON.stringify(
filePath
)}), ${JSON.stringify(filePath)}],`
})
Expand Down Expand Up @@ -245,16 +245,16 @@ const nextAppLoader: webpack.LoaderDefinitionFunction<{
export ${treeCode}
export const pages = ${JSON.stringify(pages)}
export const AppRouter = require('next/dist/client/components/app-router.js').default
export const LayoutRouter = require('next/dist/client/components/layout-router.js').default
export const RenderFromTemplateContext = require('next/dist/client/components/render-from-template-context.js').default
export { default as AppRouter } from 'next/dist/client/components/app-router'
export { default as LayoutRouter } from 'next/dist/client/components/layout-router'
export { default as RenderFromTemplateContext } from 'next/dist/client/components/render-from-template-context'
export const staticGenerationAsyncStorage = require('next/dist/client/components/static-generation-async-storage').staticGenerationAsyncStorage
export const requestAsyncStorage = require('next/dist/client/components/request-async-storage.js').requestAsyncStorage
export { staticGenerationAsyncStorage } from 'next/dist/client/components/static-generation-async-storage'
export { requestAsyncStorage } from 'next/dist/client/components/request-async-storage'
export const serverHooks = require('next/dist/client/components/hooks-server-context.js')
export * as serverHooks from 'next/dist/client/components/hooks-server-context'
export const renderToReadableStream = require('next/dist/compiled/react-server-dom-webpack/server.browser').renderToReadableStream
export { renderToReadableStream } from 'next/dist/compiled/react-server-dom-webpack/server.browser'
export const __next_app_webpack_require__ = __webpack_require__
`

Expand Down
Expand Up @@ -85,13 +85,11 @@ export class FlightClientEntryPlugin {
const recordModule = (modId: string, mod: any) => {
const modResource = mod.resourceResolveData?.path || mod.resource

if (
mod.resourceResolveData?.context?.issuerLayer !==
WEBPACK_LAYERS.client
) {
if (mod.layer !== WEBPACK_LAYERS.client) {
return
}

// Check mod resource to exclude the empty resource module like virtual module created by next-flight-client-entry-loader
if (typeof modId !== 'undefined' && modResource) {
// Note that this isn't that reliable as webpack is still possible to assign
// additional queries to make sure there's no conflict even using the `named`
Expand Down
4 changes: 2 additions & 2 deletions packages/next/server/app-render.tsx
Expand Up @@ -915,7 +915,7 @@ export async function renderToHTMLOrFlight(
}

if (head) {
const Head = await interopDefault(head[0]())
const Head = await interopDefault(await head[0]())
return <Head params={currentParams} />
}

Expand Down Expand Up @@ -993,7 +993,7 @@ export async function renderToHTMLOrFlight(
/>
))
: null
const Comp = await interopDefault(getComponent())
const Comp = await interopDefault(await getComponent())

return [Comp, styles]
}
Expand Down
3 changes: 3 additions & 0 deletions test/e2e/app-dir/app-alias.test.ts
Expand Up @@ -22,6 +22,9 @@ describe('app-dir alias handling', () => {
'@types/react': 'latest',
'@types/node': 'latest',
},
packageJson: {
type: 'module',
},
})
})
afterAll(() => next.destroy())
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/app-dir/app-alias/next.config.js
@@ -1,4 +1,4 @@
module.exports = {
export default {
experimental: {
appDir: true,
},
Expand Down
3 changes: 3 additions & 0 deletions test/e2e/app-dir/app-alias/package.json
@@ -0,0 +1,3 @@
{
"type": "module"
}

0 comments on commit 05bdd71

Please sign in to comment.