在大型项目中,构建流程的优化对于提高开发效率和产品性能至关重要。本节将详细介绍如何优化 Tailwind CSS 项目的构建流程。

开发环境优化

Webpack 配置优化

  1. // webpack.dev.js
  2. const path = require('path');
  3. module.exports = {
  4. mode: 'development',
  5. devtool: 'eval-cheap-module-source-map',
  6. module: {
  7. rules: [
  8. {
  9. test: /\.css$/,
  10. use: [
  11. 'style-loader',
  12. {
  13. loader: 'css-loader',
  14. options: {
  15. importLoaders: 1,
  16. },
  17. },
  18. 'postcss-loader',
  19. ],
  20. },
  21. ],
  22. },
  23. // 开发服务器配置
  24. devServer: {
  25. hot: true,
  26. liveReload: true,
  27. client: {
  28. overlay: {
  29. errors: true,
  30. warnings: false,
  31. },
  32. },
  33. },
  34. // 缓存配置
  35. cache: {
  36. type: 'filesystem',
  37. buildDependencies: {
  38. config: [__filename],
  39. },
  40. },
  41. }

PostCSS 配置优化

  1. // postcss.config.js
  2. module.exports = {
  3. plugins: {
  4. 'postcss-import': {},
  5. 'tailwindcss/nesting': {},
  6. tailwindcss: {},
  7. autoprefixer: {},
  8. ...(process.env.NODE_ENV === 'development'
  9. ? {
  10. 'postcss-preset-env': {
  11. stage: 3,
  12. features: {
  13. 'nesting-rules': true,
  14. },
  15. },
  16. }
  17. : {}),
  18. },
  19. }

生产环境优化

构建配置

  1. // webpack.prod.js
  2. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  3. const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
  4. const TerserPlugin = require('terser-webpack-plugin');
  5. module.exports = {
  6. mode: 'production',
  7. devtool: 'source-map',
  8. module: {
  9. rules: [
  10. {
  11. test: /\.css$/,
  12. use: [
  13. MiniCssExtractPlugin.loader,
  14. {
  15. loader: 'css-loader',
  16. options: {
  17. importLoaders: 1,
  18. },
  19. },
  20. 'postcss-loader',
  21. ],
  22. },
  23. ],
  24. },
  25. optimization: {
  26. minimizer: [
  27. new CssMinimizerPlugin({
  28. minimizerOptions: {
  29. preset: [
  30. 'default',
  31. {
  32. discardComments: { removeAll: true },
  33. normalizeWhitespace: false,
  34. },
  35. ],
  36. },
  37. }),
  38. new TerserPlugin({
  39. terserOptions: {
  40. format: {
  41. comments: false,
  42. },
  43. },
  44. extractComments: false,
  45. }),
  46. ],
  47. splitChunks: {
  48. cacheGroups: {
  49. styles: {
  50. name: 'styles',
  51. test: /\.css$/,
  52. chunks: 'all',
  53. enforce: true,
  54. },
  55. },
  56. },
  57. },
  58. plugins: [
  59. new MiniCssExtractPlugin({
  60. filename: 'css/[name].[contenthash].css',
  61. }),
  62. ],
  63. }

Tree Shaking 优化

  1. // tailwind.config.js
  2. module.exports = {
  3. // 精确控制内容范围
  4. content: [
  5. './src/pages/**/*.{js,jsx,ts,tsx}',
  6. './src/components/**/*.{js,jsx,ts,tsx}',
  7. '!./src/**/*.test.{js,jsx,ts,tsx}',
  8. '!./src/**/*.stories.{js,jsx,ts,tsx}',
  9. ],
  10. // 禁用未使用的核心插件
  11. corePlugins: {
  12. float: false,
  13. clear: false,
  14. objectFit: false,
  15. },
  16. // 减少变体
  17. variants: {
  18. extend: {
  19. backgroundColor: ['hover', 'focus'],
  20. textColor: ['hover', 'focus'],
  21. opacity: ['hover', 'disabled'],
  22. },
  23. },
  24. }

缓存策略

构建缓存

  1. // webpack.config.js
  2. module.exports = {
  3. output: {
  4. filename: '[name].[contenthash].js',
  5. path: path.resolve(__dirname, 'dist'),
  6. clean: true,
  7. },
  8. cache: {
  9. type: 'filesystem',
  10. version: `${process.env.NODE_ENV}-${Date.now()}`,
  11. buildDependencies: {
  12. config: [__filename],
  13. },
  14. name: process.env.NODE_ENV === 'production'
  15. ? 'production-cache'
  16. : 'development-cache',
  17. },
  18. }

依赖缓存

  1. // package.json
  2. {
  3. "scripts": {
  4. "build": "cross-env NODE_ENV=production webpack",
  5. "build:cache": "cross-env NODE_ENV=production CACHE=true webpack"
  6. }
  7. }
  8. // webpack.config.js
  9. const useCache = process.env.CACHE === 'true';
  10. module.exports = {
  11. // ...其他配置
  12. cache: useCache ? {
  13. type: 'filesystem',
  14. // ...缓存配置
  15. } : false,
  16. }

并行处理

多进程构建

  1. // webpack.config.js
  2. const ThreadsPlugin = require('threads-plugin');
  3. module.exports = {
  4. module: {
  5. rules: [
  6. {
  7. test: /\.jsx?$/,
  8. use: [
  9. {
  10. loader: 'thread-loader',
  11. options: {
  12. workers: require('os').cpus().length - 1,
  13. },
  14. },
  15. 'babel-loader',
  16. ],
  17. },
  18. ],
  19. },
  20. plugins: [
  21. new ThreadsPlugin(),
  22. ],
  23. }

资源并行加载

  1. <!-- public/index.html -->
  2. <head>
  3. <link
  4. rel="preload"
  5. href="/css/main.[hash].css"
  6. as="style"
  7. >
  8. <link
  9. rel="preload"
  10. href="/js/main.[hash].js"
  11. as="script"
  12. >
  13. </head>

监控与分析

构建分析

  1. // webpack.analyze.js
  2. const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
  3. module.exports = {
  4. plugins: [
  5. new BundleAnalyzerPlugin({
  6. analyzerMode: 'static',
  7. reportFilename: 'bundle-report.html',
  8. openAnalyzer: false,
  9. generateStatsFile: true,
  10. statsFilename: 'bundle-stats.json',
  11. }),
  12. ],
  13. }

性能监控

  1. // utils/performance.ts
  2. export const measureBuildPerformance = () => {
  3. const startTime = process.hrtime();
  4. return () => {
  5. const endTime = process.hrtime(startTime);
  6. const duration = (endTime[0] * 1000 + endTime[1] / 1e6).toFixed(2);
  7. console.log(`Build completed in ${duration}ms`);
  8. return {
  9. duration,
  10. timestamp: Date.now(),
  11. };
  12. };
  13. };

部署优化

CI/CD 配置

  1. # .github/workflows/build.yml
  2. name: Build and Deploy
  3. on:
  4. push:
  5. branches: [main]
  6. jobs:
  7. build:
  8. runs-on: ubuntu-latest
  9. steps:
  10. - uses: actions/checkout@v2
  11. - name: Setup Node.js
  12. uses: actions/setup-node@v2
  13. with:
  14. node-version: '16'
  15. cache: 'npm'
  16. - name: Install dependencies
  17. run: npm ci
  18. - name: Build
  19. run: npm run build
  20. - name: Upload artifacts
  21. uses: actions/upload-artifact@v2
  22. with:
  23. name: build
  24. path: dist

自动化部署

  1. // scripts/deploy.js
  2. const { exec } = require('child_process');
  3. const path = require('path');
  4. const deployToServer = async () => {
  5. try {
  6. // 构建项目
  7. await exec('npm run build');
  8. // 压缩构建文件
  9. await exec('tar -czf dist.tar.gz dist/');
  10. // 上传到服务器
  11. await exec('scp dist.tar.gz user@server:/path/to/deploy');
  12. // 在服务器上解压并部署
  13. await exec(
  14. 'ssh user@server "cd /path/to/deploy && ' +
  15. 'tar -xzf dist.tar.gz && ' +
  16. 'rm dist.tar.gz"'
  17. );
  18. console.log('部署成功');
  19. } catch (error) {
  20. console.error('部署失败:', error);
  21. }
  22. };
  23. deployToServer();

最佳实践

  1. 开发环境

    • 使用快速的 sourcemap
    • 启用热模块替换
    • 优化缓存策略
  2. 生产环境

    • 最小化bundle大小
    • 优化资源加载
    • 实施代码分割
  3. 构建性能

    • 使用并行处理
    • 实施增量构建
    • 优化依赖管理
  4. 监控分析

    • 跟踪构建性能
    • 分析bundle内容
    • 监控部署过程