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

refactor: polyfill-nomodule handling #21418

Closed
wants to merge 2 commits into from
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
30 changes: 17 additions & 13 deletions packages/next/build/webpack-config.ts
@@ -1,17 +1,15 @@
import { codeFrameColumns } from 'next/dist/compiled/babel/code-frame'
import ReactRefreshWebpackPlugin from '@next/react-refresh-utils/ReactRefreshWebpackPlugin'
import chalk from 'chalk'
import crypto from 'crypto'
import { readFileSync, realpathSync } from 'fs'
import chalk from 'chalk'
import { codeFrameColumns } from 'next/dist/compiled/babel/code-frame'
import semver from 'next/dist/compiled/semver'
// @ts-ignore No typings yet
import TerserPlugin from './webpack/plugins/terser-webpack-plugin/src/index.js'
import path from 'path'
import {
webpack,
isWebpack5,
init as initWebpack,
isWebpack5,
webpack,
} from 'next/dist/compiled/webpack/webpack'
import path from 'path'
import {
DOT_NEXT_ALIAS,
NEXT_PROJECT_ROOT,
Expand All @@ -24,13 +22,14 @@ import { Rewrite } from '../lib/load-custom-routes'
import { getTypeScriptConfiguration } from '../lib/typescript/getTypeScriptConfiguration'
import {
CLIENT_STATIC_FILES_RUNTIME_MAIN,
CLIENT_STATIC_FILES_RUNTIME_POLYFILLS,
CLIENT_STATIC_FILES_RUNTIME_POLYFILLS_SYMBOL,
CLIENT_STATIC_FILES_RUNTIME_WEBPACK,
REACT_LOADABLE_MANIFEST,
SERVERLESS_DIRECTORY,
SERVER_DIRECTORY,
} from '../next-server/lib/constants'
import { execOnce } from '../next-server/lib/utils'
import { NextConfig } from '../next-server/server/config'
import { findPageFile } from '../server/lib/find-page-file'
import { WebpackEntrypoints } from './entries'
import * as Log from './output/log'
Expand All @@ -44,6 +43,7 @@ import { __overrideCssConfiguration } from './webpack/config/blocks/css/override
import { pluginLoaderOptions } from './webpack/loaders/next-plugin-loader'
import BuildManifestPlugin from './webpack/plugins/build-manifest-plugin'
import ChunkNamesPlugin from './webpack/plugins/chunk-names-plugin'
import { CopyFilePlugin } from './webpack/plugins/copy-file-plugin'
import { CssMinimizerPlugin } from './webpack/plugins/css-minimizer-plugin'
import { JsConfigPathsPlugin } from './webpack/plugins/jsconfig-paths-plugin'
import { DropClientPage } from './webpack/plugins/next-drop-client-page-plugin'
Expand All @@ -53,14 +53,15 @@ import PagesManifestPlugin from './webpack/plugins/pages-manifest-plugin'
import { ProfilingPlugin } from './webpack/plugins/profiling-plugin'
import { ReactLoadablePlugin } from './webpack/plugins/react-loadable-plugin'
import { ServerlessPlugin } from './webpack/plugins/serverless-plugin'
// @ts-ignore No typings yet
import TerserPlugin from './webpack/plugins/terser-webpack-plugin/src/index.js'
import WebpackConformancePlugin, {
DuplicatePolyfillsConformanceCheck,
GranularChunksConformanceCheck,
MinificationConformanceCheck,
ReactSyncScriptsConformanceCheck,
} from './webpack/plugins/webpack-conformance-plugin'
import { WellKnownErrorsPlugin } from './webpack/plugins/wellknown-errors-plugin'
import { NextConfig } from '../next-server/server/config'

type ExcludesFalse = <T>(x: T | false) => x is T

Expand Down Expand Up @@ -298,10 +299,6 @@ export default async function getBaseWebpackConfig(
)
)
.replace(/\\/g, '/'),
[CLIENT_STATIC_FILES_RUNTIME_POLYFILLS]: path.join(
NEXT_PROJECT_ROOT_DIST_CLIENT,
'polyfills.js'
),
} as ClientEntries)
: undefined

Expand Down Expand Up @@ -1149,6 +1146,13 @@ export default async function getBaseWebpackConfig(
].filter(Boolean),
}),
new WellKnownErrorsPlugin(),
!isServer &&
new CopyFilePlugin({
source: require.resolve('@next/polyfill-nomodule'),
name: `static/chunks/polyfills${dev ? '' : '-[hash]'}.js`,
minimize: false,
info: { [CLIENT_STATIC_FILES_RUNTIME_POLYFILLS_SYMBOL]: 1 },
}),
].filter((Boolean as any) as ExcludesFalse),
}

Expand Down
35 changes: 20 additions & 15 deletions packages/next/build/webpack/plugins/build-manifest-plugin.ts
@@ -1,23 +1,23 @@
import devalue from 'next/dist/compiled/devalue'
import {
webpack,
isWebpack5,
sources,
webpack,
} from 'next/dist/compiled/webpack/webpack'
import { Rewrite } from '../../../lib/load-custom-routes'
import {
BUILD_MANIFEST,
CLIENT_STATIC_FILES_PATH,
CLIENT_STATIC_FILES_RUNTIME_AMP,
CLIENT_STATIC_FILES_RUNTIME_MAIN,
CLIENT_STATIC_FILES_RUNTIME_POLYFILLS,
CLIENT_STATIC_FILES_RUNTIME_POLYFILLS_SYMBOL,
CLIENT_STATIC_FILES_RUNTIME_REACT_REFRESH,
CLIENT_STATIC_FILES_RUNTIME_AMP,
} from '../../../next-server/lib/constants'
import { getSortedRoutes } from '../../../next-server/lib/router/utils'
import { BuildManifest } from '../../../next-server/server/get-page-files'
import getRouteFromEntrypoint from '../../../next-server/server/get-route-from-entrypoint'
import { traceFn, tracer } from '../../tracer'
import { ampFirstEntryNamesMap } from './next-drop-client-page-plugin'
import { Rewrite } from '../../../lib/load-custom-routes'
import { getSortedRoutes } from '../../../next-server/lib/router/utils'
import { tracer, traceFn } from '../../tracer'
import { spans } from './profiling-plugin'

type DeepMutable<T> = { -readonly [P in keyof T]: DeepMutable<T[P]> }
Expand Down Expand Up @@ -117,6 +117,12 @@ export default class BuildManifestPlugin {
ampFirstPages: [],
}

const compilationAssets: {
name: string
source: typeof sources.RawSource
info: object
}[] = compilation.getAssets()

const ampFirstEntryNames = ampFirstEntryNamesMap.get(compilation)
if (ampFirstEntryNames) {
for (const entryName of ampFirstEntryNames) {
Expand All @@ -135,14 +141,13 @@ export default class BuildManifestPlugin {
isJsFile
)

const polyfillChunk = namedChunks.get(
CLIENT_STATIC_FILES_RUNTIME_POLYFILLS
)

// Create a separate entry for polyfills
assetMap.polyfillFiles = getFilesArray(polyfillChunk?.files).filter(
isJsFile
)
assetMap.polyfillFiles = compilationAssets
.filter(
(p) =>
p.info && CLIENT_STATIC_FILES_RUNTIME_POLYFILLS_SYMBOL in p.info
)
.map((v) => v.name)
.filter(isJsFile)

const reactRefreshChunk = namedChunks.get(
CLIENT_STATIC_FILES_RUNTIME_REACT_REFRESH
Expand Down Expand Up @@ -233,7 +238,7 @@ export default class BuildManifestPlugin {
{
name: 'NextJsBuildManifest',
// @ts-ignore TODO: Remove ignore when webpack 5 is stable
stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS,
stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ANALYSE,
},
(assets: any) => {
this.createAssets(compiler, compilation, assets)
Expand Down
68 changes: 68 additions & 0 deletions packages/next/build/webpack/plugins/copy-file-plugin.ts
@@ -0,0 +1,68 @@
import { promises as fs } from 'fs'
import loaderUtils from 'next/dist/compiled/loader-utils'
import {
isWebpack5,
sources,
webpack,
} from 'next/dist/compiled/webpack/webpack'

const PLUGIN_NAME = 'CopyFilePlugin'

export class CopyFilePlugin {
private source: string
private name: string
private minimize: boolean
private info?: object

constructor({
source,
name,
minimize,
info,
}: {
source: string
name: string
minimize: boolean
info?: object
}) {
this.source = source
this.name = name
this.minimize = minimize
this.info = info
}

apply(compiler: webpack.Compiler) {
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
const hook = isWebpack5
? // @ts-ignore
compilation.hooks.processAssets
: compilation.hooks.additionalAssets
hook.tapPromise(
isWebpack5
? {
name: PLUGIN_NAME,
stage: this.minimize
? // @ts-ignore
webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL
: // @ts-ignore
webpack.Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING,
}
: PLUGIN_NAME,
async () => {
const content = await fs.readFile(this.source, 'utf8')

const file = loaderUtils.interpolateName(
{ resourcePath: this.source },
this.name,
{ content, context: compiler.context }
)

// @ts-ignore
compilation.emitAsset(file, new sources.RawSource(content), {
...this.info,
})
}
)
})
}
}
1 change: 0 additions & 1 deletion packages/next/client/polyfills.js

This file was deleted.

2 changes: 1 addition & 1 deletion packages/next/next-server/lib/constants.ts
Expand Up @@ -32,7 +32,7 @@ export const CLIENT_STATIC_FILES_RUNTIME_AMP = `amp`
// static/runtime/webpack.js
export const CLIENT_STATIC_FILES_RUNTIME_WEBPACK = `webpack`
// static/runtime/polyfills.js
export const CLIENT_STATIC_FILES_RUNTIME_POLYFILLS = `polyfills`
export const CLIENT_STATIC_FILES_RUNTIME_POLYFILLS_SYMBOL = Symbol(`polyfills`)
export const TEMPORARY_REDIRECT_STATUS = 307
export const PERMANENT_REDIRECT_STATUS = 308
export const STATIC_PROPS_ID = '__N_SSG'
Expand Down
2 changes: 1 addition & 1 deletion packages/next/package.json
Expand Up @@ -65,6 +65,7 @@
"@hapi/accept": "5.0.1",
"@next/env": "10.0.6-canary.6",
"@next/polyfill-module": "10.0.6-canary.6",
"@next/polyfill-nomodule": "10.0.6-canary.6",
"@next/react-dev-overlay": "10.0.6-canary.6",
"@next/react-refresh-utils": "10.0.6-canary.6",
"@opentelemetry/api": "0.14.0",
Expand Down Expand Up @@ -135,7 +136,6 @@
"@babel/preset-react": "7.12.10",
"@babel/preset-typescript": "7.12.7",
"@babel/types": "7.12.12",
"@next/polyfill-nomodule": "10.0.6-canary.6",
"@taskr/clear": "1.1.0",
"@taskr/esnext": "1.1.0",
"@taskr/watch": "1.1.0",
Expand Down
15 changes: 1 addition & 14 deletions packages/next/taskfile.js
Expand Up @@ -19,19 +19,6 @@ const bundleRequire = m.require
bundleRequire.resolve = (request, options) =>
Module._resolveFilename(request, m, false, options)

export async function next__polyfill_nomodule(task, opts) {
await task
.source(
opts.src ||
relative(__dirname, require.resolve('@next/polyfill-nomodule'))
)
.target('dist/build/polyfills')
}

export async function browser_polyfills(task) {
await task.parallel(['next__polyfill_nomodule'])
}

const externals = {
// Browserslist (post-css plugins)
browserslist: 'browserslist',
Expand Down Expand Up @@ -656,7 +643,7 @@ export async function path_to_regexp(task, opts) {
}

export async function precompile(task) {
await task.parallel(['browser_polyfills', 'path_to_regexp', 'copy_ncced'])
await task.parallel(['path_to_regexp', 'copy_ncced'])
}

// eslint-disable-next-line camelcase
Expand Down