chore: migrate from babel to esbuild loader

This commit is contained in:
Oprysk 2022-01-03 12:45:29 +02:00
parent 2474b76d0d
commit 2d37f4ee4f
9 changed files with 840 additions and 733 deletions

View File

@ -1,46 +1,5 @@
import * as webpack from 'webpack';
export function getBabelLoader({useBuiltIns, hot}: {useBuiltIns: boolean, hot?: boolean}) {
return {
loader: 'babel-loader',
options: {
babelrc: false,
sourceType: 'unambiguous',
presets: [
[
'@babel/preset-env',
{
useBuiltIns: useBuiltIns ? 'usage' : false,
corejs: 3,
exclude: ['transform-typeof-symbol'],
targets: 'defaults',
modules: false,
},
],
['@babel/preset-react', { development: false, runtime: 'classic' }],
'@babel/preset-typescript',
],
plugins: [
['@babel/plugin-proposal-decorators', { legacy: true }],
['@babel/plugin-proposal-class-properties', { loose: false }],
[
'@babel/plugin-transform-runtime',
{
corejs: false,
helpers: true,
// eslint-disable-next-line import/no-internal-modules
version: require('@babel/runtime/package.json').version,
regenerator: true,
},
],
'@babel/plugin-proposal-optional-chaining',
'@babel/plugin-proposal-nullish-coalescing-operator',
hot ? 'react-hot-loader/babel' : undefined,
].filter(Boolean)
},
};
}
export function webpackIgnore(regexp) {
return new webpack.NormalModuleReplacementPlugin(regexp, require.resolve('lodash/noop.js'));
return new webpack.NormalModuleReplacementPlugin(regexp, require.resolve('lodash.noop'));
}

2
custom.d.ts vendored
View File

@ -23,3 +23,5 @@ declare var reactHotLoaderGlobal: any;
interface Element {
scrollIntoViewIfNeeded(centerIfNeeded?: boolean): void;
}
type GenericObject = Record<string, any>;

View File

@ -3,7 +3,7 @@ import ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
import * as HtmlWebpackPlugin from 'html-webpack-plugin';
import { resolve } from 'path';
import * as webpack from 'webpack';
import { getBabelLoader, webpackIgnore } from '../config/webpack-utils';
import { webpackIgnore } from '../config/webpack-utils';
const VERSION = JSON.stringify(require('../package.json').version);
const REVISION = JSON.stringify(
@ -45,6 +45,7 @@ export default (env: { playground?: boolean; bench?: boolean } = {}, { mode }) =
extensions: ['.ts', '.tsx', '.js', '.json'],
fallback: {
path: require.resolve('path-browserify'),
buffer: require.resolve('buffer'),
http: false,
fs: false,
os: false,
@ -71,33 +72,28 @@ export default (env: { playground?: boolean; bench?: boolean } = {}, { mode }) =
rules: [
{ test: [/\.eot$/, /\.gif$/, /\.woff$/, /\.svg$/, /\.ttf$/], use: 'null-loader' },
{
test: /\.tsx?$/,
use: [getBabelLoader({ useBuiltIns: true, hot: true })],
exclude: {
and: [/node_modules/],
not: {
or: [
/swagger2openapi/,
/reftools/,
/openapi-sampler/,
/mobx/,
/oas-resolver/,
/oas-kit-common/,
/oas-schema-walker/,
/\@redocly\/openapi-core/,
/colorette/,
],
},
test: /\.(tsx?|[cm]?js)$/,
loader: 'esbuild-loader',
options: {
loader: 'tsx',
target: 'es2015',
tsconfigRaw: require('../tsconfig.json'),
},
exclude: [/node_modules/],
},
{
test: /\.css$/,
use: {
loader: 'css-loader',
options: {
sourceMap: true,
use: [
'style-loader',
'css-loader',
{
loader: 'esbuild-loader',
options: {
loader: 'css',
minify: true,
},
},
},
],
},
],
},
@ -118,6 +114,9 @@ export default (env: { playground?: boolean; bench?: boolean } = {}, { mode }) =
? 'benchmark/index.html'
: 'demo/index.html',
}),
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
}),
new ForkTsCheckerWebpackPlugin({ logger: { infrastructure: 'silent', issues: 'console' } }),
webpackIgnore(/js-yaml\/dumper\.js$/),
webpackIgnore(/json-schema-ref-parser\/lib\/dereference\.js/),

1322
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -61,18 +61,6 @@
"pre-commit": "pretty-quick --staged && npm run lint"
},
"devDependencies": {
"@babel/core": "^7.14.3",
"@babel/plugin-proposal-class-properties": "^7.13.0",
"@babel/plugin-proposal-decorators": "^7.14.2",
"@babel/plugin-proposal-object-rest-spread": "^7.14.4",
"@babel/plugin-syntax-decorators": "^7.12.13",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-jsx": "^7.10.4",
"@babel/plugin-syntax-typescript": "^7.10.4",
"@babel/plugin-transform-runtime": "^7.14.3",
"@babel/preset-env": "^7.14.4",
"@babel/preset-react": "^7.13.13",
"@babel/preset-typescript": "^7.13.0",
"@cypress/webpack-preprocessor": "^5.9.0",
"@hot-loader/react-dom": "^17.0.1",
"@size-limit/preset-app": "^7.0.4",
@ -82,7 +70,6 @@
"@types/enzyme-to-json": "^1.5.3",
"@types/jest": "^26.0.23",
"@types/json-pointer": "^1.0.30",
"@types/lodash": "^4.14.170",
"@types/lunr": "^2.3.3",
"@types/mark.js": "^8.11.5",
"@types/marked": "^3.0.1",
@ -100,8 +87,6 @@
"@typescript-eslint/eslint-plugin": "^4.26.0",
"@typescript-eslint/parser": "^4.26.0",
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.1",
"babel-loader": "^8.2.2",
"babel-plugin-styled-components": "^1.12.0",
"beautify-benchmark": "^0.2.4",
"conventional-changelog-cli": "^2.0.34",
"copy-webpack-plugin": "^9.0.0",
@ -111,6 +96,7 @@
"cypress": "^7.4.0",
"enzyme": "^3.11.0",
"enzyme-to-json": "^3.6.2",
"esbuild-loader": "^2.18.0",
"eslint": "^7.27.0",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-react": "^7.24.0",
@ -120,7 +106,7 @@
"jest": "^27.0.3",
"js-yaml": "^4.1.0",
"license-checker": "^25.0.1",
"lodash": "^4.17.21",
"lodash.noop": "^3.0.1",
"mobx": "^6.3.2",
"prettier": "^2.3.2",
"pretty-quick": "^3.0.0",
@ -134,7 +120,6 @@
"style-loader": "^2.0.0",
"styled-components": "^5.3.0",
"ts-jest": "^27.0.2",
"ts-loader": "^8.0.1",
"ts-node": "^10.0.0",
"typescript": "~4.1.0",
"unfetch": "^4.2.0",
@ -153,7 +138,6 @@
"styled-components": "^4.1.1 || ^5.1.1"
},
"dependencies": {
"@babel/runtime": "^7.14.0",
"@redocly/openapi-core": "^1.0.0-beta.54",
"@redocly/react-dropdown-aria": "^2.0.11",
"classnames": "^2.3.1",
@ -165,7 +149,7 @@
"mark.js": "^8.11.1",
"marked": "^3.0.4",
"mobx-react": "^7.2.0",
"openapi-sampler": "^1.0.1",
"openapi-sampler": "^1.1.1",
"path-browserify": "^1.0.1",
"perfect-scrollbar": "^1.5.1",
"polished": "^4.1.3",

View File

@ -0,0 +1,50 @@
import { objectHas, objectSet } from '../object';
describe('object utils', () => {
let obj;
beforeEach(() => {
obj = {
a: {
b: {
c: {
d: 'd',
},
c1: 'c1',
},
b1: 'b1',
},
a1: 'a1',
};
});
describe('objectHas function', () => {
it('should check if the obj has path as string', () => {
expect(objectHas(obj, 'a.b.c')).toBeTruthy();
expect(objectHas(obj, 'a.b.c1')).toBeTruthy();
expect(objectHas(obj, 'a.b.c.d')).toBeTruthy();
expect(objectHas(obj, 'a.b.c1.d')).toBeFalsy();
});
it('should check if the obj has path as array', () => {
expect(objectHas(obj, ['a', 'b', 'c'])).toBeTruthy();
expect(objectHas(obj, ['a', 'b', 'c1'])).toBeTruthy();
expect(objectHas(obj, ['a', 'b', 'c', 'd'])).toBeTruthy();
expect(objectHas(obj, ['a', 'b', 'c1', 'd'])).toBeFalsy();
});
});
describe('objectSet function', () => {
it('should set value by path as string', () => {
expect(objectHas(obj, 'a.b.c1.d')).toBeFalsy();
objectSet(obj, 'a.b.c1', { d: 'd' });
expect(objectHas(obj, 'a.b.c1.d')).toBeTruthy();
});
it('should set value by path as array', () => {
expect(objectHas(obj, ['a', 'b', 'c1', 'd'])).toBeFalsy();
objectSet(obj, ['a', 'b', 'c1'], { d: 'd' });
expect(objectHas(obj, ['a', 'b', 'c1', 'd'])).toBeTruthy();
});
});
});

28
src/utils/object.ts Normal file
View File

@ -0,0 +1,28 @@
export function objectHas(object: GenericObject, path: string | Array<string>): boolean {
let _path = <Array<string>>path;
if (typeof path === 'string') {
_path = path.split('.');
}
return _path.every((key: string) => {
if (typeof object != 'object' || object === null || !(key in object)) return false;
object = object[key];
return true;
});
}
export function objectSet(object: GenericObject, path: string | Array<string>, value: any): void {
let _path = <Array<string>>path;
if (typeof path === 'string') {
_path = path.split('.');
}
const limit = _path.length - 1;
for (let i = 0; i < limit; ++i) {
const key = _path[i];
object = object[key] ?? (object[key] = {});
}
const key = _path[limit];
object[key] = value;
}

View File

@ -1,6 +1,4 @@
/* tslint:disable:no-implicit-dependencies */
import { has, set } from 'lodash';
import { objectHas, objectSet } from './object';
function traverseComponent(root, fn) {
if (!root) {
@ -20,8 +18,8 @@ export function filterPropsDeep<T extends object>(component: T, paths: string[])
traverseComponent(component, comp => {
if (comp.props) {
for (const path of paths) {
if (has(comp.props, path)) {
set(comp.props, path, '<<<filtered>>>');
if (objectHas(comp.props, path)) {
objectSet(comp.props, path, '<<<filtered>>>');
}
}
}

View File

@ -2,7 +2,7 @@
import ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
import * as webpack from 'webpack';
import * as path from 'path';
import { getBabelLoader, webpackIgnore } from './config/webpack-utils';
import { webpackIgnore } from './config/webpack-utils';
const nodeExternals = require('webpack-node-externals')({
// bundle in modules that need transpiling + non-js (e.g. css)
@ -32,10 +32,14 @@ const BANNER = `ReDoc - OpenAPI/Swagger-generated API Reference Documentation
Version: ${VERSION}
Repo: https://github.com/Redocly/redoc`;
export default (env: { standalone?: boolean, browser?: boolean } = {}) => ({
export default (env: { standalone?: boolean; browser?: boolean } = {}) => ({
entry: env.standalone ? ['./src/polyfills.ts', './src/standalone.tsx'] : './src/index.ts',
output: {
filename: env.standalone ? 'redoc.standalone.js' : env.browser ? 'redoc.browser.lib.js' : 'redoc.lib.js',
filename: env.standalone
? 'redoc.standalone.js'
: env.browser
? 'redoc.browser.lib.js'
: 'redoc.lib.js',
path: path.join(__dirname, '/bundles'),
library: 'Redoc',
libraryTarget: 'umd',
@ -46,11 +50,12 @@ export default (env: { standalone?: boolean, browser?: boolean } = {}) => ({
extensions: ['.ts', '.tsx', '.js', '.mjs', '.json'],
fallback: {
path: require.resolve('path-browserify'),
buffer: require.resolve('buffer'),
http: false,
fs: path.resolve(__dirname, 'src/empty.js'),
os: path.resolve(__dirname, 'src/empty.js'),
tty: path.resolve(__dirname, 'src/empty.js'),
}
},
},
performance: false,
externalsPresets: env.standalone || env.browser ? {} : { node: true },
@ -74,32 +79,27 @@ export default (env: { standalone?: boolean, browser?: boolean } = {}) => ({
rules: [
{
test: /\.(tsx?|[cm]?js)$/,
use: [getBabelLoader({useBuiltIns: !!env.standalone})],
exclude: {
and: [/node_modules/],
not: {
or: [
/swagger2openapi/,
/reftools/,
/openapi-sampler/,
/mobx/,
/oas-resolver/,
/oas-kit-common/,
/oas-schema-walker/,
/\@redocly\/openapi-core/,
/colorette/,
],
},
loader: 'esbuild-loader',
options: {
loader: 'tsx',
target: 'es2015',
tsconfigRaw: require('./tsconfig.json'),
},
exclude: [/node_modules/],
},
{
test: /\.css$/,
use: {
loader: 'css-loader',
options: {
sourceMap: false,
use: [
'style-loader',
'css-loader',
{
loader: 'esbuild-loader',
options: {
loader: 'css',
minify: true,
},
},
},
],
},
],
},
@ -113,6 +113,9 @@ export default (env: { standalone?: boolean, browser?: boolean } = {}) => ({
}),
new ForkTsCheckerWebpackPlugin({ logger: { infrastructure: 'silent', issues: 'console' } }),
new webpack.BannerPlugin(BANNER),
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
}),
webpackIgnore(/js-yaml\/dumper\.js$/),
env.standalone ? webpackIgnore(/^\.\/SearchWorker\.worker$/) : undefined,
].filter(Boolean),