Skip to content
⚠️ This article was written in 2021. Some content may be outdated.

The Trend Toward Unified Frontend Build Tools

We recently adopted the trend toward unified frontend build tools on our team and accumulated quite a bit of experience. Here's a summary for reference, hoping it helps those doing similar work.

Core Concepts ​

Let's start with the basic implementation:

javascript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'

export default defineConfig({
  plugins: [vue()],
  resolve: { alias: { '@': resolve(__dirname, 'src') } },
  server: {
    port: 3000,
    proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } }
  },
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['vue', 'vue-router', 'pinia'],
          utils: ['lodash-es', 'dayjs']
        }
      }
    }
  }
})

This code demonstrates the basic usage. In real projects, you also need to consider error handling and edge cases.

In-Depth Analysis ​

Building on this foundation, we can further optimize:

javascript
module.exports = {
  entry: './src/index.js',
  output: { path: __dirname + '/dist', filename: '[name].[contenthash:8].js' },
  module: {
    rules: [
      { test: /\.jsx?$/, exclude: /node_modules/, use: 'babel-loader' },
      { test: /\.css$/, use: ['style-loader', 'css-loader', 'postcss-loader'] }
    ]
  },
  optimization: {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendors' }
      }
    }
  }
}

This pattern is very practical in large projects and can significantly reduce maintenance costs.

Implementation Experience ​

In real projects, the usage gets a bit more involved:

javascript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'

export default defineConfig({
  plugins: [vue()],
  resolve: { alias: { '@': resolve(__dirname, 'src') } },
  server: {
    port: 3000,
    proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } }
  },
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['vue', 'vue-router', 'pinia'],
          utils: ['lodash-es', 'dayjs']
        }
      }
    }
  }
})

Through this approach, both the testability and scalability of the code are improved.

Optimization Strategies ​

Here is a complete example:

javascript
module.exports = {
  entry: './src/index.js',
  output: { path: __dirname + '/dist', filename: '[name].[contenthash:8].js' },
  module: {
    rules: [
      { test: /\.jsx?$/, exclude: /node_modules/, use: 'babel-loader' },
      { test: /\.css$/, use: ['style-loader', 'css-loader', 'postcss-loader'] }
    ]
  },
  optimization: {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendors' }
      }
    }
  }
}

Pay attention to boundary condition handling, which is critical in production.

Summary ​

  • Code examples are for reference only and need to be adjusted according to your business scenario
  • The shift toward unified frontend build tools is no silver bullet; choose it based on project scale and tech stack.
  • Understanding underlying principles is more important than memorizing APIs

MIT Licensed