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

Bypass webpack compilation for precompiled @next/polyfills-nomodule #27596

Merged
Merged
Show file tree
Hide file tree
Changes from 2 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
19 changes: 14 additions & 5 deletions packages/next/build/webpack-config.ts
Expand Up @@ -19,7 +19,7 @@ import { getTypeScriptConfiguration } from '../lib/typescript/getTypeScriptConfi
import {
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_WEBPACK,
REACT_LOADABLE_MANIFEST,
Expand Down Expand Up @@ -52,6 +52,7 @@ import WebpackConformancePlugin, {
} from './webpack/plugins/webpack-conformance-plugin'
import { WellKnownErrorsPlugin } from './webpack/plugins/wellknown-errors-plugin'
import { regexLikeCss } from './webpack/config/blocks/css'
import { CopyFilePlugin } from './webpack/plugins/copy-file-plugin'

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

Expand Down Expand Up @@ -364,10 +365,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 @@ -1324,6 +1321,18 @@ export default async function getBaseWebpackConfig(
].filter(Boolean),
}),
new WellKnownErrorsPlugin(),
!isServer &&
new CopyFilePlugin({
filePath: require.resolve('./polyfills/polyfill-nomodule'),
cacheKey: process.env.__NEXT_VERSION as string,
name: `static/chunks/polyfills${dev ? '' : '-[hash]'}.js`,
minimize: false,
info: {
[CLIENT_STATIC_FILES_RUNTIME_POLYFILLS_SYMBOL]: 1,
// This file is already minified
minimized: true,
},
}),
].filter((Boolean as any) as ExcludesFalse),
}

Expand Down
24 changes: 19 additions & 5 deletions packages/next/build/webpack/plugins/build-manifest-plugin.ts
Expand Up @@ -8,7 +8,7 @@ import {
BUILD_MANIFEST,
CLIENT_STATIC_FILES_PATH,
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 '../../../shared/lib/constants'
Expand Down Expand Up @@ -146,9 +146,24 @@ export default class BuildManifestPlugin {
getEntrypointFiles(entrypoints.get(CLIENT_STATIC_FILES_RUNTIME_MAIN))
)

assetMap.polyfillFiles = getEntrypointFiles(
entrypoints.get(CLIENT_STATIC_FILES_RUNTIME_POLYFILLS)
).filter((file) => !mainFiles.has(file))
const compilationAssets: {
name: string
source: typeof sources.RawSource
info: object
}[] = compilation.getAssets()

assetMap.polyfillFiles = compilationAssets
.filter((p) => {
// Ensure only .js files are passed through
if (!p.name.endsWith('.js')) {
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to think about .cjs or .mjs here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not currently, if an output like that is added then yes.

return false
}

return (
p.info && CLIENT_STATIC_FILES_RUNTIME_POLYFILLS_SYMBOL in p.info
)
})
.map((v) => v.name)

assetMap.devFiles = getEntrypointFiles(
entrypoints.get(CLIENT_STATIC_FILES_RUNTIME_REACT_REFRESH)
Expand All @@ -160,7 +175,6 @@ export default class BuildManifestPlugin {

const systemEntrypoints = new Set([
CLIENT_STATIC_FILES_RUNTIME_MAIN,
CLIENT_STATIC_FILES_RUNTIME_POLYFILLS,
CLIENT_STATIC_FILES_RUNTIME_REACT_REFRESH,
CLIENT_STATIC_FILES_RUNTIME_AMP,
])
Expand Down
89 changes: 89 additions & 0 deletions packages/next/build/webpack/plugins/copy-file-plugin.ts
@@ -0,0 +1,89 @@
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 filePath: string
private name: string
private cacheKey: string
private info?: object

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

apply(compiler: webpack.Compiler) {
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation: any) => {
const cache = isWebpack5 ? compilation.getCache('CopyFilePlugin') : null
const hook = isWebpack5
? // @ts-ignore
compilation.hooks.processAssets
: compilation.hooks.additionalAssets
hook.tapPromise(
isWebpack5
? {
name: PLUGIN_NAME,
// @ts-ignore TODO: Remove ignore when webpack 5 is stable
stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS,
}
: PLUGIN_NAME,
async () => {
if (cache) {
const cachedResult = await cache.getPromise(
this.filePath,
this.cacheKey
)
if (cachedResult) {
const { file, source } = cachedResult
compilation.emitAsset(file, source, {
...this.info,
})
return
}
}
const content = await fs.readFile(this.filePath, 'utf8')

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

const source = new sources.RawSource(content)

if (cache) {
await cache.storePromise(this.filePath, this.cacheKey, {
file,
source,
})
}

// @ts-ignore
compilation.emitAsset(file, source, {
...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/shared/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