mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-01 01:38:07 +08:00
Using a regex to denote all properties that can be mangled, we can mangle all private class fields. Since we know that private class fields are only accessed in a class, we know that terser can safely mangle the properties in a single rolled up bundle. Mangling of private class fields on `core/sdk/` has shown an expected 8.6% bundle size improvement. R=aerotwist@chromium.org Doc: https://docs.google.com/document/d/13yeJuvIq8JYFXSOsjRgcXzQVrIviJmukvxj27rn1Ab8/preview Bug: 1222126 Change-Id: Id3bb3f4ff4af295eddaa4bce3bff4fabe4d87794 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2975285 Commit-Queue: Tim van der Lippe <tvanderlippe@chromium.org> Auto-Submit: Tim van der Lippe <tvanderlippe@chromium.org> Reviewed-by: Paul Lewis <aerotwist@chromium.org>
151 lines
5.5 KiB
JavaScript
151 lines
5.5 KiB
JavaScript
// Copyright 2020 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// @ts-check
|
|
|
|
import {defaultStrategy} from 'minify-html-literals/src/strategy'; // eslint-disable-line rulesdir/es_modules_import
|
|
import * as path from 'path';
|
|
import minifyHTML from 'rollup-plugin-minify-html-template-literals';
|
|
import {terser} from 'rollup-plugin-terser';
|
|
|
|
/**
|
|
* `path.dirname` does not include trailing slashes. If we would always
|
|
* use `path.dirname` and then later perform comparisons on the paths that
|
|
* it returns, we could run into false positives. For example, given the
|
|
* the following two paths:
|
|
*
|
|
* front_end/timeline_model/TimelineModel.js
|
|
* front_end/timeline/Timeline.js
|
|
*
|
|
* And that would have the following values for `path.dirname`:
|
|
*
|
|
* front_end/timeline_model
|
|
* front_end/timeline
|
|
*
|
|
* If we would do a simple `.startswith` on the `path.dirname` of both of
|
|
* these paths, then the first path would start with the dirname of the
|
|
* second. However, they *are* part of different folders. To fix that problem,
|
|
* we need to force a path separator after each folder. That makes sure we
|
|
* and up with the following comparison of path dirnames:
|
|
*
|
|
* front_end/timeline_model/
|
|
* front_end/timeline/
|
|
*
|
|
* Now, the first path does *not* start with the second one, as expected.
|
|
*
|
|
* @param {string} file
|
|
* @return {string}
|
|
*/
|
|
function dirnameWithSeparator(file) {
|
|
return path.dirname(file) + path.sep;
|
|
}
|
|
|
|
/**
|
|
* @type {import("minify-html-literals").Strategy<import("html-minifier").Options, unknown>}
|
|
*/
|
|
const minifyHTMLStrategy = {
|
|
getPlaceholder() {
|
|
return 'TEMPLATE_EXPRESSION';
|
|
},
|
|
combineHTMLStrings(parts, placeholder) {
|
|
return defaultStrategy.combineHTMLStrings(parts, placeholder);
|
|
},
|
|
minifyHTML(html, options) {
|
|
return defaultStrategy.minifyHTML(html, options);
|
|
},
|
|
minifyCSS(css, options) {
|
|
return defaultStrategy.minifyCSS(css, options);
|
|
},
|
|
splitHTMLByPlaceholder(html, placeholder) {
|
|
return defaultStrategy.splitHTMLByPlaceholder(html, placeholder);
|
|
}
|
|
};
|
|
|
|
/** @type {function({configDCHECK: boolean}): import("rollup").MergedRollupOptions} */
|
|
// eslint-disable-next-line import/no-default-export
|
|
export default commandLineArgs => ({
|
|
treeshake: false,
|
|
context: 'self',
|
|
output: [{
|
|
format: 'esm',
|
|
}],
|
|
plugins: [
|
|
minifyHTML({
|
|
options: {
|
|
strategy: minifyHTMLStrategy,
|
|
minifyOptions: {
|
|
minifyCSS: false,
|
|
removeOptionalTags: true,
|
|
},
|
|
},
|
|
}),
|
|
terser({
|
|
compress: {
|
|
pure_funcs: commandLineArgs.configDCHECK ? ['Platform.DCHECK'] : [],
|
|
},
|
|
mangle: {
|
|
properties: {
|
|
regex: /^#\w+/,
|
|
},
|
|
},
|
|
}),
|
|
{
|
|
name: 'devtools-plugin',
|
|
resolveId(source, importer) {
|
|
if (!importer) {
|
|
return null;
|
|
}
|
|
const currentDirectory = path.normalize(dirnameWithSeparator(importer));
|
|
const importedFilelocation = path.normalize(path.join(currentDirectory, source));
|
|
const importedFileDirectory = dirnameWithSeparator(importedFilelocation);
|
|
|
|
// Generated files are part of other directories, as they are only imported once
|
|
if (path.basename(importedFileDirectory) === 'generated') {
|
|
return null;
|
|
}
|
|
|
|
// An import is considered external (and therefore a separate
|
|
// bundle) if its filename matches its immediate parent's folder
|
|
// name (without the extension). For example:
|
|
// import * as Components from './components/components.js' = external
|
|
// import * as UI from '../ui/ui.js' = external
|
|
// import * as LitHtml from '../third_party/lit-html/lit-html.js' = external
|
|
// import {DataGrid} from './components/DataGrid.js' = not external
|
|
// import * as Components from './components/foo.js' = not external
|
|
|
|
// Note that we can't do a simple check for only `third_party`, as in Chromium
|
|
// our full path is `third_party/devtools-frontend/src/`, which thus *always*
|
|
// includes third_party. It also not possible to use the current directory
|
|
// as a check for the import, as the import will be different in Chromium and
|
|
// would therefore not match the path of `__dirname`.
|
|
// These should be removed because the new heuristic _should_ deal with these
|
|
// e.g. it'll pick up third_party/lit-html/lit-html.js is its own entrypoint
|
|
|
|
// Puppeteer has dynamic imports in its build gated on an ifNode
|
|
// flag, but our Rollup config doesn't know about that and tries
|
|
// to parse dynamic import('fs'). Let's ignore Puppeteer for now.
|
|
// The long term plan is probably for Puppeteer to ship a web
|
|
// bundle anyway. See go/pptr-agnostify for details.
|
|
if (importedFileDirectory.includes(path.join('front_end', 'third_party', 'puppeteer'))) {
|
|
return null;
|
|
}
|
|
|
|
// The CodeMirror addons look like bundles (addon/comment/comment.js) but are not.
|
|
if (importedFileDirectory.includes(path.join('front_end', 'third_party', 'codemirror', 'package'))) {
|
|
return null;
|
|
}
|
|
|
|
const importedFileName = path.basename(importedFilelocation, '.js');
|
|
const importedFileParentDirectory = path.basename(path.dirname(importedFilelocation));
|
|
const isExternal = importedFileName === importedFileParentDirectory;
|
|
|
|
return {
|
|
id: importedFilelocation,
|
|
external: isExternal,
|
|
};
|
|
}
|
|
},
|
|
]
|
|
});
|