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: Webpack 5 Experimental Support #10885

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/with-firebase-hosting/src/functions/.babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
}
]
]
}
}
2 changes: 1 addition & 1 deletion examples/with-flow/.babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
"plugins": [
"transform-flow-strip-types"
]
}
}
2 changes: 1 addition & 1 deletion examples/with-lingui/.babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
"plugins": [
"macros"
]
}
}
2 changes: 1 addition & 1 deletion examples/with-mocha/.babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
"presets": [["next/babel", { "preset-env": { "modules": "commonjs" } }]]
}
}
}
}
2 changes: 1 addition & 1 deletion examples/with-react-jss/.babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"presets": ["next/babel"]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ type BlogPost implements Node {
id: ID! @isUnique
title: String!
updatedAt: DateTime!
}
}
2 changes: 1 addition & 1 deletion examples/with-rebass/.babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
"plugins": [
["styled-components", { "ssr": true, "displayName": true, "preprocess": false } ]
]
}
}
2 changes: 1 addition & 1 deletion examples/with-relay-modern/.babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
"plugins": [
"relay"
]
}
}
2 changes: 1 addition & 1 deletion examples/with-relay-modern/schema/init-schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ type BlogPost implements Node {
id: ID! @isUnique
title: String!
updatedAt: DateTime!
}
}
10 changes: 10 additions & 0 deletions packages/next/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@
</a>
</p>

## Installation of Webpack 5 Compatible Next.js

Running the following command will alias `@module-federation/next` as `next`.

`yarn add next@npm:@module-federation/next`

`npm i next@npm:@module-federation/next`

Doing so allows no implementation changes to use. You would still consume as `require("next/head")` and so on.

## Getting Started

Visit <a aria-label="next.js learn" href="https://nextjs.org/learn">https://nextjs.org/learn</a> to get started with Next.js.
Expand Down
3 changes: 2 additions & 1 deletion packages/next/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,6 @@ export default async function build(dir: string, conf = null): Promise<void> {
pagesManifest[page] = bundleRelative.replace(/\\/g, '/')

const nonReservedPage = !page.match(/^\/(_app|_error|_document|api)/)

if (nonReservedPage && customAppGetInitialProps === undefined) {
customAppGetInitialProps = hasCustomGetInitialProps(
isLikeServerless
Expand Down Expand Up @@ -633,6 +632,7 @@ export default async function build(dir: string, conf = null): Promise<void> {
'utf8'
)
}

// Since custom _app.js can wrap the 404 page we have to opt-out of static optimization if it has getInitialProps
// Only export the static 404 when there is no /_error present
const useStatic404 =
Expand Down Expand Up @@ -671,6 +671,7 @@ export default async function build(dir: string, conf = null): Promise<void> {
if (staticPages.size > 0 || ssgPages.size > 0 || useStatic404) {
const combinedPages = [...staticPages, ...ssgPages]
const exportApp = require('../export').default

const exportOptions = {
silent: true,
buildExport: true,
Expand Down
117 changes: 82 additions & 35 deletions packages/next/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import ChunkNamesPlugin from './webpack/plugins/chunk-names-plugin'
import { CssMinimizerPlugin } from './webpack/plugins/css-minimizer-plugin'
import { importAutoDllPlugin } from './webpack/plugins/dll-import'
import { DropClientPage } from './webpack/plugins/next-drop-client-page-plugin'
import NextEsmPlugin from './webpack/plugins/next-esm-plugin'
Copy link
Contributor Author

Choose a reason for hiding this comment

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

broken in WP5, will address later

import NextJsSsrImportPlugin from './webpack/plugins/nextjs-ssr-import'
import NextJsSSRModuleCachePlugin from './webpack/plugins/nextjs-ssr-module-cache'
import PagesManifestPlugin from './webpack/plugins/pages-manifest-plugin'
Expand All @@ -51,6 +50,15 @@ import WebpackConformancePlugin, {
} from './webpack/plugins/webpack-conformance-plugin'

type ExcludesFalse = <T>(x: T | false) => x is T
var LiveReloadPlugin = require('./webpack/plugins/livereload.js').default

let NextEsmPlugin: any

const webpack5Experiential = parseInt(require('webpack').version) === 5

if (!webpack5Experiential) {
NextEsmPlugin = require('./webpack/plugins/next-esm-plugin')
}

const escapePathVariables = (value: any) => {
return typeof value === 'string'
Expand Down Expand Up @@ -270,7 +278,7 @@ export default async function getBaseWebpackConfig(
...getOptimizedAliases(isServer),
},
mainFields: isServer ? ['main', 'module'] : ['browser', 'module', 'main'],
plugins: [PnpWebpackPlugin],
plugins: !webpack5Experiential ? [PnpWebpackPlugin] : [],
}

const webpackMode = dev ? 'development' : 'production'
Expand Down Expand Up @@ -565,7 +573,7 @@ export default async function getBaseWebpackConfig(
// When the 'serverless' target is used all node_modules will be compiled into the output bundles
// So that the 'serverless' bundles have 0 runtime dependencies
'@ampproject/toolbox-optimizer', // except this one
],
].concat(webpack5Experiential ? ['enhanced-resolve'] : []),
optimization: {
checkWasmTypes: false,
nodeEnv: false,
Expand Down Expand Up @@ -629,8 +637,12 @@ export default async function getBaseWebpackConfig(
return '[name]'
},
libraryTarget: isServer ? 'commonjs2' : 'var',
hotUpdateChunkFilename: 'static/webpack/[id].[hash].hot-update.js',
hotUpdateMainFilename: 'static/webpack/[hash].hot-update.json',
hotUpdateChunkFilename: webpack5Experiential
? 'static/webpack/[id].[fullhash].hot-update.js'
: 'static/webpack/[id].[hash].hot-update.js',
hotUpdateMainFilename: webpack5Experiential
? 'static/webpack/[fullhash].hot-update.json'
: 'static/webpack/[hash].hot-update.json',
// This saves chunks with the name given via `import()`
chunkFilename: isServer
? `${dev ? '[name]' : '[name].[contenthash]'}.js`
Expand Down Expand Up @@ -663,7 +675,7 @@ export default async function getBaseWebpackConfig(
'node_modules',
...nodePathList, // Support for NODE_PATH environment variable
],
plugins: [PnpWebpackPlugin],
plugins: webpack5Experiential ? [] : [PnpWebpackPlugin],
},
module: {
rules: [
Expand Down Expand Up @@ -806,41 +818,59 @@ export default async function getBaseWebpackConfig(
]

if (!isServer) {
const AutoDllPlugin = importAutoDllPlugin({ distDir })
devPlugins.push(
new AutoDllPlugin({
filename: '[name]_[hash].js',
path: './static/development/dll',
context: dir,
entry: {
dll: ['react', 'react-dom'],
},
config: {
devtool,
mode: webpackMode,
resolve: resolveConfig,
},
})
)
devPlugins.push(new webpack.HotModuleReplacementPlugin())
if (!webpack5Experiential) {
// Not needed with webpack 5
const AutoDllPlugin = importAutoDllPlugin({ distDir })
Copy link
Contributor Author

Choose a reason for hiding this comment

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

WP5 has its own cache, and its faast

devPlugins.push(
new AutoDllPlugin({
filename: '[name]_[hash].js',
path: './static/development/dll',
context: dir,
entry: {
dll: ['react', 'react-dom'],
},
config: {
devtool,
mode: webpackMode,
resolve: resolveConfig,
},
})
)
}
!webpack5Experiential &&
devPlugins.push(new webpack.HotModuleReplacementPlugin())
webpack5Experiential &&
devPlugins.push(new LiveReloadPlugin({ appendScriptTag: true }))
}

return devPlugins
})()
: []),
!dev && new webpack.HashedModuleIdsPlugin(),
!dev &&
new webpack.IgnorePlugin({
checkResource: (resource: string) => {
return /react-is/.test(resource)
},
checkContext: (context: string) => {
return (
/next-server[\\/]dist[\\/]/.test(context) ||
/next[\\/]dist[\\/]/.test(context)
)
},
}),
(webpack5Experiential
? // @ts-ignore
new webpack.ids.HashedModuleIdsPlugin()
: new webpack.HashedModuleIdsPlugin()),
!dev &&
new webpack.IgnorePlugin(
webpack5Experiential
? {
// webpack 5 only accepts New RegEx
resourceRegExp: /react-is/,
contextRegExp: /(next-server|next)[\\/]dist[\\/]/,
}
: {
checkResource: (resource: string) => {
return /react-is/.test(resource)
},
checkContext: (context: string) => {
return (
/next-server[\\/]dist[\\/]/.test(context) ||
/next[\\/]dist[\\/]/.test(context)
)
},
}
),
isServerless && isServer && new ServerlessPlugin(),
isServer && new PagesManifestPlugin(isLikeServerless),
target === 'server' &&
Expand Down Expand Up @@ -874,8 +904,10 @@ export default async function getBaseWebpackConfig(
})
),
config.experimental.modern &&
!webpack5Experiential &&
!isServer &&
!dev &&
// does not work with WP5, needs to be refactored.
new NextEsmPlugin({
filename: (getFileName: Function | string) => (...args: any[]) => {
const name =
Expand Down Expand Up @@ -932,6 +964,13 @@ export default async function getBaseWebpackConfig(
)
}

if (webpack5Experiential) {
// @ts-ignore
delete webpackConfig.output.futureEmitAssets
// @ts-ignore
delete webpackConfig.node.setImmediate
}

webpackConfig = await buildConfiguration(webpackConfig, {
rootDirectory: dir,
customAppFile,
Expand All @@ -943,6 +982,14 @@ export default async function getBaseWebpackConfig(
sassOptions: config.experimental.sassOptions,
})

// in Webpack 5- var larbraryType output requires a name, will default to package.json name soon
if (!isServer && webpack5Experiential) {
// @ts-ignore
webpackConfig.output.library = webpackConfig.output.library
? webpackConfig.output.library
: 'nextapp'
}

if (typeof config.webpack === 'function') {
webpackConfig = config.webpack(webpackConfig, {
dir,
Expand Down