Skip to content

Commit

Permalink
Revert "Ensure mangling is disabled for dev runtime builds (#75297)"
Browse files Browse the repository at this point in the history
This reverts commit 98b0700.
  • Loading branch information
ijjk committed Jan 29, 2025
1 parent 4273581 commit 803651f
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 11 deletions.
2 changes: 1 addition & 1 deletion contributing/core/vscode-debugger.md
Original file line number Diff line number Diff line change
Expand Up @@ -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_NO_MANGLE=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_EVAL_SOURCE_MAPS=1`. This is automatically applied when using `pnpm dev`.
12 changes: 3 additions & 9 deletions packages/next/next_runtime.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const rspack = require('@rspack/core')
const webpack = require('@rspack/core')
const path = require('path')
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
const DevToolsIgnoreListPlugin = require('./webpack-plugins/devtools-ignore-list-plugin')
Expand Down Expand Up @@ -172,17 +172,11 @@ module.exports = ({ dev, turbo, bundleType, experimental }) => {
moduleIds: 'named',
minimize: true,
concatenateModules: true,
minimizer: [
new rspack.SwcJsMinimizerRspackPlugin({
minimizerOptions: {
mangle: dev || process.env.NEXT_SERVER_NO_MANGLE ? false : true,
},
}),
],
minimizer: [new webpack.SwcJsMinimizerRspackPlugin()],
},
plugins: [
new DevToolsIgnoreListPlugin({ shouldIgnorePath }),
new rspack.DefinePlugin({
new webpack.DefinePlugin({
'typeof window': JSON.stringify('undefined'),
'process.env.NEXT_MINIMAL': JSON.stringify('true'),
'this.serverOptions.experimentalTestProxy': JSON.stringify(false),
Expand Down
2 changes: 1 addition & 1 deletion packages/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
"next": "./dist/bin/next"
},
"scripts": {
"dev": "cross-env NEXT_SERVER_NO_MANGLE=1 taskr",
"dev": "taskr",
"release": "taskr release",
"build": "pnpm release",
"prepublishOnly": "cd ../../ && turbo run build",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
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,
Expand Down
219 changes: 219 additions & 0 deletions packages/next/webpack-plugins/eval-source-map-dev-tool-plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
/*
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)
}
)
}
}
)
}
}

0 comments on commit 803651f

Please sign in to comment.