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工具进行转换。
前端性能优化/首屏加载过慢优化
页面渲染优化
- v-if和v-show使用场景的选择。
- 避免v-if和v-for同时使用。
- 使用组件化,进行组件复用,减少d不必要的dom操作和渲染。
- 使用浏览器缓存,对不经常变动的图片设置合适缓存头进行缓存。
- 添加样式或大小的时候尽量使用类的方式进行添加,避免频繁的引发页面的回流和重绘。
资源加载优化
- webpack的loader对图片和文件进行压缩。
- 通过Tree Shaking,删除未使用到的代码和依赖,减少最后的打包体积。
- 开启GZIP压缩
- 使用按需加载,图片懒加载,路由懒加载
- 使用缓存,减少对服务器频繁请求
- 第三方包引入CDN加速
CDN原理
CDN是什么?
CDN就是内容分发网络,通过部署在各地的服务器,使用户能够就近获得所需要的内容。
CDN的作用
降低网络阻塞,提高用户的访问速度。
CDN的技术原理
- 用户在访问网站的时候,先进行DNS解析,
- 本地的DNS服务器将解析请求转发至网站的DNS服务器,
- CDN网络中的GLB系统对域名进行智能解析,将响应速度最快的节点IP返回给用户,
- 用户得到ip后,向CDN节点发起访问请求,
- CDN节点将回到源站获得用户请求的数据并发给用户,同时CDN节点根据缓存策略对该数据进行缓存;
- 当有其他用户再次访问同样内容时,CDN节点直接将数据返回给客户,完成请求过程。
webpack构建流程
- 读取配置文件: webpack首先会读取项目的配置文件,(...congig.js),该配置文件包含了构建过程中的各项设置,如入口文件,输出的目录,loder,plugins等。
- 解析入口文件: webpack会根据入口文件来解析应用的依赖关系,入口文件通常是应用程序的主要js文件,当然也可以有多个入口。
- 依赖解析: webpack分析入口文件和其依赖的模块,构建一个依赖关系图,来确定哪些模块依赖于其它模块以及它们之间的依赖关系。
- 加载器处理: webpack会根据各种loader来处理不同类型的资源,例如图片,字体,css等。loader允许开发人员在构建过程中转换这些资源文件,以便最后输出到文件中。
- 插件处理: webpack提供可插件系统,这些插件可以执行各种任务,比如代码压缩,资源优化,如热模块更新等。
- 生成输出文件: webpack根据入口文件和依赖关系图生成一个或者多个文件,包含js文件,css文件,图片,字体资源等。
- 优化和代码压缩: webpack会进行各种优化,理由代码压缩,Tree Sharking,懒加载,以减少包的资源大小并提高性能。
- 生成soure Maps: webpack生成映射文件,将最终输出的文件映射回原始源代码,以便在开发中调试。
- 输出到指定目录: 经构建结果输出到配置文件指定的目录中,通常为dist目录下。输出文件目录以及结构可以根据配置自定义。
- 完成构建: 构建文成后,生成构建报告,包括构建成功失败的信息,输出文件大小等统计信息。
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
},
};
});