Optimizing a Vue.js Internal Ops System: From Tech Stack to Build Strategies

This article details the design and implementation of Tencent Cloud's internal YY‑DSA operations platform, covering project background, frontend technology selection (Vue.js, Element‑UI, webpack), project structure, development environment, build optimizations such as code splitting, CommonsChunk, and the comparison of Dll versus externals for faster builds.

Tencent IMWeb Frontend Team
Tencent IMWeb Frontend Team
Tencent IMWeb Frontend Team
Optimizing a Vue.js Internal Ops System: From Tech Stack to Build Strategies

Project Background

The front‑end team built an internal operations system for Tencent Cloud DSA, called YY‑DSA. Because it is internal, the team could freely choose the technology stack but had to follow strict architectural guidelines: clear module responsibilities, low coupling, and maintaining overall efficiency without sacrificing process efficiency for program speed.

Frontend Technology Selection

After evaluating options, the team chose Vue.js as the MV* framework because the team was already familiar with it, reducing learning cost. Vue’s virtual DOM provides good performance, and its API is concise and easy to adopt.

For UI components, several libraries were examined (bootstrap‑vue, uiv, vue‑beauty, element‑ui, iview). The team selected Element‑UI due to its design size, scoped‑slot style, and similarity to Ant Design while fitting the project’s needs.

The build automation tool selected was webpack rather than gulp, because webpack excels at module bundling and offers better performance for the project’s primary need of packaging.

Project Structure

Front‑end structure (generated by vue‑webpack scaffold):

├── build            // build tools and dev server
├── config           // build configuration
├── dist             // compiled output
├── lib-dist         // external libraries
├── index.html       // entry HTML
├── node_modules
├── src              // source code
│   ├── router
│   ├── pages
│   ├── components
│   ├── util
│   ├── style
│   ├── assets
│   ├── App.vue
│   └── main.js
└── package.json

Web server structure :

├── middleware
├── node_modules
├── lib
├── util
├── route
├── dao
├── controller
├── app.js
├── config.js
└── package.json

Front‑end Development Environment

The scaffold provides a dev‑server that can be started with npm run dev. It incorporates three key middleware:

webpack-dev-middleware : compiles assets to memory for fast response.

webpack-hot-middleware : enables hot module replacement via a long‑lived connection.

http-proxy-middleware : proxies API requests to the backend while serving static resources locally.

Proxy configuration uses a zero‑width‑assertion regex to redirect all non‑/api requests to the local dev server, e.g.:

/yy.dsa.oa.com(?!/api)(.*)/i localhost:8080$1

Front‑end Build Adjustments

Code Splitting

To avoid a monolithic app.js, the team uses require.ensure to split business pages into separate chunks, loading them on demand.

// router/index.js
let Vue = require('vue');
let Router = require('vue-router');
Vue.use(Router);

const requireUserVip = (component) => {
  return (resolve, reject) => {
    return require.ensure([], (item) => {
      resolve(require('@/pages/user/vip/index.js')[component]);
    }, "user-vip");
  }
};

module.exports = new Router({
  mode: 'history',
  routes: [
    {path: '/user/vip/list', name: 'user-vip-list', component: requireUserVip("list")},
    {path: '/user/vip/add', name: 'user-vip-add', component: requireUserVip("add")},
    {path: '/user/vip/edit/:app_id', name: 'user-vip-edit', component: requireUserVip("edit")},
    {path: '/user/vip/detail/:app_id', name: 'user-vip-detail', component: requireUserVip("detail")}
  ]
});

Module Format Conversion

Because require.ensure uses CommonJS, the project’s .babelrc was updated with transform-es2015-modules-commonjs. Vue‑loader’s esModule option was set to false in build/vue-loader.conf.js to keep .vue files in CommonJS format.

// build/vue-loader.conf.js
module.exports = {
  loaders: loaders,
  transformToRequire: {
    video: 'src',
    source: 'src',
    img: 'src',
    image: 'xlink:href'
  },
  esModule: false // disable ES module output for .vue files
};

CommonsChunk Optimization

The default webpack config already extracts node_modules into a common chunk. Additional configuration was added to extract shared utility modules and to create a manifest chunk, preventing duplicate inclusion of util code across business chunks.

// Example snippet from build/webpack.prod.conf.js
new webpack.optimize.CommonsChunkPlugin({
  name: 'node-modules',
  minChunks: function (module) {
    return module.resource && /\.js$/.test(module.resource) &&
      isInvolve(module.resource, [pathJoin("../node_modules")]);
  },
  chunks: ['app']
}),
new webpack.optimize.CommonsChunkPlugin({
  name: 'common',
  minChunks: function (module) {
    return module.resource && /\.js$/.test(module.resource) &&
      isInvolve(module.resource, [pathJoin("../src/util")]);
  },
  chunks: ['app']
}),
new webpack.optimize.CommonsChunkPlugin({
  name: 'manifest',
  chunks: ['common', 'node-modules']
});

Dll vs. Externals

To speed up builds, two strategies were evaluated:

Dll : pre‑bundle stable libraries (Vue, Vue‑router, Vue‑resource, Element‑UI) into a separate DLL bundle using webpack.DllPlugin and reference it with DllReferencePlugin.

Externals : declare these libraries as external globals, load them via script tags, and tell webpack not to bundle them.

Both approaches reduced build time, but externals gave a larger gain because DLL still required copying the bundles into dist. The team ultimately adopted the externals method.

Conclusion

Technology selection should match actual needs, not necessarily be the most cutting‑edge.

Simplicity and overall benefit outweigh premature performance tweaks.

Continuous exploration of small details can yield significant improvements.

Thanks to mentor alsotang for guidance (GitHub: https://github.com/alsotang).

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.

Build OptimizationwebpackVue.jsCode Splitting
Tencent IMWeb Frontend Team
Written by

Tencent IMWeb Frontend Team

IMWeb Frontend Community gathering frontend development enthusiasts. Follow us for refined live courses by top experts, cutting‑edge technical posts, and to sharpen your frontend skills.

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.