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 inlining with configuration for v4 / v5 #20598

Merged
merged 80 commits into from Jan 14, 2021
Merged
Show file tree
Hide file tree
Changes from 74 commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
099cd30
webpack inlining
guybedford Dec 29, 2020
77ab633
taskfile changes
guybedford Dec 31, 2020
d9f0486
modify test
guybedford Dec 31, 2020
abc587f
webpack5 testing
guybedford Dec 31, 2020
876e327
webpack5 fixes
guybedford Dec 31, 2020
0e89f25
schema utils, sass loader
guybedford Dec 31, 2020
7167351
fixup: update compiled
guybedford Dec 31, 2020
17049fe
patch sass loader
guybedford Dec 31, 2020
47c4bb8
add schema utils pin to workaround yarn bug
guybedford Dec 31, 2020
effeda4
update fixture
guybedford Dec 31, 2020
d9907ea
fixup sass externalization
guybedford Dec 31, 2020
91169f1
compiled update
guybedford Dec 31, 2020
5ee9377
webpack nodelibs externalization
guybedford Dec 31, 2020
6f6a60b
revert fixture change
guybedford Dec 31, 2020
59033eb
webpack patch for hmr runtimes
guybedford Dec 31, 2020
6074374
new taskfile customEmits
guybedford Jan 1, 2021
5e2c63f
ncc update
guybedford Jan 10, 2021
16d7298
update compiled
guybedford Jan 10, 2021
d0502a8
ncc update, alias package virtualization
guybedford Jan 11, 2021
19f4b36
fixup schemautils external
guybedford Jan 11, 2021
3df41c4
custom emit updates
guybedford Jan 11, 2021
82bd8b6
custom patch
guybedford Jan 11, 2021
b498815
alias shadowing install
guybedford Jan 11, 2021
cdce288
remove alias shadowing
guybedford Jan 11, 2021
7226ee4
adjust build output
guybedford Jan 11, 2021
3838da9
Revert "remove alias shadowing"
guybedford Jan 11, 2021
e9f8583
fix custom patch with new ncc emit hook
guybedford Jan 11, 2021
49f2e5a
update compiled
guybedford Jan 11, 2021
7dd4509
live bindings fix
guybedford Jan 11, 2021
9418887
typing fixes
guybedford Jan 11, 2021
60740e3
update compiled
guybedford Jan 11, 2021
46e31ed
dummy commit
guybedford Jan 12, 2021
b345075
ncc update
guybedford Jan 12, 2021
9fefc93
include webpack5 hmr runtime sync in check-pre-compiled
guybedford Jan 12, 2021
f658e29
react-refresh-utils webpack dependency injection
guybedford Jan 12, 2021
9250c85
remove unnecessary lint flag
guybedford Jan 12, 2021
3b1264f
please typescript
guybedford Jan 12, 2021
33528a1
ts lint fixes
guybedford Jan 12, 2021
3f8f6c6
update eslint-plugin-react
guybedford Jan 12, 2021
b42f3e8
fixup pnpm test
guybedford Jan 12, 2021
f967685
fixup type check
guybedford Jan 12, 2021
82d88fc
export RawSource directly
guybedford Jan 12, 2021
d6e0924
Revert "export RawSource directly"
guybedford Jan 12, 2021
368228a
fixup live RawSource
guybedford Jan 12, 2021
1c90d86
fixup
guybedford Jan 12, 2021
a7ac6ad
fixup2
guybedford Jan 12, 2021
84fe939
reenable minification
guybedford Jan 12, 2021
ea5ab08
disable webpack minification
guybedford Jan 12, 2021
641732f
disable webpack5 font-optimization test
guybedford Jan 12, 2021
11ed7c9
try adding webpack dependency for next stats action
guybedford Jan 12, 2021
8baba2d
try azure build with cache disabled
guybedford Jan 12, 2021
1a4b77b
fixup cache
guybedford Jan 12, 2021
5a90373
try something
guybedford Jan 12, 2021
274f7b6
add some logging
guybedford Jan 12, 2021
3798270
fixup log
guybedford Jan 12, 2021
6760e64
Revert "try something"
guybedford Jan 12, 2021
555693c
Update stats package handling
ijjk Jan 12, 2021
ff4268d
Remove un-needed dep in stats app
ijjk Jan 12, 2021
7bfc3f3
retry azure
guybedford Jan 12, 2021
518e777
fixup windows pathing
guybedford Jan 12, 2021
7797a19
wat
guybedford Jan 12, 2021
c690c8f
move down log script
guybedford Jan 13, 2021
90d4d69
Update stats build command
ijjk Jan 12, 2021
5d65272
Update stats build command
ijjk Jan 12, 2021
be14afa
lint fix
guybedford Jan 13, 2021
08da70f
next log
guybedford Jan 13, 2021
7d1581d
next log
guybedford Jan 13, 2021
39565e4
next log
guybedford Jan 13, 2021
a67db9f
next log
guybedford Jan 13, 2021
767a43e
add extra yarn step
guybedford Jan 13, 2021
dd88ebe
maybe
guybedford Jan 13, 2021
ae8510c
fixup create require
guybedford Jan 13, 2021
fccbff6
fixup webpack5 sources ref
guybedford Jan 13, 2021
51b4cc5
remove stats config changes
guybedford Jan 13, 2021
af499a9
update compiled
guybedford Jan 13, 2021
1cba4e4
try remove build output changes
guybedford Jan 13, 2021
36614aa
lol
guybedford Jan 13, 2021
2656b39
Revert "try remove build output changes"
guybedford Jan 13, 2021
5619651
Update ncc target for webpack
ijjk Jan 13, 2021
4641bd3
Update compiled
ijjk Jan 13, 2021
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
1 change: 1 addition & 0 deletions .eslintignore
Expand Up @@ -4,6 +4,7 @@ node_modules
**/dist/**
examples/with-typescript-eslint-jest/**
examples/with-kea/**
packages/next/bundles/webpack/packages/*.runtime.js
packages/next/compiled/**/*
packages/react-refresh-utils/**/*.js
packages/react-dev-overlay/lib/**
Expand Down
17 changes: 14 additions & 3 deletions .github/actions/next-stats-action/src/prepare/repo-setup.js
Expand Up @@ -69,13 +69,17 @@ module.exports = (actionInfo) => {
for (const pkg of pkgs) {
const pkgPath = path.join(repoDir, 'packages', pkg)
const packedPkgPath = path.join(pkgPath, `${pkg}-packed.tgz`)
// pack the package with yarn
await exec(`cd ${pkgPath} && yarn pack -f ${pkg}-packed.tgz`)

const pkgDataPath = path.join(pkgPath, 'package.json')
const pkgData = require(pkgDataPath)
const { name } = pkgData
pkgDatas.set(name, { pkgDataPath, pkgData, packedPkgPath })
pkgDatas.set(name, {
pkgDataPath,
pkg,
pkgPath,
pkgData,
packedPkgPath,
})
pkgPaths.set(name, packedPkgPath)
}

Expand All @@ -93,6 +97,13 @@ module.exports = (actionInfo) => {
'utf8'
)
}

// wait to pack packages until after dependency paths have been updated
// to the correct versions
for (const pkgName of pkgDatas.keys()) {
const { pkg, pkgPath } = pkgDatas.get(pkgName)
await exec(`cd ${pkgPath} && yarn pack -f ${pkg}-packed.tgz`)
}
return pkgPaths
},
}
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/build_test_deploy.yml
Expand Up @@ -160,6 +160,7 @@ jobs:
NEXT_TELEMETRY_DISABLED: 1
NEXT_TEST_JOB: 1
HEADLESS: true
NEXT_WEBPACK5: 1

steps:
- uses: actions/checkout@v2
Expand All @@ -170,9 +171,6 @@ jobs:
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs-only' }}

- run: cat package.json | jq '.resolutions.webpack = "^5.11.1"' > package.json.tmp && mv package.json.tmp package.json
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs-only' }}

- run: cat package.json | jq '.resolutions.react = "^17.0.1"' > package.json.tmp && mv package.json.tmp package.json
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs-only' }}

Expand All @@ -185,7 +183,7 @@ jobs:
- run: yarn list webpack react react-dom
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs-only' }}

- run: xvfb-run node run-tests.js test/integration/{link-ref,production,basic,async-modules,font-optimization,ssr-ctx}/test/index.test.js test/acceptance/*.test.js
- run: xvfb-run node run-tests.js test/integration/{link-ref,production,basic,async-modules,ssr-ctx}/test/index.test.js test/acceptance/*.test.js
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs-only' }}

testFirefox:
Expand Down
3 changes: 2 additions & 1 deletion .prettierignore
Expand Up @@ -2,6 +2,7 @@ node_modules
**/.next/**
**/_next/**
**/dist/**
packages/next/bundles/webpack/packages/*.runtime.js
packages/next/compiled/**
packages/react-refresh-utils/**/*.js
packages/react-refresh-utils/**/*.d.ts
Expand All @@ -14,4 +15,4 @@ packages/next-codemod/transforms/__tests__/**/*
packages/next-codemod/**/*.js
packages/next-codemod/**/*.d.ts
packages/next-env/**/*.d.ts
test-timings.json
test-timings.json
1 change: 1 addition & 0 deletions .prettierignore_staged
Expand Up @@ -2,6 +2,7 @@
**/_next/**
**/dist/**
packages/next/compiled/**/*
packages/next/bundles/webpack/packages/*.runtime.js
lerna.json
packages/next-codemod/transforms/__testfixtures__/**/*
packages/next-codemod/transforms/__tests__/**/*
3 changes: 3 additions & 0 deletions check-pre-compiled.sh
@@ -1,5 +1,8 @@
#!/bin/bash

yarn --cwd packages/next/bundles
cp packages/next/bundles/node_modules/webpack5/lib/hmr/HotModuleReplacement.runtime.js packages/next/bundles/webpack/packages/
cp packages/next/bundles/node_modules/webpack5/lib/hmr/JavascriptHotModuleReplacement.runtime.js packages/next/bundles/webpack/packages/
yarn --cwd packages/next ncc-compiled

# Make sure to exit with 1 if there are changes after running ncc-compiled
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -74,7 +74,7 @@
"eslint": "6.8.0",
"eslint-plugin-import": "2.20.2",
"eslint-plugin-jest": "23.13.1",
"eslint-plugin-react": "7.18.0",
"eslint-plugin-react": "7.19.0",
"eslint-plugin-react-hooks": "2.3.0",
"execa": "2.0.3",
"express": "4.17.0",
Expand Down
14 changes: 10 additions & 4 deletions packages/next/build/compiler.ts
@@ -1,11 +1,14 @@
import webpack, { Stats, Configuration } from 'webpack'
import { webpack } from 'next/dist/compiled/webpack/webpack'

export type CompilerResult = {
errors: string[]
warnings: string[]
}

function generateStats(result: CompilerResult, stat: Stats): CompilerResult {
function generateStats(
result: CompilerResult,
stat: webpack.Stats
): CompilerResult {
const { errors, warnings } = stat.toJson('errors-warnings')
if (errors.length > 0) {
result.errors.push(...errors)
Expand All @@ -32,12 +35,15 @@ function closeCompiler(compiler: webpack.Compiler | webpack.MultiCompiler) {
}

export function runCompiler(
config: Configuration | Configuration[]
config: webpack.Configuration | webpack.Configuration[]
): Promise<CompilerResult> {
return new Promise((resolve, reject) => {
const compiler = webpack(config)
compiler.run(
(err: Error, statsOrMultiStats: { stats: Stats[] } | Stats) => {
(
err: Error,
statsOrMultiStats: { stats: webpack.Stats[] } | webpack.Stats
) => {
closeCompiler(compiler).then(() => {
if (err) {
const reason = err?.toString()
Expand Down
42 changes: 22 additions & 20 deletions packages/next/build/webpack-config.ts
Expand Up @@ -7,8 +7,11 @@ 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 from 'webpack'
import { Configuration } from 'webpack'
import {
webpack,
isWebpack5,
init as initWebpack,
} from 'next/dist/compiled/webpack/webpack'
import {
DOT_NEXT_ALIAS,
NEXT_PROJECT_ROOT,
Expand Down Expand Up @@ -61,23 +64,16 @@ import { NextConfig } from '../next-server/server/config'

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

const isWebpack5 = parseInt(webpack.version!) === 5

if (isWebpack5 && semver.lt(webpack.version!, '5.11.1')) {
Log.error(
`webpack 5 version must be greater than v5.11.1 to work properly with Next.js, please upgrade to continue!\nSee more info here: https://err.sh/next.js/invalid-webpack-5-version`
)
process.exit(1)
}

const devtoolRevertWarning = execOnce((devtool: Configuration['devtool']) => {
console.warn(
chalk.yellow.bold('Warning: ') +
chalk.bold(`Reverting webpack devtool to '${devtool}'.\n`) +
'Changing the webpack devtool in development mode will cause severe performance regressions.\n' +
'Read more: https://err.sh/next.js/improper-devtool'
)
})
const devtoolRevertWarning = execOnce(
(devtool: webpack.Configuration['devtool']) => {
console.warn(
chalk.yellow.bold('Warning: ') +
chalk.bold(`Reverting webpack devtool to '${devtool}'.\n`) +
'Changing the webpack devtool in development mode will cause severe performance regressions.\n' +
'Read more: https://err.sh/next.js/improper-devtool'
)
}
)

function parseJsonFile(filePath: string) {
const JSON5 = require('next/dist/compiled/json5')
Expand Down Expand Up @@ -208,6 +204,12 @@ export default async function getBaseWebpackConfig(
rewrites: Rewrite[]
}
): Promise<webpack.Configuration> {
initWebpack(
config.future?.webpack5 ||
(config.future?.webpack5 !== false &&
Number(process.env.NEXT_WEBPACK5) > 0)
)

let plugins: PluginMetaData[] = []
let babelPresetPlugins: { dir: string; config: any }[] = []

Expand Down Expand Up @@ -909,7 +911,7 @@ export default async function getBaseWebpackConfig(
].filter(Boolean),
},
plugins: [
hasReactRefresh && new ReactRefreshWebpackPlugin(),
hasReactRefresh && new ReactRefreshWebpackPlugin(webpack),
// Makes sure `Buffer` and `process` are polyfilled in client-side bundles (same behavior as webpack 4)
isWebpack5 &&
!isServer &&
Expand Down
4 changes: 2 additions & 2 deletions packages/next/build/webpack/config/blocks/base.ts
@@ -1,13 +1,13 @@
import isWslBoolean from 'next/dist/compiled/is-wsl'
import curry from 'next/dist/compiled/lodash.curry'
import { Configuration } from 'webpack'
import { webpack } from 'next/dist/compiled/webpack/webpack'
import { ConfigurationContext } from '../utils'

const isWindows = process.platform === 'win32' || isWslBoolean

export const base = curry(function base(
ctx: ConfigurationContext,
config: Configuration
config: webpack.Configuration
) {
config.mode = ctx.isDevelopment ? 'development' : 'production'
config.name = ctx.isServer ? 'server' : 'client'
Expand Down
6 changes: 3 additions & 3 deletions packages/next/build/webpack/config/blocks/css/index.ts
@@ -1,6 +1,6 @@
import curry from 'next/dist/compiled/lodash.curry'
import path from 'path'
import webpack, { Configuration } from 'webpack'
import { webpack } from 'next/dist/compiled/webpack/webpack'
import MiniCssExtractPlugin from '../../../plugins/mini-css-extract-plugin'
import { loader, plugin } from '../../helpers'
import { ConfigurationContext, ConfigurationFn, pipe } from '../../utils'
Expand All @@ -26,7 +26,7 @@ const regexSassModules = /\.module\.(scss|sass)$/

export const css = curry(async function css(
ctx: ConfigurationContext,
config: Configuration
config: webpack.Configuration
) {
const {
prependData: sassPrependData,
Expand All @@ -38,7 +38,7 @@ export const css = curry(async function css(
// First, process files with `sass-loader`: this inlines content, and
// compiles away the proprietary syntax.
{
loader: require.resolve('sass-loader'),
loader: require.resolve('next/dist/compiled/sass-loader'),
options: {
// Source maps are required so that `resolve-url-loader` can locate
// files original to their source directory.
Expand Down
@@ -1,4 +1,4 @@
import webpack from 'webpack'
import { webpack } from 'next/dist/compiled/webpack/webpack'
import MiniCssExtractPlugin from '../../../../plugins/mini-css-extract-plugin'

export function getClientStyleLoader({
Expand Down
@@ -1,6 +1,6 @@
import loaderUtils from 'loader-utils'
import path from 'path'
import webpack from 'webpack'
import { webpack } from 'next/dist/compiled/webpack/webpack'

const regexLikeIndexModule = /(?<!pages[\\/])index\.module\.(scss|sass|css)$/

Expand Down
@@ -1,5 +1,5 @@
import { AcceptedPlugin } from 'postcss'
import webpack from 'webpack'
import { webpack } from 'next/dist/compiled/webpack/webpack'
import { ConfigurationContext } from '../../../utils'
import { getClientStyleLoader } from './client'
import { cssFileResolve } from './file-resolve'
Expand Down
@@ -1,5 +1,5 @@
import { AcceptedPlugin } from 'postcss'
import webpack from 'webpack'
import { webpack } from 'next/dist/compiled/webpack/webpack'
import { ConfigurationContext } from '../../../utils'
import { getClientStyleLoader } from './client'
import { cssFileResolve } from './file-resolve'
Expand Down
@@ -1,14 +1,14 @@
import { Configuration, RuleSetRule } from 'webpack'
import { webpack } from 'next/dist/compiled/webpack/webpack'
import { getPostCssPlugins } from './plugins'

export async function __overrideCssConfiguration(
rootDirectory: string,
isProduction: boolean,
config: Configuration
config: webpack.Configuration
) {
const postCssPlugins = await getPostCssPlugins(rootDirectory, isProduction)

function patch(rule: RuleSetRule) {
function patch(rule: webpack.RuleSetRule) {
if (
rule.options &&
typeof rule.options === 'object' &&
Expand Down
15 changes: 9 additions & 6 deletions packages/next/build/webpack/config/helpers.ts
@@ -1,9 +1,9 @@
import curry from 'next/dist/compiled/lodash.curry'
import { Configuration, Plugin, RuleSetRule } from 'webpack'
import { webpack } from 'next/dist/compiled/webpack/webpack'

export const loader = curry(function loader(
rule: RuleSetRule,
config: Configuration
rule: webpack.RuleSetRule,
config: webpack.Configuration
) {
if (!config.module) {
config.module = { rules: [] }
Expand All @@ -22,8 +22,8 @@ export const loader = curry(function loader(
})

export const unshiftLoader = curry(function unshiftLoader(
rule: RuleSetRule,
config: Configuration
rule: webpack.RuleSetRule,
config: webpack.Configuration
) {
if (!config.module) {
config.module = { rules: [] }
Expand All @@ -41,7 +41,10 @@ export const unshiftLoader = curry(function unshiftLoader(
return config
})

export const plugin = curry(function plugin(p: Plugin, config: Configuration) {
export const plugin = curry(function plugin(
p: webpack.Plugin,
config: webpack.Configuration
) {
if (!config.plugins) {
config.plugins = []
}
Expand Down
2 changes: 1 addition & 1 deletion packages/next/build/webpack/config/index.ts
@@ -1,4 +1,4 @@
import webpack from 'webpack'
import { webpack } from 'next/dist/compiled/webpack/webpack'
import { NextConfig } from '../../../next-server/server/config'
import { base } from './blocks/base'
import { css } from './blocks/css'
Expand Down
2 changes: 1 addition & 1 deletion packages/next/build/webpack/config/utils.ts
@@ -1,4 +1,4 @@
import webpack from 'webpack'
import { webpack } from 'next/dist/compiled/webpack/webpack'
import { NextConfig } from '../../../next-server/server/config'

export type ConfigurationContext = {
Expand Down
4 changes: 2 additions & 2 deletions packages/next/build/webpack/loaders/error-loader.ts
@@ -1,9 +1,9 @@
import chalk from 'chalk'
import loaderUtils from 'loader-utils'
import path from 'path'
import { loader } from 'webpack'
import { webpack } from 'next/dist/compiled/webpack/webpack'

const ErrorLoader: loader.Loader = function () {
const ErrorLoader: webpack.loader.Loader = function () {
const options = loaderUtils.getOptions(this) || {}

const { reason = 'An unknown error has occurred' } = options
Expand Down
4 changes: 2 additions & 2 deletions packages/next/build/webpack/loaders/next-plugin-loader.ts
@@ -1,4 +1,4 @@
import { loader } from 'webpack'
import { webpack } from 'next/dist/compiled/webpack/webpack'
import { parse } from 'querystring'
import { PluginMetaData, getPluginId } from '../../plugins/collect-plugins'

Expand All @@ -12,7 +12,7 @@ export const pluginLoaderOptions: {
plugins: [],
}

const nextPluginLoader: loader.Loader = function () {
const nextPluginLoader: webpack.loader.Loader = function () {
const { middleware }: NextPluginLoaderQuery =
typeof this.query === 'string' ? parse(this.query.substr(1)) : this.query

Expand Down
Expand Up @@ -2,7 +2,7 @@ import devalue from 'next/dist/compiled/devalue'
import escapeRegexp from 'next/dist/compiled/escape-string-regexp'
import { join } from 'path'
import { parse } from 'querystring'
import { loader } from 'webpack'
import { webpack } from 'next/dist/compiled/webpack/webpack'
import { API_ROUTE } from '../../../../lib/constants'
import { isDynamicRoute } from '../../../../next-server/lib/router/utils'
import { __ApiPreviewProps } from '../../../../next-server/server/api-utils'
Expand Down Expand Up @@ -33,7 +33,7 @@ export type ServerlessLoaderQuery = {
i18n: string
}

const nextServerlessLoader: loader.Loader = function () {
const nextServerlessLoader: webpack.loader.Loader = function () {
const span = tracer.startSpan('next-serverless-loader')
return traceFn(span, () => {
const {
Expand Down