Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: modernize build pipeline #1635

Merged
merged 3 commits into from
Jun 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
- The widest OpenAPI v2.0 features support (yes, it supports even `discriminator`) <br>
![](docs/images/discriminator-demo.gif)
- OpenAPI 3.0 support
- Basic OpenAPI 3.1 support
- Neat **interactive** documentation for nested objects <br>
![](docs/images/nested-demo.gif)
- Code samples support (via vendor extension) <br>
Expand All @@ -43,7 +44,6 @@
- [x] ~~React rewrite~~
- [x] ~~docs pre-rendering (performance and SEO)~~
- [ ] ability to simple branding/styling
- [ ] built-in API Console

## Releases
**Important:** all the 2.x releases are deployed to npm and can be used via jsdeliver:
Expand All @@ -58,6 +58,7 @@ Additionally, all the 1.x releases are hosted on our GitHub Pages-based CDN **(d
## Version Guidance
| ReDoc Release | OpenAPI Specification |
|:--------------|:----------------------|
| 2.0.0-alpha.54| 3.1, 3.0.x, 2.0 |
| 2.0.0-alpha.x | 3.0, 2.0 |
| 1.19.x | 2.0 |
| 1.18.x | 2.0 |
Expand Down
680 changes: 313 additions & 367 deletions cli/npm-shrinkwrap.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"mkdirp": "^1.0.4",
"mobx": "^6.3.2",
"node-libs-browser": "^2.2.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react": "^16.8.4",
"react-dom": "^16.8.4",
"redoc": "2.0.0-rc.53",
"styled-components": "^5.3.0",
"tslib": "^2.2.0",
Expand Down
46 changes: 46 additions & 0 deletions config/webpack-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
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'));
}
2 changes: 1 addition & 1 deletion demo/ComboBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const DropDownList = styled.ul`
list-style: none;
margin: 4px 0 0 0;
padding: 5px 0;
font-family: 'Lato';
font-family: Roboto,sans-serif;
overflow: hidden;
`;

Expand Down
4 changes: 2 additions & 2 deletions demo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const demos = [
label: 'Google Calendar',
},
{ value: 'https://api.apis.guru/v2/specs/slack.com/1.5.0/openapi.yaml', label: 'Slack' },
{ value: 'https://api.apis.guru/v2/specs/zoom.us/2.0.0/swagger.yaml', label: 'Zoom.us' },
{ value: 'https://api.apis.guru/v2/specs/zoom.us/2.0.0/openapi.yaml', label: 'Zoom.us' },
{ value: 'https://docs.graphhopper.com/openapi.json', label: 'GraphHopper' },
];

Expand Down Expand Up @@ -154,7 +154,7 @@ const Heading = styled.nav`

display: flex;
align-items: center;
font-family: 'Lato';
font-family: Roboto, sans-serif;
`;

const Logo = styled.img`
Expand Down
44 changes: 3 additions & 41 deletions demo/playground/hmr-playground.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,7 @@
import * as React from 'react';
import { render } from 'react-dom';
// tslint:disable-next-line
import { AppContainer } from 'react-hot-loader';
// import DevTools from 'mobx-react-devtools';

import { Redoc, RedocProps } from '../../src/components/Redoc/Redoc';
import { AppStore } from '../../src/services/AppStore';
import { RedocRawOptions } from '../../src/services/RedocNormalizedOptions';
import { loadAndBundleSpec } from '../../src/utils/loadAndBundleSpec';

const renderRoot = (props: RedocProps) =>
render(
<AppContainer>
<Redoc {...props} />
</AppContainer>,
document.getElementById('example'),
);
import type { RedocRawOptions } from '../../src/services/RedocNormalizedOptions';
import RedocStandalone from './hot';

const big = window.location.search.indexOf('big') > -1;
const swagger = window.location.search.indexOf('swagger') > -1;
Expand All @@ -25,30 +11,6 @@ const userUrl = window.location.search.match(/url=(.*)$/);
const specUrl =
(userUrl && userUrl[1]) || (swagger ? 'swagger.yaml' : big ? 'big-openapi.json' : 'openapi.yaml');

let store;
const options: RedocRawOptions = { nativeScrollbars: false, maxDisplayedEnumValues: 3 };

async function init() {
const spec = await loadAndBundleSpec(specUrl);
store = new AppStore(spec, specUrl, options);
renderRoot({ store });
}

init();

if (module.hot) {
const reload = (reloadStore = false) => async () => {
if (reloadStore) {
// create a new Store
store.dispose();

const state = await store.toJS();
store = AppStore.fromJS(state);
}

renderRoot({ store });
};

module.hot.accept(['../../src/components/Redoc/Redoc'], reload());
module.hot.accept(['../../src/services/AppStore'], reload(true));
}
render(<RedocStandalone specUrl={specUrl} options={options} />, document.getElementById('example'));
10 changes: 10 additions & 0 deletions demo/playground/hot.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import * as React from 'react';
// eslint-disable-next-line import/no-internal-modules
import { hot } from 'react-hot-loader/root';
import { RedocStandalone as RedocStandaloneOrig, RedocStandaloneProps } from '../../src';

const RedocStandalone = function (props: RedocStandaloneProps) {
return <RedocStandaloneOrig {...props} />;
}

export default hot(RedocStandalone);
106 changes: 37 additions & 69 deletions demo/webpack.config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import * as CopyWebpackPlugin from 'copy-webpack-plugin';
import ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
import * as HtmlWebpackPlugin from 'html-webpack-plugin';
import { compact } from 'lodash';
import { resolve } from 'path';
import * as webpack from 'webpack';
import { getBabelLoader, webpackIgnore } from '../config/webpack-utils';

const VERSION = JSON.stringify(require('../package.json').version);
const REVISION = JSON.stringify(
Expand All @@ -14,38 +14,6 @@ function root(filename) {
return resolve(__dirname + '/' + filename);
}

const tsLoader = (env) => ({
loader: 'ts-loader',
options: {
compilerOptions: {
module: env.bench ? 'esnext' : 'es2015',
declaration: false,
},
},
});

const babelLoader = () => ({
loader: 'babel-loader',
options: {
generatorOpts: {
decoratorsBeforeExport: true,
},
plugins: compact([
['@babel/plugin-syntax-typescript', { isTSX: true }],
['@babel/plugin-syntax-decorators', { legacy: true }],
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-syntax-jsx',
]),
},
});

const babelHotLoader = {
loader: 'babel-loader',
options: {
plugins: ['react-hot-loader/babel'],
},
};

export default (env: { playground?: boolean; bench?: boolean } = {}, { mode }) => ({
entry: [
root('../src/polyfills.ts'),
Expand All @@ -57,6 +25,7 @@ export default (env: { playground?: boolean; bench?: boolean } = {}, { mode }) =
: 'index.tsx',
),
],
target: 'web',
output: {
filename: 'redoc-demo.bundle.js',
path: root('dist'),
Expand All @@ -69,22 +38,25 @@ export default (env: { playground?: boolean; bench?: boolean } = {}, { mode }) =
port: 9090,
disableHostCheck: true,
stats: 'minimal',
hot: true,
},

resolve: {
extensions: ['.ts', '.tsx', '.js', '.json'],
fallback: {
path: require.resolve('path-browserify'),
http: false,
fs: false,
os: false,
},
alias:
mode !== 'production'
? {
'react-dom': '@hot-loader/react-dom',
}
'react-dom': '@hot-loader/react-dom',
}
: {},
},

node: {
fs: 'empty',
},

performance: false,

externals: {
Expand All @@ -101,12 +73,23 @@ export default (env: { playground?: boolean; bench?: boolean } = {}, { mode }) =
{ test: [/\.eot$/, /\.gif$/, /\.woff$/, /\.svg$/, /\.ttf$/], use: 'null-loader' },
{
test: /\.tsx?$/,
use: compact([
mode !== 'production' ? babelHotLoader : undefined,
tsLoader(env),
babelLoader(),
]),
exclude: [/node_modules/],
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: /\.css$/,
Expand All @@ -117,46 +100,31 @@ export default (env: { playground?: boolean; bench?: boolean } = {}, { mode }) =
},
},
},
{
test: /node_modules\/(swagger2openapi|reftools|oas-resolver|oas-kit-common|oas-schema-walker)\/.*\.js$/,
use: {
loader: 'ts-loader',
options: {
transpileOnly: true,
instance: 'ts2js-transpiler-only',
compilerOptions: {
allowJs: true,
declaration: false,
},
},
},
},
],
},
plugins: [
new webpack.DefinePlugin({
__REDOC_VERSION__: VERSION,
__REDOC_REVISION__: REVISION,
'process.env': '{}',
'process.platform': '"browser"',
'process.stdout': 'null',
}),
new webpack.NamedModulesPlugin(),
new webpack.optimize.ModuleConcatenationPlugin(),
// new webpack.NamedModulesPlugin(),
// new webpack.optimize.ModuleConcatenationPlugin(),
new HtmlWebpackPlugin({
template: env.playground
? 'demo/playground/index.html'
: env.bench
? 'benchmark/index.html'
: 'demo/index.html',
}),
new ForkTsCheckerWebpackPlugin(),
ignore(/js-yaml\/dumper\.js$/),
ignore(/json-schema-ref-parser\/lib\/dereference\.js/),
ignore(/^\.\/SearchWorker\.worker$/),
new ForkTsCheckerWebpackPlugin({ logger: { infrastructure: 'silent', issues: 'console' } }),
webpackIgnore(/js-yaml\/dumper\.js$/),
webpackIgnore(/json-schema-ref-parser\/lib\/dereference\.js/),
webpackIgnore(/^\.\/SearchWorker\.worker$/),
new CopyWebpackPlugin({
patterns: ['demo/openapi.yaml'],
}),
],
});

function ignore(regexp) {
return new webpack.NormalModuleReplacementPlugin(regexp, require.resolve('lodash/noop.js'));
}
Loading