从多个方面详述build:prod

发布时间:2023-05-19

一、build:prod概述

build:prod 是指在项目开发完成之后,将代码打包成最终可以上线的版本。一般而言,通过 build:prod 进行打包会减小代码大小、提高性能、优化体验以及保障安全等方面的目标。 在 Vue 项目中,我们可以通过执行 npm run build:prod 来进行打包,最终的打包文件会生成在 /dist 目录下。下面我们将从代码优化、性能提升、体验优化、安全保障等方面对 build:prod 进行详细阐述。

二、代码的优化

在代码的优化方面,主要从三个方面入手:文件压缩、代码分割和 Tree Shaking。

1、文件压缩

// bable.config.js
module.exports = {
  ...
  // 压缩JS代码
  presets: [
    ['@babel/preset-env', {
      useBuiltIns: false,
      corejs: false,
      modules: false,
      targets: {
        browsers: [
          '> 1%',
          'last 2 versions',
          'not ie <= 8',
        ],
      },
    }],
  ],
  // 压缩CSS代码
  plugins: [
    ...
    new OptimizeCSSAssetsPlugin({
      assetNameRegExp: /\.css$/g,
      cssProcessor: require('cssnano'),
      cssProcessorPluginOptions: {
        preset: ['default', {
          discardComments: {
            removeAll: true,
          },
          normalizeUnicode: false,
        }],
      },
      canPrint: true,
    }),
    ...
  ],
}

以上的配置表明了在打包生产环境的文件时,需要对 JS 和 CSS 代码进行压缩。其中使用了 @babel/preset-envcssnano 等第三方库进行压缩,同时可以选择移除注释、一些特殊字符等内容,从而减小文件大小。

2、代码分割

// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
module.exports = {
  ...
  // 使用webpack的splitChunks进行代码分割
  optimization: {
    splitChunks: {
      chunks: 'all',
      name: 'vendor',
    },
  },
  plugins: [
    ...
    // 使用HtmlWebpackPlugin注入产生的vendor.js
    new HtmlWebpackPlugin({
      ...
      chunks: ['vendor', 'main'],
      ...
    }),
    ...
  ],
  ...
};

以上的配置表明了在打包生产环境的文件时,webpack 会将代码拆分成多个文件,这些文件会被单独引入,从而减少页面加载时间。

3、Tree Shaking

// webpack.config.js
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
  ...
  // 开启Tree Shaking,需要使用uglifyjs压缩JS代码
  optimization: {
    minimize: true,
    minimizer: [new UglifyJSPlugin({
      cache: true,
      parallel: true,
      sourceMap: false,
      extractComments: false,
      uglifyOptions: {
        // 开启Tree Shaking
        compress: {
          unused: true,
          drop_debugger: true,
          drop_console: true,
          pure_funcs: ['console.log'],
        },
      },
    })],
  },
  ...
};

以上的配置表明了在打包生产环境的文件时,会进行 Tree Shaking 机制,去掉无用的代码。开启 Tree Shaking 需要使用 uglifyjs 插件。

三、性能的提升

在性能的提升方面,主要从两个方面入手:打包速度和页面加载速度。

1、打包速度

// vue.config.js
module.exports = {
  ...
  // 开启parallel配置来提高打包速度
  configureWebpack: {
    ...
    plugins: [],
    performance: {
      hints: false,
    },
  },
  parallel: require('os').cpus().length > 1,
  ...
};

以上的配置表明了在打包生产环境的文件时,开启 parallel 配置可以提高打包速度。

2、页面加载速度

// vue.config.js
module.exports = {
  ...
  // 对静态资源进行gzip压缩
  configureWebpack: {
    ...
  },
  pluginOptions: {
    compression: {
      algorithm: 'gzip',
      test: /\.js$|\.html$|\.json$|\.css/,
      threshold: 10240,
      minRatio: 0.8,
      deleteOriginalAssets: false,
    },
  },
  ...
};

以上的配置表明了在打包生产环境的文件时,对静态资源进行 gzip 压缩以减小文件大小,从而提高页面加载速度。

四、体验的优化

在体验的优化方面,主要从两个方面入手:打包文件的结果进行分析以及 Web Workers。

1、打包文件的结果进行分析

module.exports = {
  ...
  // 分析打包文件的结果
  plugins: [
    ...
    new BundleAnalyzerPlugin({
      analyzerMode: 'static',
      openAnalyzer: false,
    }),
    ...
  ],
  ...
};

以上的配置表明了在打包生产环境的文件时,可以分析打包文件的结果,以便了解打包文件是否有冗余代码以及文件大小占比等信息,从而进行相应的优化。

2、Web Workers

// 异步处理用户数据
if (window.Worker) {
  const worker = new Worker('./user.worker.js');
  worker.onmessage = (event) => {
    console.log(event.data);
  };
  worker.postMessage({
    type: 'getText',
    message: 'bundle',
  });
} else {
  // fallback
}

以上的代码表明了使用 Web Workers 进行异步处理,可以在页面处理数据时提高响应速度,从而优化用户体验。

五、安全保障

在安全保障方面,主要从两个方面入手:CSRF 攻击和 XSS 攻击。

1、CSRF 攻击

// vue.config.js
module.exports = {
  ...
  // 在webpack.config.js中使用CopyWebpackPlugin拷贝不经过处理的静态资源代码
  // 在vue.config.js中使用compression-webpack-plugin压缩静态资源代码
  configureWebpack: {
    ...
    plugins: [
      ...
      new CopyWebpackPlugin([{
        from: path.resolve(__dirname, 'src/assets'),
        to: path.resolve(__dirname, 'dist/assets'),
        ignore: ['.*'],
      }]),
      ...
    ],
  },
  pluginOptions: {
    compression: {
      algorithm: 'gzip',
      test: /\.js$|\.html$|\.json$|\.css/,
      threshold: 10240,
      minRatio: 0.8,
      deleteOriginalAssets: false,
    },
  },
  ...
};

以上的配置表明了在打包生产环境的文件时,可以使用 CopyWebpackPlugin 拷贝不经过处理的静态资源代码,并使用 compression-webpack-plugin 压缩静态资源代码,从而避免被黑客在前端代码中注入恶意代码,防止 CSRF 攻击。

2、XSS 攻击

// 引入DOMPurify库进行HTML过滤
import DOMPurify from 'dompurify';
...
this.$refs.content.innerHTML = DOMPurify.sanitize(this.html);

以上的代码表明了在前端页面渲染 HTML 代码时,可以使用 DOMPurify 库进行 HTML 过滤,从而防止被黑客在前端代码中注入恶意代码,防止 XSS 攻击。