menu
close_24px

BLOG

Integrating Swagger UI into Web Apps Using Webpack 5 & EmberJs

Learn how you can successfully integrate Swagger UI into your web applications using Webpack 5 as the module bundler and Ember as the Javascript framework.
  • Posted on: Aug 20, 2024
  • By Sam Gnana David
  • Read time 3 Mins Read
  • Last updated on: Sep 10, 2024

This article provides a detailed guide on successfully integrating Swagger UI into web applications using EmberJs as the Javascript framework and Webpack as the module bundler. We will cover the step-by-step process, including any challenges encountered along the way and how we resolved them.

For those unfamiliar with Ember Js or Webpack, we have included introductory sections to get you up to speed. If you’re already familiar with it, feel free to skip directly to the integration steps. 


Table of Contents


Introduction to Swagger UI

Swagger UI is a collection of HTML, JavaScript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API.

Swagger UI allows anyone—be it your development team or your end consumers—to visualize and interact with the API’s resources without having any of the implementation logic in place. It’s automatically generated from your OpenAPI (formerly known as Swagger) Specification, and the visual documentation makes it easy for back-end implementation and client-side consumption.

Introduction to EmberJs

Ember.js is a productive, battle-tested JavaScript framework for building modern web applications. It includes everything you need to build rich UIs that work on any device. 

It does so by providing developers with many features essential to managing complexity in modern web applications and an integrated development toolkit that enables rapid iteration.

Introduction to Webpack

Webpack is a static module bundler for modern JavaScript applications. When Webpack processes your application, it internally builds a dependency graph from one or more entry points and then combines every module your project needs into one or more bundles, which are static assets to serve your content from.

How to create a new Ember application?

npx ember new ember-swagger-ui --lang en

This command will create a new directory, ember-swagger-ui, and set up a new Ember application inside of it.

Installing Swagger UI

npm install swagger-ui

Note: We are using the latest version of the library (  5.17.14  ) at the time of writing this article.

Installing ember-cli-sass

We need to install ember-cli-sass and node-sass to import styles from swagger-ui.

npm install ember-cli-sass node-sass

 

Adding configuration & import styles

In  ember-cli-build.js: 

const EmberApp = require('ember-cli/lib/broccoli/ember-app');
module.exports = function (defaults) {
  const app = new EmberApp(defaults, {
    // Add options here
    sassOptions: {
      includePaths: ['node_modules/swagger-ui/dist/'],
      implementation: require('node-sass'),
    },
  });
  return app.toTree();
};


In  styles/app.scss  (rename app.css):

@import "swagger-ui";

 

How to create a wrapper component?

  1. Go to app/components.
  2. Create a new folder swagger-ui. 
  3. Inside swagger-ui create files index.html  and index.js.

In  swagger-ui/index.hbs : 

<div ></div>

In  swagger-ui/index.js : 

import Component from '@glimmer/component';
import { action } from '@ember/object';

import SwaggerUI from 'swagger-ui';

export default class SwaggerUIComponent extends Component {
  @action
  intializeSwaggerUI(element) {
    SwaggerUI({
      url: 'https://petstore.swagger.io/v2/swagger.json',
      domNode: element,
      presets: [SwaggerUI.presets.apis, SwaggerUI.SwaggerUIStandalonePreset],
    });
  }
}

Add component to  templates/application.hbs  for preview:



<SwaggerUi />

 

The Polyfill issue in Webpack 5

Now, if we try to start the application, build compilation will fail, and we will see the following error:

ERROR in ./node_modules/xml/lib/xml.js 1:54-78
Module not found: Error: Can't resolve 'stream' in 'path-to-project/node_modules/xml/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
        - add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
        - install 'stream-browserify'

If you don't want to include a polyfill, you can use an empty module like this:
        resolve.fallback: { "stream": false }
resolve 'stream' in 'path-to-project/node_modules/xml/lib'
  Parsed request is a module
  using description file: path-to-project/node_modules/xml/package.json (relative path: ./lib)
    Field 'browser' doesn't contain a valid alias configuration
    resolve as module

This is because Webpack 4 automatically poly-filled many node APIs in the browser. This was not a great system because it could lead to surprisingly giant libraries getting pulled into your app by accident, and it gave us no control over the exact versions of the polyfills we were using.

So, Webpack 5 removed this functionality. That means we need to make changes to fix this.

 

Fixing the Polyfill issue in Webpack 5

To fix the build compilation, we need to use the polyfill stream module. Install stream-browserify. 

npm install -D stream-browserify

In  ember-cli-build.js: 

'use strict';

const EmberApp = require('ember-cli/lib/broccoli/ember-app');

module.exports = function (defaults) {
  const app = new EmberApp(defaults, {
    // Add options here
    ...
    autoImport: {
      webpack: {
        // extra webpack configuration goes here
        resolve: {
          fallback: {
            stream: require.resolve('stream-browserify'),
          },
        },
      },
    },
  });
  return app.toTree();
};


Now, build the application again, and we should see the build be successful. But if we check the UI in the browser (open and go to http://localhost:4200), it will be blank. Open the console (press F12), and we will see this error:

A screenshot of the Console showing the error caused by the polyfill issue.


To fix this, we need to add this to the Webpack configuration:

webpack: {
  // extra webpack configuration goes here
  node: {
    global: true,
  },
  ...
},

Let's build again for the changes to take effect. Now, when we check the browser, the UI still appears to be blank, and there is a new error in the console.

A screenshot of the Console showing a new error after adding an extra Webpack configuration.


Now, we need to polyfill the  buffer module.

npm install -D buffer

In  ember-cli-build.js: 

const EmberApp = require('ember-cli/lib/broccoli/ember-app');
const webpack = require('webpack');

module.exports = function (defaults) {
  const app = new EmberApp(defaults, {
    // Add options here
    ...
    autoImport: {
      webpack: {
        // extra webpack configuration goes here
        ...
        plugins: [
          new webpack.ProvidePlugin({
            Buffer: ['buffer', 'Buffer'],
          }),
        ],
        resolve: {
          fallback: {
            ...
            buffer: require.resolve('buffer/'),
          },
        },
      },
    },
  });

  return app.toTree();

};


Now, build again, and we should see the API documentation in the browser.

An image showing the API documentation in the browser.

 

Conclusion

We have successfully integrated swagger-ui using Webpack 5 and Ember Js. For more configuration and customization, please check out their documentation on GitHub.