前端工程化实践(一):老项目工程化升级改造

本文正在参加「金石计划」

目录

前端功能化概念

前端工程化解决的问题

前端工程化解决解决的问题包含前端开发效率,开发规范,访问性能等。

传统前端开发会碰到的问题以及解决方案

  • js全局作用域冲突问题,解决:模块化 npm webpack
  • 编码规范问题,解决:eslint
  • 资源合并和压缩问题,解决:webpack
  • 高版本js预发降级,解决:es6降级es5使用babel等工具

前端工程化应用场景

企业中存在的前端问题:

  • 解决研发流程中的问题
  • 工程化核心目标是效率、规范、性能
  • 对研发流程中的痛点进行诊断优化
    • 项目量级增加:几千行代码=>几万行代码,解决:模块化
    • 项目数量扩大:几个=> 几千个,解决:研发脚手架,研发平台
    • 项目复杂度高:web项目=>H5/PC/小程序/脚手架…,解决:工程脚手架

如何解决这些问题:

  • 项目研发模式升级,模块化
  • 工程脚手架(vue、react等等)
  • 研发脚手架(创建、发布)
  • 项目性能优化

模块化

什么是前端模块化

  • 将复杂的程序根据需求拆分成若干个模块,一个模块包括输入和输出
  • 模块内部是私有的,对外暴露接口和其他模块通信
  • 一个html页面可以引用的script包括:脚本和模块

CommonJS

CommonJS介绍

  • Node.js默认模块化规范, 每个文件就是一个模块,有自己的作用域
  • Node中CJS模块加载采用同步加载方式
  • 通过require加载模块,通过exports或module.exports输出模块

CommonJS规范特点

  • 所有代码都运行在模块作用域,不会污染全局作用域。
  • 模块可以多次加载,第一次加载时会运行模块,模块输出结果会被向缓存,再次加载时,会从缓存结果中直接读取模块输出结果。
  • 模块加载的顺序按照其在代码中出现的顺序。

AMD

  • AMD规范采用非同步加载模块,允许指定回调函数
  • Node模块通常都位于本地,加载速度快,所以适用于同步加载
  • 浏览器环境下,模块需要请求获取,所以适用于异步加载
  • require.js是AMD的一个具体实现库

CMD

  • CMD整合了CommonJS和AMD的优点,模块加载是异步的
  • CMD专门用于浏览器端,sea.js是CMD规范的一 个实现
  • AMD和CMD最大的问题是没有通过语法升级解决模块化

ESModule

ESModule规范介绍

  • ESModule设计理念是希望在编译时就确定模块依赖关系及输入输出
  • CommonJS和AMD必须在运行时才能确定依赖和输入、输出
  • ESM通过import加载模块,通过export输出模块

ESModule和CommonJS对比

  • CommonJS模块输出的是值的拷贝,ES6模块输出的是值的引用
  • CommonJS模块是运行时加载,ES6模块是编译时输出接口
  • CommonJs是单个值导出,ES6 Module可以导出多个

实战前言

如果对webpack不熟悉的同学可以提前预习一下我之前的文章 构建webpack5知识体系【近万字总结】
本篇文章带你从0完成对一个老项目的工程化改造,学习本篇文章你将会掌握以下技能:

  • 工程化基本概念
  • webpack的熟练配置和优化技巧
  • 对老项目工程化升级

本文章采用开源项目 ZBestPC 来改造。

项目源码地址:github.com/NewCoder798…

项目架构改造难点:

  • 资源合并和拆分
  • 拆分粒度如何
  • 用webpack如何控制

问题分析

原始项目中存在的问题:

  • css和js资源多,且全部采用同步加载,渲染时需多次请求和加载,降低页面加载性能
  • css和js源码未压缩
  • 开发模式陈旧,需要同时维护html、js和css, 代码逻辑和结构不清晰,迭代困难
  • 项目不支持source-map,调试困难,手动维护source-map成本大

项目需求

  • 第一阶段:项目webpack改造,使原生js项目能够支持模块开发及打包
  • 第二阶段: Vue SPA (单页应用)改造,使项目能够使用Vue进行单页应用开发
  • 第三阶段: Vue MPA (多页应用)改造,使项目能够使用Vue进行多页应用开发

项目webpack改造

项目初始化

目录规划

前端工程化实践(一):老项目工程化升级改造

创建npm项目安装webpack依赖

npm init -y
npm install webpack webpack-cli

创建js入口文件

前端工程化实践(一):老项目工程化升级改造

创建webpack配置文件

// webpack.config.js
const path = require("path");

module.exports = {
  mode: "development",
  entry: "./src/index.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "./dist"),
  },
};

配置package.json命令

// package.json
{
  "name": "pc_update",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

执行 npm run build 生成结果

npm run build

添加html页面,引入打包后的js文件。
前端工程化实践(一):老项目工程化升级改造
出现打印信息则表示成功。
前端工程化实践(一):老项目工程化升级改造

本小结源码地址

源码地址:github.com/linhexs/old…

首页移植

资源文件拷贝

资源文件拷贝,将源码中html/js/ css/img文件拷贝至新项目中:

  1. 将index.html拷贝至src/index.html
  2. 将js目录拷贝至src/js
  3. 将css目录拷贝至src/css
  4. 将img目录拷贝至src/img

删除引用

删除src/index.html 中所有link 和script的引用。
需要注意的是下面这一段不是外链引入的不能删除。
前端工程化实践(一):老项目工程化升级改造

安装插件配置信息

安装html-webpack-plugin插件

npm install html-webpack-plugin --save-dev

在webpack.config.js添加html-webpack-plugin配置信息

// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");

module.exports = {
  mode: "development",
  // 新修改entry
  entry: {
    bundle: "./src/index.js", 
  },
  // 新修改output
  output: {
    filename: "[name].js", 
    path: path.resolve(__dirname, "./dist"),
  },
  // 添加插件信息
  plugins: [
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: "./src/index.html",
    }),
  ],
};

重新执行 npm run build 会在dist目录下生成两个文件。
前端工程化实践(一):老项目工程化升级改造
index.html文件中会异步引入bundle.js文件。
前端工程化实践(一):老项目工程化升级改造

添加css引用

在src/index.js中添加 css 引用

import './css/public.css'
import './css/index.css'

安装css-loader、style-loader

npm install css-loader style-loader -D

添加css-loader、style-loader配置

// webpack.config.js
module.exports = {
  // ...省略其他配置...
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};

添加图片处理

图片处理采用webpack内置 asset 模块,添加文件处理配置 parsergenerator

 module: {
    // ...省略其他配置...
    rules: [
      // ...省略其他配置...
      // 图片处理
      {
        test: /\.(png|jpg|svg|jpeg|gif)$/i,
        type: "asset",
        parser: {
          // 如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。
          dataUrlCondition: {
            maxSize: 8 * 1024,
          },
        },
        // 输出目录
        generator: {
          filename: "images/[name].[hash:6][ext]",
        },
      },
    ],
  },

执行npm run build命令,发现有两处报错。
前端工程化实践(一):老项目工程化升级改造
这里需要注意的是:它源码包中没有这两个图片,所以我们需要注释掉这两断引入图片的css代码。
前端工程化实践(一):老项目工程化升级改造
前端工程化实践(一):老项目工程化升级改造
重新执行npm run build,打包成功。
前端工程化实践(一):老项目工程化升级改造
前端工程化实践(一):老项目工程化升级改造

引用js文件

在src/index.js中添加js引用

import './js/jquery-1.12.4.min'
import './js/public'
import './js/nav'
import './js/jquery.flexslider-min'

执行npm run build,打包好后我们在浏览器打开dist/html文件,发现jquery的$没定义。

前端工程化实践(一):老项目工程化升级改造
我们来解决一下jquery的$没定义的这个问题。
安装jquery和flexslider。

npm install -S jquery flexslider -D

在webpack.config.js插件中使用 ProvidePlugin 配置jquery。

 plugins: [
    // ...省略...
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
    }),
  ],

修改src/index.js模块引入。

// src/index.js
import './css/public.css'
import './css/index.css'

import 'jquery'
import './js/public'
import './js/nav'

“删除引用” 的小章节中,我们src/index.html中留下一段js代码。
前端工程化实践(一):老项目工程化升级改造
我们将这段代码移入到src/js/nav.js中,并且引入flexslider。

// src/js/nav.js

// 引入flexslider
import 'flexslider'

// 导航固定顶部
$(function () {
  $(window).scroll(function () {
    var ws = $(window).scrollTop();
    if (ws > 60) {
      $(".head")
        .addClass("ding")
        .css({ background: "rgba(255,255,255," + ws / 300 + ")" });
    } else {
      $(".head").removeClass("ding").css({ background: "#fff" });
    }
  });
});

$(function () {
  $("#home_slider").flexslider({
    animation: "slide",
    controlNav: true,
    directionNav: true,
    animationLoop: true,
    slideshow: true,
    slideshowSpeed: 2000,
    useCSS: false,
  });
});

重新打包npm run build,来看一下控制台已经不报$没定义的错误了,不过还存在着大量图片找不到,这是因为我们src/index.html的图片地址路径不正确,我们来替换一下。
前端工程化实践(一):老项目工程化升级改造
替换完成后重新打包,在浏览器中打开dist/html页面,会看到报错全部消失了,页面也完美呈现了。
前端工程化实践(一):老项目工程化升级改造

源码地址

源码地址:github.com/linhexs/old…

登录页移植

通过对首页的移植,已经大致明白了移植的流程。这里只简单写一下。

插件配置

  plugins: [
    // ...省略...
    new HtmlWebpackPlugin({
      filename: "login.html",
      template: "./src/login.html",
    }),
  ],

引入login页面link文件

前端工程化实践(一):老项目工程化升级改造
大家可以参考源代码自己移植一下。

源码地址

源码地址:github.com/linhexs/old…

项目优化

js分离

存在的问题

目前index.html和login.html同时引用了bundle.js,bundle.js对应src/index.js, 该文件同时引用了index.html
和login.html的依赖资源,这样会导致src/index.js随项目规模扩大越来越臃肿。
前端工程化实践(一):老项目工程化升级改造
前端工程化实践(一):老项目工程化升级改造
此时的bundle.js大小为466kb。
前端工程化实践(一):老项目工程化升级改造

要解决这个问题需要指定index.html和login.html分别引用不同的js文件,这就需要涉及webpack多入口配置。

多入口配置

创建login.js,将login相关内容写入,同时删除index.js中login相关内容。
前端工程化实践(一):老项目工程化升级改造
配置webpack文件为多入口,同时配置chunks。
前端工程化实践(一):老项目工程化升级改造
执行npm run build,发现文件从原来的466kb减小到53.8kb。
前端工程化实践(一):老项目工程化升级改造

增加开发模式

dev-server

目前我们改造的项目每次修改内容都需要重新打包,所以这阶段我们需要做的是支持开发模式提升效率。
安装 webpack-dev-server

npm i -D webpack-dev-server

添加webpack-dev-server配置。

module.exports = {
  
  /** ...省略其他配置... **/
  
  devServer: {
    static: {
      directory: path.resolve(__dirname, '../dist'),
    },
    compress: true,
    port: 8000,
    hot: true,
  },
  
  /** ...省略其他配置... **/
  
}

添加启动命令。
前端工程化实践(一):老项目工程化升级改造
执行npm run start,打开localhost:8000,发现图片路径丢失,那么我们接下来我们来解决这个问题。
前端工程化实践(一):老项目工程化升级改造

copy-plugin

我们从上一节的截图可以看到页面的图片路径不正确,所以图片加载不出来,我们安装 CopyWebpackPlugin 插件将src里面的图片都copy到dist里面。
安装copy-webpack-plugin插件

npm i -D copy-webpack-plugin

添加webpack-dev-server配置。

const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
const webpack = require("webpack");
const CopyPlugin = require("copy-webpack-plugin");

module.exports = {
  
  /** ...省略其他配置... **/
  
  plugins: [
    
    /** ...省略其他配置... **/
    
    new CopyPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, "./src/img"),
          to: path.resolve(__dirname, "./dist/img"),
        },
      ],
    }),
  ],
};

替换图片路径。
前端工程化实践(一):老项目工程化升级改造
重新执行npm run start,打开页面,发现已经没问题了。
前端工程化实践(一):老项目工程化升级改造

本小节源码地址

源码地址:github.com/linhexs/old…

剥离css文件

安装插件 MiniCssExtractPlugin

npm install --save-dev mini-css-extract-plugin

修改mini-css-extract-plugin配置。

const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
const webpack = require("webpack");
const CopyPlugin = require("copy-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  
  /** ...省略其他配置... **/
  
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          MiniCssExtractPlugin.loader,
          { loader: 'css-loader' },
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "css/[name].css",
      chunkFilename: "css/[name].chunk.css",
    }),
  ],
};

重新打包,css文件已经抽离出来了,当然js文件大小也会减少,可以自己体验一下。
前端工程化实践(一):老项目工程化升级改造

文件压缩

js和css文件压缩

安装插件 UglifyJsPluginOptimizeCssAssetsPlugin

npm install --save-dev uglifyjs-webpack-plugin
npm install --save-dev css-minimizer-webpack-plugin

添加webpack压缩配置。

const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');

const config = {

  /** ...省略其他配置... **/
  
  optimization: {
    minimize: true, //代码压缩
    minimizer: [
      new UglifyJsPlugin(),
      new CssMinimizerPlugin(),
    ],
  },
}

本小节源码地址:github.com/linhexs/old…

treeshaking触发条件

  • 通过解构的方式获取方法, 可以触发treesiaking
  • 调用的npm包必须使用ESM
  • 同一文件的treeshaking有触发条件,条件就是mode=production
  • 一定要注意使用解构来加载模块

代码分割

这里我们在src/index.js中加入了一个lodash。
前端工程化实践(一):老项目工程化升级改造
分割前效果:
前端工程化实践(一):老项目工程化升级改造
利用 splitChunks 来进行拆分。

const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
const webpack = require("webpack");
const CopyPlugin = require("copy-webpack-plugin");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');

module.exports = {
  
  /** ...省略其他配置... **/
  
  optimization: {
    minimize: true, //代码压缩
    minimizer: [
      new UglifyJsPlugin(),
      new CssMinimizerPlugin(),
    ],
    // 分包
    splitChunks: {
      minSize: 5 * 1024,
      chunks: 'all',
      name: 'common',
      automaticNameDelimiter: '_',
      cacheGroups: {
        jquery: {
          name: 'jquery',
          chunks: 'all',
          test: /jquery\.js/,
        },
        'lodash': {
          name: 'lodash',
          chunks: 'all',
          test: /lodash/,
        }
      },
    },
  },
};

拆分后效果,只看红框内标出的即可:
前端工程化实践(一):老项目工程化升级改造
可以看出包单个包明显体积减少了。
本小节源码地址:github.com/linhexs/old…

公共文件提取

添加ejs抽取header和footer部分。
前端工程化实践(一):老项目工程化升级改造
在html页面引入ejs。
前端工程化实践(一):老项目工程化升级改造
添加ejs-loader解析。

npm install ejs-loader -D
 module: {
   
    /** ...省略其他配置... **/
   
    rules: [
      {
        test: /\.ejs/,
        loader: "ejs-loader",
        options: {
          esModule: false,
        },
      },
    ],
  },

清空dist目录

使用CleanWebpackPlugin插件对dist目录清理。

npm install clean-webpack-plugin -D
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  /** ...省略其他配置... **/
  plugins: [
    new CleanWebpackPlugin(),
  ],
};

小结代码:github.com/linhexs/old…

webpack配置完整代码

const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
const webpack = require("webpack");
const CopyPlugin = require("copy-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  mode: "development",
  entry: {
    index: "./src/index.js",
    login: "./src/login.js",
  },
  devServer: {
    static: {
      directory: path.resolve(__dirname, "../dist"),
    },
    compress: true,
    port: 8000,
    hot: true,
  },
  output: {
    filename: "js/[name].js",
    path: path.resolve(__dirname, "./dist"),
  },
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, { loader: "css-loader" }],
      },
      {
        test: /\.(png|jpg|svg|jpeg|gif)$/i,
        type: "asset",
        parser: {
          // 如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。
          dataUrlCondition: {
            maxSize: 8 * 1024,
          },
        },
        // 输出目录
        generator: {
          filename: "images/[name].[hash:6][ext]",
        },
      },
      {
        test: /\.ejs/,
        loader: "ejs-loader",
        options: {
          esModule: false,
        },
      },
    ],
  },
  optimization: {
    minimize: true, //代码压缩
    minimizer: [new UglifyJsPlugin(), new CssMinimizerPlugin()],
    splitChunks: {
      minSize: 5 * 1024,
      chunks: "all",
      name: "common",
      automaticNameDelimiter: "_",
      cacheGroups: {
        jquery: {
          name: "jquery",
          chunks: "all",
          test: /jquery\.js/,
        },
        lodash: {
          name: "lodash",
          chunks: "all",
          test: /lodash/,
        },
      },
    },
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "css/[name].css",
      chunkFilename: "css/[name].chunk.css",
    }),
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: "./src/index.html",
      chunks: ["index"],
    }),
    new HtmlWebpackPlugin({
      filename: "login.html",
      template: "./src/login.html",
      chunks: ["login"],
    }),
    new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery",
    }),
    new CopyPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, "./src/img"),
          to: path.resolve(__dirname, "./dist/img"),
        },
      ],
    }),
    new CleanWebpackPlugin(),
  ],
};

Vue SPA应用改造

转移webpack文件

我们新建一个build文件,将webpack配置移入进去。
前端工程化实践(一):老项目工程化升级改造
对应要修改我们里面的输出路径,这里我就将源码都粘贴出来,大家对应修改即可。

修改package.json中的scripts命令。

接入vue

安装Vue相关的依赖

这里直接升级为vue3。

创建vue相关代码

创建src/main.js文件

创建src/App.vue文件

创建模版文件

创建public/index.html文件

创建vue配置命令

创建build/webpack.config.vue.js文件,并写入配置。

添加vue打包命令

执行npm run start:vue

页面出现效果则成功。
前端工程化实践(一):老项目工程化升级改造

接入路由

安装依赖

安装 vue-router 依赖。

添加配置

添加 src/router.js。

添加vue-router相关内容

修改 src/main.js,添加 vue-router 相关内容。

修改App.vue。

添加组件

添加Login组件和Home组件,将原来的登录页和首页移植进去,看文章源码,这里就不仔细讲了。

源码地址

源码地址:github.com/linhexs/old…

Vue MPA应用改造

这里先留个悬念,过几天再更新,其实就是配置一个多入口即刻,大家可以自己尝试一下,大家也可以根据现有知识完成对项目React的升级改造和把其他页面移植过来。

webpack优化相关知识点补充

webpack打包优化方向

  • 打包速度:优化打包速度,主要提升开发效率,更快的打包构建过程。
  • 打包体积:优化打包体积,主要是提升产品的使用体验,降低服务器资源成本,更快的页面加载,同时也可以让打包更快

webpack打包速度优化

webpack 进行打包速度优化有七种常用手段

优化 loader 搜索范围

对于 loader 来说,影响打包效率首当其冲必属 Babel 了。因为 Babel 会将代码转为字符串生成 AST,然后对 AST 继续进行转变 最后再生成新的代码,项目越大,转换代码越多,效率就越低。优化正则匹配、使用 include 和 exclude 指定需要处理的文件,忽略不需要处理的文件。

多进程/多线程

受限于 node 是单线程运行的,所以 webpack 在打包的过程中也是单线程的,特别是在执行 loader 的时候,长时间编译的任务很多,这样就会导致等待的情况。我们可以使用一些方法将 loader 的同步执行转换为并行,这样就能充分利用系统资源来提高打包速度了。

分包

在使用 webpack 进行打包时候,对于依赖的第三方库,比如 vue,vuex 等这些不会修改的依赖,我们可以让它和我们自己编写的代码分开打包,这样做的好处是每次更改我本地代码的文件的时候,webpack 只需要打包我项目本身的文件代码,而不会再 去编译第三方库,那么第三方库在第一次打包的时候只打包一次,以后只要我们不升级第三方包的时候,那么 webpack 就不会 对这些库去打包,这样可以快速提高打包的速度。因此为了解决这个问题,DllPlugin 和 DllReferencePlugin 插件就产生了。这种方式可以极大的减少打包类库的次数,只有当类库更新版本才需要重新打包,并且也实现了将公共代码抽离成单独文件的优化方案。

开启缓存

当设置 cache.type: “filesystem” 时,webpack 会在内部以分层方式启用文件系统缓存和内存缓存,将处理结果结存放到内存中。

打包分析工具

显示测量打包过程中各个插件和 loader 每一步所消耗的时间,然后让我们可以有针对的分析项目中耗时的模块对其进行处理。

ignorePlugin

这是 webpack 内置插件, 它的作用是忽略第三方包指定目录,让这些指定目录不要被打包进去,防止在 import 或 require 调用时,生成以下正则表达式匹配的模块.

  • requestRegExp 匹配( test )资源请求路径的正则表达式。
  • contextRegExp( 可选 )匹配( test )资源上下文( 目录 )的正则表达式。

优化文件路径

  • alias:省下搜索文件的时间,让 webpack 更快找到路径
  • mainFiles:解析目录时要使用的文件名
  • extensions:指定需要检查的扩展名,配置之后可以不用在 require 或是 import 的时候加文件扩展名,会依次尝试添加扩展名进行匹配

webpack打包体积优化

webpack打包体积优化有11种常用优化手段

构建体积分析

npm run build 构建,会默认打开: http://127.0.0.1:8888/,可以看到各个包的体积,分析项目各模块的大小,可以按需优化。

项目图片资源优化压缩处理

删除无用的 css 样式

有时候一些项目中可能会存在一些 css 样式被迭代废弃,需要将其删除,可以使用 purgecss-webpack-plugin 插件,该插件可以去除未使用的 css。

代码压缩

开启 Scope Hoisting

Scope Hoisting 又译作“作用域提升”。只需在配置文件中添加一个新的插件,就可以让 webpack 打包出来的代码文件更小、运行 的更快, Scope Hoisting 会分析出模块之间的依赖关系,尽可能的把打包出来的模块合并到一个函数中去,然后适当地重命名一些变量以防止命名冲突。

提取公共代码

将项目中的公共模块提取出来,可以减少代码的冗余度,提高代码的运行效率和页面的加载速度。

代码分离

代码分离能够将工程代码分离到各个文件中,然后按需加载或并行加载这些文件,也用于获取更小的 bundle,以及控制资源加载优先级,在配置文件中配置多入口,输出多个 chunk。

Tree-shaking

tree shaking 是一个术语,通常用于描述移除 JavaScript 上下文中的未引用代码( dead-code )。它依赖于 ES2015 模块语法的静态结构 特性,例如 import 和 export。

CDN 加速

CDN是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN 的关键技术主要有内容存储和分发技术。在项目中以 CDN 的方式加载资源,项目中不需要对资源进行打包,大大减少打包后的文件体积 。

生产环境关闭 sourceMap

sourceMap 本质上是一种映射关系,打包出来的 js 文件中的代码可以映射到代码文件的具体位置,这种映射关系会帮助我们直接找到在源代码中的错误。但这样会使项目打包速度减慢,项目体积变大,可以在生产环境关闭 sourceMap 。

按需加载

在开发项目的时候,项目中都会存在十几甚至更多的路由页面。如果我们将这些页面全部打包进一个文件的话,虽然将多个请求合并了,但是同样也加载了很多并不需要的代码,耗费了更长的时间。那么为了页面能更快地呈现给用户,我们肯定是希望页面能加载的文件体积越小越好,这时候我们就可以使用按需加载,将每个路由页面单独打包为一个文件。以下是常见的按需加载的场景。

  • 路由组件按需加载
  • 按需加载需引入第三方组件
  • 对于一些插件,如果只是在个别组件中用的到,也可以不要在 main.js 里面引入,而是在组件中按需引入

原文链接:https://juejin.cn/post/7220463381492514853 作者:lin嘟嘟嘟

(0)
上一篇 2023年4月11日 上午10:31
下一篇 2023年4月11日 上午10:43

相关推荐

发表回复

登录后才能评论