Optimizing Micro‑Frontend Applications with Dependency Sharing and CDN Externalization

This article explains how to reduce bundle size and improve load speed of large micro‑frontend projects by sharing common dependencies through CDN externalization, using tools such as qiankun, vite‑plugin‑cdn‑import, and Rollup plugins for HTML generation.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Optimizing Micro‑Frontend Applications with Dependency Sharing and CDN Externalization

Introduction

As micro‑frontend architecture gains popularity, projects often split a front‑end application into many independent sub‑applications, each with its own node_modules bundle. In a company using the qiankun framework with a Vue 3 host app, over 400 sub‑apps lead to duplicated third‑party code, hurting performance.

Optimization Strategies

Common code‑level optimizations such as lazy loading and static asset compression are well known; this article focuses on two packaging‑level techniques: gzip compression and dependency sharing . The latter is explored in depth.

Initial Load Files of a Typical Project

A vanilla project without special bundling configuration typically loads the following files on first visit:

File

Purpose

Size

Load Time

0.js

Route page content

(prefetch cache)

60 ms

app.js

Main non‑route code

893 kB

12 ms

chunk‑vendors.js

Third‑party dependencies from node_modules 37.9 MB

427 ms

The bulk of the payload comes from chunk‑vendors.js , which contains duplicated third‑party libraries across sub‑apps.

Dependency Sharing Concept

When many sub‑apps each bundle their own node_modules, the same libraries (e.g., Vue core, state management, linting tools) are downloaded repeatedly. By externalizing these common libraries and loading them once via a CDN, all sub‑apps can reuse the cached copies, dramatically reducing download size and improving perceived performance.

How to Implement Dependency Sharing

Externalizing Dependencies via CDN

The simplest approach is to mark frequently used libraries as external dependencies and load them from a CDN instead of bundling them into each sub‑app.

Using vite-plugin-cdn-import

Install the plugin: npm install vite-plugin-cdn-import --save-dev Then add it to vite.config.js:

import { defineConfig } from 'vite';
import cdnImport from 'vite-plugin-cdn-import';

export default defineConfig({
  plugins: [
    cdnImport({
      imports: [
        {
          // library name, e.g., 'react'
          libraryName: 'react',
          // CDN URL for the library
          url: 'https://cdn.jsdelivr.net/npm/[email protected]/umd/react.production.min.js',
          prod: true,   // use CDN in production
          dev: false    // do not use CDN in development
        },
        // add more libraries as needed
      ]
    })
  ]
});

When building or running the dev server, the listed dependencies are injected as <script> tags pointing to the CDN URLs.

In the configuration above, libraryName specifies the package to replace, and url is the CDN location. The prod and dev flags control usage in different environments.

Note: configuring each dependency manually can be tedious for large projects.

Using rollup-plugin-html and rollup-plugin-node-resolve

Another method is to generate an HTML file that includes all bundled node_modules as separate <script> tags.

Install the required plugins:

npm install --save-dev rollup-plugin-html rollup-plugin-node-resolve rollup-plugin-terser

Create a custom Rollup plugin to emit an index.html with script tags:

import resolve from '@rollup/plugin-node-resolve';
import html from '@rollup/plugin-html';
import { terser } from 'rollup-plugin-terser';
import { defineConfig } from 'rollup';

const generateHTML = () => {
  return {
    name: 'generate-html',
    generateBundle(options, bundle) {
      const scriptTags = Object.keys(bundle)
        .filter(fileName => fileName.endsWith('.js'))
        .map(fileName => `<script src="${fileName}"></script>`)
        .join('
');

      const htmlContent = `
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My App</title>
</head>
<body>
  ${scriptTags}
</body>
</html>`;

      this.emitFile({
        type: 'asset',
        fileName: 'index.html',
        source: htmlContent
      });
    }
  };
};

export default defineConfig({
  input: 'src/main.js',
  output: {
    dir: 'dist',
    format: 'esm',
    entryFileNames: 'static/js/[name]-[hash].js',
    chunkFileNames: 'static/js/[name]-[hash].js',
    assetFileNames: 'static/assets/[name]-[hash][extname]'
  },
  plugins: [
    resolve(),
    terser(),
    generateHTML()
  ]
});

The generateHTML plugin scans the bundle for JavaScript files and injects them as script tags, producing an HTML entry point that loads shared dependencies from the CDN when configured accordingly.

The generateBundle hook iterates over bundle assets, creates &lt;script&gt; tags for each .js file, and writes an index.html asset.

Conclusion

By externalizing common libraries and sharing them across micro‑frontend sub‑applications—either via vite-plugin-cdn-import or custom Rollup HTML generation—teams can dramatically shrink bundle sizes, reduce duplicate network requests, and achieve faster load times for both host and child apps.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Frontend OptimizationCDNViteRollupDependency Sharingmicro-frontend
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.