From 98b0700e9746387ce63ac715d300be82100dce55 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Fri, 24 Jan 2025 16:34:44 -0800 Subject: [PATCH] Ensure mangling is disabled for dev runtime builds (#75297) Just ensures we keep mangling behavior prior to https://github.com/vercel/next.js/pull/75294 --------- Co-authored-by: Hendrik Liebau --- contributing/core/vscode-debugger.md | 2 +- packages/next/next_runtime.config.js | 12 +- packages/next/package.json | 2 +- .../eval-source-map-dev-tool-plugin.ts | 1 - .../eval-source-map-dev-tool-plugin.js | 219 ------------------ 5 files changed, 11 insertions(+), 225 deletions(-) delete mode 100644 packages/next/webpack-plugins/eval-source-map-dev-tool-plugin.js diff --git a/contributing/core/vscode-debugger.md b/contributing/core/vscode-debugger.md index 22be0b556b33d..52c9033e7823b 100644 --- a/contributing/core/vscode-debugger.md +++ b/contributing/core/vscode-debugger.md @@ -24,4 +24,4 @@ To see the changes you make to the Next.js codebase during development, you can When developing/debugging Next.js, you can set breakpoints anywhere in the `packages/next` source code that will stop the debugger at certain locations so you can examine the behavior. Read more about [breakpoints in the VS Code documentation](https://code.visualstudio.com/docs/nodejs/nodejs-debugging#_breakpoints). -To ensure that the original names are displayed in the "Variables" section, build the Next.js source code with `NEXT_SERVER_EVAL_SOURCE_MAPS=1`. This is automatically applied when using `pnpm dev`. +To ensure that the original names are displayed in the "Variables" section, build the Next.js source code with `NEXT_SERVER_NO_MANGLE=1`. This is automatically applied when using `pnpm dev`. diff --git a/packages/next/next_runtime.config.js b/packages/next/next_runtime.config.js index 8fe41ef4e0ae8..03490803301c3 100644 --- a/packages/next/next_runtime.config.js +++ b/packages/next/next_runtime.config.js @@ -1,4 +1,4 @@ -const webpack = require('@rspack/core') +const rspack = require('@rspack/core') const path = require('path') const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer') const DevToolsIgnoreListPlugin = require('./webpack-plugins/devtools-ignore-list-plugin') @@ -172,11 +172,17 @@ module.exports = ({ dev, turbo, bundleType, experimental }) => { moduleIds: 'named', minimize: true, concatenateModules: true, - minimizer: [new webpack.SwcJsMinimizerRspackPlugin()], + minimizer: [ + new rspack.SwcJsMinimizerRspackPlugin({ + minimizerOptions: { + mangle: dev || process.env.NEXT_SERVER_NO_MANGLE ? false : true, + }, + }), + ], }, plugins: [ new DevToolsIgnoreListPlugin({ shouldIgnorePath }), - new webpack.DefinePlugin({ + new rspack.DefinePlugin({ 'typeof window': JSON.stringify('undefined'), 'process.env.NEXT_MINIMAL': JSON.stringify('true'), 'this.serverOptions.experimentalTestProxy': JSON.stringify(false), diff --git a/packages/next/package.json b/packages/next/package.json index 4fcf8690c1f3f..05d72c13d0902 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -80,7 +80,7 @@ "next": "./dist/bin/next" }, "scripts": { - "dev": "taskr", + "dev": "cross-env NEXT_SERVER_NO_MANGLE=1 taskr", "release": "taskr release", "build": "pnpm release", "prepublishOnly": "cd ../../ && turbo run build", diff --git a/packages/next/src/build/webpack/plugins/eval-source-map-dev-tool-plugin.ts b/packages/next/src/build/webpack/plugins/eval-source-map-dev-tool-plugin.ts index 8d46d2c2b7b8e..ae0e7051dfc9e 100644 --- a/packages/next/src/build/webpack/plugins/eval-source-map-dev-tool-plugin.ts +++ b/packages/next/src/build/webpack/plugins/eval-source-map-dev-tool-plugin.ts @@ -3,7 +3,6 @@ Author Tobias Koppers @sokra Forked to add support for `ignoreList`. - Keep in sync with packages/next/webpack-plugins/eval-source-map-dev-tool-plugin.js */ import { type webpack, diff --git a/packages/next/webpack-plugins/eval-source-map-dev-tool-plugin.js b/packages/next/webpack-plugins/eval-source-map-dev-tool-plugin.js deleted file mode 100644 index bc1d83d9504ed..0000000000000 --- a/packages/next/webpack-plugins/eval-source-map-dev-tool-plugin.js +++ /dev/null @@ -1,219 +0,0 @@ -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra - - Forked to add support for `ignoreList`. - Keep in sync with packages/next/webpack-plugins/eval-source-map-dev-tool-plugin.js - */ -// eslint-disable-next-line import/no-extraneous-dependencies -- this is a dev-only file -const ConcatenatedModule = require('webpack/lib/optimize/ConcatenatedModule') -// eslint-disable-next-line import/no-extraneous-dependencies -- this is a dev-only file -const { makePathsAbsolute } = require('webpack/lib/util/identifier') -// eslint-disable-next-line import/no-extraneous-dependencies -- this is a dev-only file -const ModuleFilenameHelpers = require('webpack/lib/ModuleFilenameHelpers') -// eslint-disable-next-line import/no-extraneous-dependencies -- this is a dev-only file -const NormalModule = require('webpack/lib/NormalModule') -// eslint-disable-next-line import/no-extraneous-dependencies -- this is a dev-only file -const RuntimeGlobals = require('webpack/lib/RuntimeGlobals') -// eslint-disable-next-line import/no-extraneous-dependencies -- this is a dev-only file -const SourceMapDevToolModuleOptionsPlugin = require('webpack/lib/SourceMapDevToolModuleOptionsPlugin') - -const cache = new WeakMap() -const devtoolWarningMessage = `/* - * ATTENTION: An "eval-source-map" devtool has been used. - * This devtool is neither made for production nor for readable output files. - * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools. - * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) - * or disable the default devtool with "devtool: false". - * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). - */ -` - -// @ts-expect-error -- can't compare `string` with `number` in `version`Ï - -// Fork of webpack's EvalSourceMapDevToolPlugin with support for adding `ignoreList`. -// https://github.com/webpack/webpack/blob/e237b580e2bda705c5ab39973f786f7c5a7026bc/lib/EvalSourceMapDevToolPlugin.js#L37 -module.exports = class EvalSourceMapDevToolPlugin { - sourceMapComment - moduleFilenameTemplate - namespace - options - shouldIgnorePath - - /** - * @param {SourceMapDevToolPluginOptions|string} inputOptions Options object - */ - constructor(inputOptions) { - let options - if (typeof inputOptions === 'string') { - options = { - append: inputOptions, - } - } else { - options = inputOptions - } - this.sourceMapComment = - options.append && typeof options.append !== 'function' - ? options.append - : '//# sourceURL=[module]\n//# sourceMappingURL=[url]' - this.moduleFilenameTemplate = - options.moduleFilenameTemplate || - 'webpack://[namespace]/[resource-path]?[hash]' - this.namespace = options.namespace || '' - this.options = options - - // fork - this.shouldIgnorePath = options.shouldIgnorePath ?? (() => false) - } - - /** - * Apply the plugin - * @param compiler the compiler instance - */ - apply(compiler) { - const options = this.options - compiler.hooks.compilation.tap( - 'NextJSEvalSourceMapDevToolPlugin', - (compilation) => { - const { JavascriptModulesPlugin } = compiler.webpack.javascript - const { RawSource, ConcatSource } = compiler.webpack.sources - const devtoolWarning = new RawSource(devtoolWarningMessage) - const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation) - new SourceMapDevToolModuleOptionsPlugin(options).apply(compilation) - const matchModule = ModuleFilenameHelpers.matchObject.bind( - ModuleFilenameHelpers, - options - ) - hooks.renderModuleContent.tap( - 'NextJSEvalSourceMapDevToolPlugin', - (source, m, { chunk, runtimeTemplate, chunkGraph }) => { - const cachedSource = cache.get(source) - if (cachedSource !== undefined) { - return cachedSource - } - const result = (r) => { - cache.set(source, r) - return r - } - if (m instanceof NormalModule) { - const module = m - if (!matchModule(module.resource)) { - return result(source) - } - } else if (m instanceof ConcatenatedModule) { - const concatModule = m - if (concatModule.rootModule instanceof NormalModule) { - const module = concatModule.rootModule - if (!matchModule(module.resource)) { - return result(source) - } - } else { - return result(source) - } - } else { - return result(source) - } - const namespace = compilation.getPath(this.namespace, { - chunk, - }) - let sourceMap - let content - if (source.sourceAndMap) { - const sourceAndMap = source.sourceAndMap(options) - sourceMap = sourceAndMap.map - content = sourceAndMap.source - } else { - sourceMap = source.map(options) - content = source.source() - } - if (!sourceMap) { - return result(source) - } - - // Clone (flat) the sourcemap to ensure that the mutations below do not persist. - sourceMap = { - ...sourceMap, - } - const context = compiler.options.context - const root = compiler.root - const modules = sourceMap.sources.map((sourceMapSource) => { - if (!sourceMapSource.startsWith('webpack://')) - return sourceMapSource - sourceMapSource = makePathsAbsolute( - context, - sourceMapSource.slice(10), - root - ) - const module = compilation.findModule(sourceMapSource) - return module || sourceMapSource - }) - let moduleFilenames = modules.map((module) => - ModuleFilenameHelpers.createFilename( - module, - { - moduleFilenameTemplate: this.moduleFilenameTemplate, - namespace, - }, - { - requestShortener: runtimeTemplate.requestShortener, - chunkGraph, - hashFunction: compilation.outputOptions.hashFunction, - } - ) - ) - moduleFilenames = ModuleFilenameHelpers.replaceDuplicates( - moduleFilenames, - (filename, _i, n) => { - for (let j = 0; j < n; j++) filename += '*' - return filename - } - ) - sourceMap.sources = moduleFilenames - sourceMap.ignoreList = [] - for (let index = 0; index < moduleFilenames.length; index++) { - if (this.shouldIgnorePath(moduleFilenames[index])) { - sourceMap.ignoreList.push(index) - } - } - if (options.noSources) { - sourceMap.sourcesContent = undefined - } - sourceMap.sourceRoot = options.sourceRoot || '' - const moduleId = /** @type {ModuleId} */ chunkGraph.getModuleId(m) - if (moduleId) { - sourceMap.file = - typeof moduleId === 'number' ? `${moduleId}.js` : moduleId - } - const footer = `${this.sourceMapComment.replace(/\[url\]/g, `data:application/json;charset=utf-8;base64,${Buffer.from(JSON.stringify(sourceMap), 'utf8').toString('base64')}`)}\n//# sourceURL=webpack-internal:///${moduleId}\n` // workaround for chrome bug - - return result( - new RawSource( - `eval(${compilation.outputOptions.trustedTypes ? `${RuntimeGlobals.createScript}(${JSON.stringify(content + footer)})` : JSON.stringify(content + footer)});` - ) - ) - } - ) - hooks.inlineInRuntimeBailout.tap( - 'EvalDevToolModulePlugin', - () => 'the eval-source-map devtool is used.' - ) - hooks.render.tap( - 'EvalSourceMapDevToolPlugin', - (source) => new ConcatSource(devtoolWarning, source) - ) - hooks.chunkHash.tap('EvalSourceMapDevToolPlugin', (_chunk, hash) => { - hash.update('EvalSourceMapDevToolPlugin') - hash.update('2') - }) - if (compilation.outputOptions.trustedTypes) { - compilation.hooks.additionalModuleRuntimeRequirements.tap( - 'EvalSourceMapDevToolPlugin', - (_module, set, _context) => { - set.add(RuntimeGlobals.createScript) - } - ) - } - } - ) - } -}