工程化相关知识

156 阅读6分钟

CommonJS和ESM区别?

运行时机不同

Commonjs: 在加载时运行,所以在require的时候就会被加载执行。

ESM: 在编译时运行,在编译的过程即确定好依赖关系。

依赖关系

Commonjs:动态加载依赖,可以根据环境变量或配置来判断在运行时候加载哪一个模块。

ESM: 使用import语句来加载模块,这些语句在编译时是静态的,即依赖关系在模块被解析时就已经确定。

静态分析

Commonjs:很难分析模块的依赖关系。

ESM: 因为ESM依赖是静态的,即依赖关系在模块被解析时就已经确定,所以可以在不执行代码的情况下分析模块的依赖关系,对tree shaking这种优化很重要。

导出方式不同

Commonjs: 导出导入分别为Module.exports/exports,require方式

ESM: 导入导出分别使用import,export方式

严格模式

Commonjs: commonjs默认不开启严格模式。

ESM: ESM默认开启严格模式。

应用场景

Commonjs: 广泛应用于服务端(Nodejs),不能直接运行在浏览器中,想要应用在浏览器中,需要借助工具进行打包转换。

ESM: 可直接使用在浏览器中,老旧的浏览器可能需要Babel工具进行转换。

前端性能优化/首屏加载过慢优化

页面渲染优化

  1. v-if和v-show使用场景的选择。
  2. 避免v-if和v-for同时使用。
  3. 使用组件化,进行组件复用,减少d不必要的dom操作和渲染。
  4. 使用浏览器缓存,对不经常变动的图片设置合适缓存头进行缓存。
  5. 添加样式或大小的时候尽量使用类的方式进行添加,避免频繁的引发页面的回流和重绘。

资源加载优化

  1. webpack的loader对图片和文件进行压缩。
  2. 通过Tree Shaking,删除未使用到的代码和依赖,减少最后的打包体积。
  3. 开启GZIP压缩
  4. 使用按需加载,图片懒加载,路由懒加载
  5. 使用缓存,减少对服务器频繁请求
  6. 第三方包引入CDN加速

CDN原理

CDN是什么?

CDN就是内容分发网络,通过部署在各地的服务器,使用户能够就近获得所需要的内容。

CDN的作用

降低网络阻塞,提高用户的访问速度。

CDN的技术原理

  1. 用户在访问网站的时候,先进行DNS解析,
  2. 本地的DNS服务器将解析请求转发至网站的DNS服务器,
  3. CDN网络中的GLB系统对域名进行智能解析,将响应速度最快的节点IP返回给用户,
  4. 用户得到ip后,向CDN节点发起访问请求,
  5. CDN节点将回到源站获得用户请求的数据并发给用户,同时CDN节点根据缓存策略对该数据进行缓存;
  6. 当有其他用户再次访问同样内容时,CDN节点直接将数据返回给客户,完成请求过程。

webpack构建流程

  1. 读取配置文件: webpack首先会读取项目的配置文件,(...congig.js),该配置文件包含了构建过程中的各项设置,如入口文件,输出的目录,loder,plugins等。
  2. 解析入口文件: webpack会根据入口文件来解析应用的依赖关系,入口文件通常是应用程序的主要js文件,当然也可以有多个入口。
  3. 依赖解析: webpack分析入口文件和其依赖的模块,构建一个依赖关系图,来确定哪些模块依赖于其它模块以及它们之间的依赖关系。
  4. 加载器处理: webpack会根据各种loader来处理不同类型的资源,例如图片,字体,css等。loader允许开发人员在构建过程中转换这些资源文件,以便最后输出到文件中。
  5. 插件处理: webpack提供可插件系统,这些插件可以执行各种任务,比如代码压缩,资源优化,如热模块更新等。
  6. 生成输出文件: webpack根据入口文件和依赖关系图生成一个或者多个文件,包含js文件,css文件,图片,字体资源等。
  7. 优化和代码压缩: webpack会进行各种优化,理由代码压缩,Tree Sharking,懒加载,以减少包的资源大小并提高性能。
  8. 生成soure Maps: webpack生成映射文件,将最终输出的文件映射回原始源代码,以便在开发中调试。
  9. 输出到指定目录: 经构建结果输出到配置文件指定的目录中,通常为dist目录下。输出文件目录以及结构可以根据配置自定义。
  10. 完成构建: 构建文成后,生成构建报告,包括构建成功失败的信息,输出文件大小等统计信息。

webpack中loaders和plugins的区别

处理对象不同

  • Loaders用于对一些文件(css,图片,字体等)进行转换和处理,使得这些文件能被webpack打包。
  • Plugins执行更广泛得任务,打包优化,资源管理以及注入环境变量等。

处理的阶段不同

  • Loaders在模块加载得时候对文件进行转换。
  • Plugins在整个编译和打包过程中执行。

使用方式不同

  • Loaders通过配置module.rules来使用。
  • Plugins在plugins中配置使用。

为什么webpack不设计为都使用plugins来处理

职责单一

Loaders主要做文件转换,Plugins专注于打包的优化和资源管理等, 有助于保持每项的职责单一

灵活性

二者分开,提高了webpack配置的灵活性,用户可以更好理解和配置文件的转换和构建的优化。

简化配置

Loaders 专注于文件转换,并且可以使用链式(执行顺序从右到左)调用的方式简化了配置和理解。 Plugins 则专注于复杂的构建过程中的操作,不需要关心具体的文件处理。

vite打包基本配置

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";

// https://vitejs.dev/config/
export default defineConfig(({ command }) => {
  console.log(command, __dirname);
  return {
    // 共享配置
    mode: "development", //配置开发模式
    define: {
      //定义全局常量
      _APP_VERSION: JSON.stringify("v1.0.0"),
    },
    resolve: {
      alias: {
        //配置路径别名
        "@": path.resolve(__dirname, "src"),
      },
      extensions: [".mjs", ".js", ".mts", ".ts", ".jsx", ".tsx", ".json"], //自定义省略导入文件扩展名
    },
    plugins: [
      //插件配置
      {
        ...vue(),
      },
    ],
    //服务器选项配置
    server: {
      port: 5000, //自定义启动服务端口号,默认值5173
      open: true, //启动服务后是否自动打开浏览器
      cors: true, //为开发服务器配置cors,默认允许任何源
      proxy: {
        //为服务配置自定义代理规则
        //配置代理,解决常见跨域问题
        "/api": {
          target: "http://localhost:8080", //将/api开头的请求转发到这个地址上
          changeOrigin: true, //是否需要修改请求头的origin值,避免后端设置origin限制引起跨域问题
          rewrite: (path) => path.replace(/^\/api/, ""), //重写请求路径,这里/api/user会被转发到/user路径上
        },
      },
    },
    // 构建配置
    build: {
      target: "modules", //最终构建的浏览器兼容目标,默认modules
      outDir: "dist", //自定义输出目录,默认dist
      assetsDir: "build", //自定义静态资源目录
      sourcemap: true, //是否生成sourcemap文件,默认false
      emptyOutDir: true, //构建时清理输出目录,如果输出目录在根目录下则默认为true
    },
  };
});