mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
After https://github.com/elastic/kibana/pull/146212 it feels like the babel-register cache is getting invalidated more frequently for some reason. The current version of the cache only stores a single cache entry for each file path, which shouldn't be too big of a problem but with these changes several versions of a file will be cached. The performance seems about equal, but because the cache contains multiple versions of a single file we should spend less time transpiling files when switching branches often. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
149 lines
4.2 KiB
JavaScript
149 lines
4.2 KiB
JavaScript
/*
|
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
* or more contributor license agreements. Licensed under the Elastic License
|
|
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
|
* Side Public License, v 1.
|
|
*/
|
|
|
|
/* eslint-disable @kbn/eslint/require-license-header */
|
|
|
|
/**
|
|
* This module is based on @babel/register @ 9808d25, modified to use
|
|
* a more efficient caching implementation which writes to disk as
|
|
* the cache is built rather than keeping the whole cache in memory
|
|
* and then dumping it to disk when the process exits.
|
|
*/
|
|
|
|
/**
|
|
* @notice
|
|
* MIT License
|
|
*
|
|
* Copyright (c) 2014-present Sebastian McKenzie and other contributors
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
* a copy of this software and associated documentation files (the
|
|
* "Software"), to deal in the Software without restriction, including
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
* the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be
|
|
* included in all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
const Fs = require('fs');
|
|
const Path = require('path');
|
|
|
|
const { addHook } = require('pirates');
|
|
const sourceMapSupport = require('source-map-support');
|
|
|
|
const { getCache } = require('./cache');
|
|
|
|
const { TRANSFORMS } = require('./transforms');
|
|
|
|
/** @typedef {RegExp | string} Matcher */
|
|
|
|
/** @type {Matcher[]} */
|
|
const IGNORE_PATTERNS = [
|
|
// ignore paths matching `/node_modules/{a}`, unless `a` is "@kbn"
|
|
/[\/\\]node_modules[\/\\](?!@kbn)([^\/\\]+)[\/\\]/,
|
|
|
|
// ignore packages with "babel" in their names
|
|
/[\/\\]packages[\/\\]([^\/\\]+-)?babel(-[^\/\\]+)?[\/\\]/,
|
|
|
|
// ignore paths matching `/canvas/canvas_plugin/`
|
|
/[\/\\]canvas[\/\\]canvas_plugin[\/\\]/,
|
|
];
|
|
|
|
/**
|
|
*
|
|
* @param {string} path
|
|
* @param {Matcher[] | undefined} matchers
|
|
*/
|
|
function match(path, matchers) {
|
|
if (!matchers) {
|
|
return false;
|
|
}
|
|
|
|
return matchers.some((m) => {
|
|
if (typeof m === 'string') {
|
|
if (m.endsWith('/')) {
|
|
return path.startsWith(m);
|
|
}
|
|
|
|
return path === m || path.startsWith(m + Path.sep);
|
|
}
|
|
|
|
return m.test(path);
|
|
});
|
|
}
|
|
|
|
let installed = false;
|
|
|
|
/**
|
|
* @param {{ ignore?: Matcher[], only?: Matcher[] } | undefined} options
|
|
*/
|
|
function install(options = undefined) {
|
|
if (installed) {
|
|
return;
|
|
}
|
|
|
|
installed = true;
|
|
const cache = getCache();
|
|
|
|
sourceMapSupport.install({
|
|
handleUncaughtExceptions: false,
|
|
environment: 'node',
|
|
// @ts-expect-error bad source-map-support types
|
|
retrieveSourceMap(path) {
|
|
if (!Path.isAbsolute(path)) {
|
|
return null;
|
|
}
|
|
|
|
let source;
|
|
try {
|
|
source = Fs.readFileSync(path, 'utf8');
|
|
} catch {
|
|
return null;
|
|
}
|
|
|
|
const map = cache.getSourceMap(cache.getKey(path, source));
|
|
return map ? { map, url: null } : null;
|
|
},
|
|
});
|
|
|
|
const ignorePatterns = options?.ignore
|
|
? [...options.ignore, ...IGNORE_PATTERNS]
|
|
: IGNORE_PATTERNS;
|
|
|
|
addHook(
|
|
(code, path) => {
|
|
const ext = Path.extname(path);
|
|
const transform = (Object.hasOwn(TRANSFORMS, ext) && TRANSFORMS[ext]) || TRANSFORMS.default;
|
|
return transform(path, code, cache);
|
|
},
|
|
{
|
|
exts: ['.js', '.ts', '.tsx', '.peggy'],
|
|
ignoreNodeModules: false,
|
|
matcher(path) {
|
|
if (options?.only && !match(path, options.only)) {
|
|
return false;
|
|
}
|
|
|
|
return !match(path, ignorePatterns);
|
|
},
|
|
}
|
|
);
|
|
}
|
|
|
|
module.exports = { install };
|