面试篇-webpack+vite

文章目录

webpack及vite知识点

webpack(vue2)

一、webpack定义

  • webpack是一个js模块打包工具 ,使用它管理项目中的模块依赖 ,并编译输出模块所需的静态文件
  • webpack基于入口 ,会自动地递归解析入口所需要加载 的所有资源文件
  • 将webpack中的各种资源模块 进行打包合并成一个或多个包(Bundle)
  • 打包的过程 中用loader来处理不同的文件 (webpack原生只能解析js代码,若要其他文件也打包,需要loader);用plugin扩展webpack功能

二、webpack安装配置

  • 安装npm install --save-dev webpack webpack-cli
  • 配置:
    • 项目根目录 创建webpack.config.js
    • 编写webpack.config.js初始化配置
    • package.jsonscripts节点中加入配置
    • 修改入口文件,添加添加语句:<script src ="/bundle.js"></script>
    • 启动:
      • 开发模式 : 使用 npm run serve 启动开发服务器,支持热重载。
      • 生产模式 : 使用 npm run build 构建项目,生成的文件会放在 dist 目录下。
bash 复制代码
//局部安装,--save-dev(或简写 -D)表示将 Webpack 作为开发依赖,‌不包含在生产构建中
npm install --save-dev webpack webpack-cli
//全局安装:官方明确不推荐‌此做法,因为会锁定全局版本,导致不同项目间出现兼容性问题
npm install -g webpack webpack-cli

webpack.config.js

javascript 复制代码
const path = require('path')
module.exports = {
    entry : "./src/main.js",
    output: {
        path: path.resolve(__dirname,'dist'), //动态获取绝对路径,__dirname是node中全局变量
        filename :  "bundle.js"
    },
}

packge.json

json 复制代码
"build": "webpack --mode production",
"dev": "webpack serve --mode development",
// "serve": "vue-cli-service serve --no-lint",
// "build": "vue-cli-service build --no-lint",

入口文件index.html

html 复制代码
<body>
	<script src ="/bundle.js"></script>
</body>

三、Webpack配置项

  • mode:用来指定构建方式 ,可选值有developmentproduction
  • entry:指定打包入口。默认的打包入口文件为src->index.js
  • output:指定打包出口。默认的打包入口文件为dist->main.js
  • module.rules
    • 配置loader,处理不同的文件
    • 常见的loader
      • css-loader:处理css文件。需要安装npm i style-loader css-loader;在module.rules中使用{ test:/\.css$/,use:['style-loader','css-loader']}
      • less-loader:处理less文件。需要安装npm i less-loader less;在module.rules中使用{ test:/\.less$/,use:['style-loader','css-loader','less-loader']}
      • style-loader:将css代码注入js中,通过DOM操作加载css
      • babel-loader:es6->es5
      • img-loader:加载并压缩图片文件
  • plugins
    • 挂载插件,使用之前要先安装npm i webpack-dev-server -D
    • 注意点:如果想要将最新的配置生效,则需要使用命令npm run dev来重新生效配置
    • 常见的plugin
      • html-webpack-plugin :压缩html。安装npm i html-webpack-plugin -D;在plugins挂载插件的实例
      • clean-webpack-plugin :自动删除dist目录下的旧文件
      • commons-chunk-plugin :提取公共代码
  • devServer:对webpack-dev-server插件进行更多的配置
javascript 复制代码
const path = require('path')
// 实例化plugin
const HtmlPlugin = require('html-webpack-plugin')
const htmlPlugin = new HtmlPlugin({
    template:'./src/index.html',
    filename:'/index.html'
})
const CleanWebpackPlugin = require('clean-webpack-plugin')
const cleanPlugin = new CleanWebpackPlugin()

module.exports = {
	mode:'development', //mode用来指定构建方式,可选值有development和production
    entry : "./src/main.js",
    output: {
        path: path.resolve(__dirname,'dist'), //输出文件的路径。动态获取绝对路径,__dirname是node中全局变量
        filename :  "bundle.js" //输出文件的名称
    },
    module:{
    	rules:[
    		{test:/\.css$/,use:['style-loader','css-loader']}, //采用正则表示loader来处理css后缀的文件
    		{test:/\.less$/,use:['style-loader','css-loader','less-loader']} //处理less
    	]
	},
	plugins:[htmlPlugin,cleanPlugin],  //插件实例
	devServer:{ //对webpack-dev-server插件进行更多的配置
	    open:true, //打包完成后自动打开浏览器
	    host:'127.0.0.1', //实时打包使用的主机地址
	    port:80, //实时打包使用的端口号
	}
}

vite(vue3)

一、定义

Vite 作为一款现代化的前端构建工具 ,凭借其快速的冷启动和高效的热更新 ,确实能显著提升开发体验
Vite 通过利用浏览器原生的 ES 模块导入功能 ,实现了闪电般的冷启动 。在开发环境下,它无需打包 ,而是直接按需编译和提供源码生产构建则使用 Rollup,确保输出高度优化的静态资源。

二、安装及配置

Vite 需要 Node.js 版本 20.19+ 或 22.12+ 。

bash 复制代码
// 创建新项目
npm create vite@latest

一个典型的 Vite 项目结构如下:

text 复制代码
my-project/
├── node_modules/    # 依赖包
├── public/          # 静态资源(直接复制到构建输出)
├── src/
│   ├── assets/      # 图片、字体等资源
│   ├── App.jsx/.vue # 主组件
│   └── main.jsx/.ts # 入口文件
├── index.html       # &zwnj;**入口 HTML 文件(位于根目录)**&zwnj;
├── package.json
├── vite.config.js   # Vite 配置文件
└── README.md

Vite 的配置写在 vite.config.js 或 vite.config.ts 中

javascript 复制代码
// vite.config.js
import { defineConfig } from 'vite'

export default defineConfig({
  // 你的配置选项
})
javascript 复制代码
import { defineConfig } from 'vite'

export default defineConfig(({ command, mode }) => {
  // command: 'serve' 或 'build'
  // mode: 通常是 'development' 或 'production'
  if (command === 'serve') {
    return {
      // 开发环境独有配置
      server: {
        port: 3000
      }
    }
  } else {
    // command === 'build'
    return {
      // 生产环境构建独有配置
      build: {
        outDir: 'build'
      }
    }
  }
})

配置项

  • base:设置部署应用时的基本 URL
  • build:配置构建输出相关的选项
  • server:配置开发服务器
  • plugins:使用插件来扩展 Vite 的功能
  • resolve:配置模块解析选项
  • optimizeDeps:优化依赖预构建
  • define 和 envPrefix (环境变量):定义全局常量或在构建时注入环境变量
  • css 和 cssCodeSplit (CSS 相关配置):配置 CSS 处理和分割
javascript 复制代码
import vue from '@vitejs/plugin-vue'
import legacy from '@vitejs/plugin-legacy'
import { defineConfig } from 'vite'
export default {
  base: '/app/',
  build: {
    outDir: 'dist', // 构建输出目录
    assetsDir: 'assets', // 静态资源目录
    sourcemap: true, // 生成 source map
    minify: 'esbuild', // 混淆器,使用 esbuild
    rollupOptions: {
      // rollup 打包选项
    }
  },
  server: {
    port: 3000, // 开发服务器端口号
    open: true, // 在服务器启动时自动在浏览器中打开应用
    cors: true, // 允许跨域请求
    proxy: { // 代理配置,例如将 /api/* 的请求代理到 localhost:5000/api/*
      '/api': {
        target: 'http://localhost:5000',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, '')
      }
    }
  },
  plugins: [vue(), legacy()],
  resolve: {
    alias: { // 路径别名,例如将 @ 指向 src 目录
      '@': '/path/to/src'
    }
  },
  optimizeDeps: {
    include: ['some-package'], // 强制包含的依赖包列表,这些包不会被 esbuild 转换,而是在预构建阶段处理。
    exclude: ['another-package'] // 排除的依赖包列表,这些包不会被预构建。
  },
  define: { // 在编译时定义全局常量,例如:`process.env.NODE_ENV` 将被替换为 `"production"` 或 `"development"`。
    '__APP_VERSION__': JSON.stringify(process.env.npm_package_version) || '0.0.0'
  },
  envPrefix: ['VITE_', 'TAURI_'], // 环境变量前缀,用于从 `.env` 文件加载环境变量。例如,`VITE_SOME_KEY` 或 `TAURI_SOME_KEY`。
  css: { // CSS 相关配置项,例如 CSS 分割和预处理器配置。
    modules: { // CSS Modules 配置}
    }
}

三、环境变量及模式

环境变量文件

Vite 使用 .env 文件来加载环境变量 :

  • .env:所有模式都会加载
  • .env.development:开发环境加载
  • .env.production:生产环境加载

使用环境变量

在客户端代码中,只有以 VITE_ 开头的变量才会被注入 。

在代码中通过 import.meta.env.VITE_自定义变量名 访问 。
内置变量:

  • import.meta.env.MODE:应用运行的模式
  • import.meta.env.DEV:是否为开发环境 。
  • import.meta.env.PROD:是否为生产环境 。
  • import.meta.env.BASE_URL:部署的基础路径
javascript 复制代码
// .env.development
VITE_API_BASE_URL = http://localhost:3000/api
// 在你的代码中
console.log(import.meta.env.VITE_API_BASE_URL)

在 Vite 配置中加载环境变量

默认情况下,Vite 不会在配置文件中加载 .env 文件。如果需要在配置中使用,可以手动调用 loadEnv 函数 :

javascript 复制代码
// vite.config.js
import { defineConfig, loadEnv } from 'vite'

export default defineConfig(({ mode }) => {
  // 加载对应模式的环境变量,第三个参数为空字符串表示加载所有
  const env = loadEnv(mode, process.cwd(), '')
  return {
    // 使用环境变量,例如设置服务器端口
    server: {
      port: env.VITE_APP_PORT ? Number(env.VITE_APP_PORT) : 5173,
    },
  }
})

四、相关命令

  • npm run dev 启动开发服务器
  • npm run build 生产环境构建,输出到 dist/ 目录
  • npm run preview 本地预览生产构建结果

webpack及vite相关面试题

webpack(vue2)

1、webpack是什么,有什么作用

Webpackjs的静态模块打包工具核心是将各类资源(JS、CSS、图片等)视为模块 ,通过分析依赖关系打包成 浏览器 可识别的静态资源

核心作用:

  • 模块打包整合分散模块,生成bundle文件,解决浏览器模块化支持问题。
  • 资源转换通过Loader 将ES6+、SCSS等转为浏览器兼容格式
  • 代码优化Tree Shaking剔除死代码、压缩资源,提升加载性能。
  • 工程化支持 :配合插件实现自动化构建、环境区分等工程化能力。

2、webpack与grunt、gulp的不同?

  • grunt/gulp: 如果你的工程模块依赖非常简单,甚至是没有用到模块化的概念,只需要进行简单的合并、压缩
  • webpack: 如果整个项目使用了模块化管理,而且相互依赖非常强

3、Webpack核心概念有哪些?请分别说明

  • entry入口 。指定构建起点 ,Webpack从这里开始解析依赖
  • output出口 。定义打包后资源的存储路径和命名规则
  • module加载器。转换非JS资源为Webpack可处理的模块
  • plugins插件。扩展Webpack功能,如生成HTML、压缩代码
  • mode模式区分环境,启用对应优化策略

4、请描述Webpack的完整打包流程

打包流程是一个串⾏的过程:

  • 初始化参数 :从配置⽂件和 Shell 语句读取与合并参数,得出最终的参数;
  • 开始编译 :⽤上⼀步得到的参数初始化 Compiler 对象加载所有配置的插件执⾏对象的 run ⽅法开始执⾏编译
  • 确定⼊⼝ :根据配置中的 entry 找出所有的⼊⼝⽂件
  • 编译模块 :从⼊⼝⽂件出发,调⽤所有配置的 Loader 对模块进⾏翻译 ,再找出该模块依赖的模块 ,再递归本步骤 直到所有⼊⼝依赖的⽂件 都经过了本步骤的处理;
  • 完成模块编译 :在经过Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;
  • 输出资源 :根据**⼊⼝和模块之间的依赖关系** ,组装 成⼀个个包含多个模块的 Chunk ,再把每个 Chunk 转换成⼀个单独的⽂件加⼊到输出列表,这步是可以修改输出内容的最后机会;
  • 输出完成 :在确定好输出内容 后,根据配置确定输出的路径和⽂件名 ,把**⽂件内容写⼊到⽂件系统**

5、有哪些常⻅的Loader?

  • css-loader:处理css文件。需要安装npm i style-loader css-loader;在module.rules中使用{ test:/\.css$/,use:['style-loader','css-loader']}
  • less-loader:处理less文件。需要安装npm i less-loader less;在module.rules中使用{ test:/\.less$/,use:['style-loader','css-loader','less-loader']}
  • style-loader:将css代码注入js中,通过DOM操作加载css
  • babel-loader:es6->es5
  • img-loader:加载并压缩图片文件

6、有哪些常⻅的Plugin?

  • html-webpack-plugin :压缩html。安装npm i html-webpack-plugin -D;在plugins中挂载插件的实例
  • clean-webpack-plugin :自动删除dist目录下的旧文件
  • commons-chunk-plugin :提取公共代码

7、Loader和Plugin的不同?

  • 作用不同:
    • loader加载器,让webpack拥有加载和解析非js文件的能力(webpack原生只能解析js代码,若要其他文件也打包,需要loader)
    • plugin插件,扩展webpack的功能。(plugin监听webpack生命周期广播的事件,合适时机,用webpack的API改变输出结果)
  • 用法不同:
    • loader:在module.rules中配置
    • plugin:在plugins中配置(挂载的是插件实例)

8、bundle,chunk,module是什么?

- bundle:是由webpack打包出来的⽂件

  • chunk代码块⼀个chunk由多个模块组合 ⽽成,⽤于代码的合并和分割
  • module:是开发中的单个模块 ,在webpack的世界,⼀切皆模块,⼀个模块对应⼀个⽂件,webpack会从配置的 entry中递归开始找出所有依赖的模块

9、Tree Shaking的原理是什么?如何确保生效?

Tree Shaking是通过静态分析剔除未使用代码的优化手段,核心依赖ES Module的静态导入特性。

生效条件(缺一不可)

  • 代码使用ES Module(import/export) ,而非CommonJS(require)
  • Mode 设为production(开发模式默认关闭)。
  • package.json配置sideEffects标记无副作用的文件(避免误删CSS等资源)

10、什么是代码分割(Code Splitting)?有哪些实现方式?

代码分割是将代码拆分为多个Chunk,实现按需加载,减少首屏加载体积。

主要有3种实现方式:

  • 多入口分割配置多个Entry,适用于多页面应用
  • 动态导入 :通过import()语法实现异步加载 ,适用于路由按需加载
  • splitChunks提取公共代码自动提取多入口公共依赖,避免重复打包
js 复制代码
module.exports = { 
	entry: { page1: './src/page1.js', page2: './src/page2.js' }, //方法一
	output: { filename: '[name].js', path: './dist' },
	optimization: {  //方法三
		splitChunks: { 
			chunks: 'all', // 分割同步/异步代码 		
			cacheGroups: { 
				vendor: { // 提取第三方库(如vue、react) 
				test: /node_modules/, name: 'vendors', priority: 10 }, 
				common: { // 提取公共业务代码 minChunks: 2, // 被引用2次以上 name: 'common' } 
			} 
		}
	 } 
}
javascript 复制代码
//方法二
// 点击按钮异步加载模块 
document.getElementById('btn').addEventListener('click', async () => { const utils = await import('./utils.js'); // 生成独立Chunk utils.doSomething(); });

11、怎么配置单⻚应⽤?怎么配置多⻚应⽤?

总结:在entry入口中配置,单页面就是一个地址字符串;多页就是一个对象

javascript 复制代码
module.exports={
	entry:'/path/file.js',   //单⻚应⽤
	entry:{ //多⻚应⽤
		pageOne:'./src/pageOne/index.js',
		pageTwo:'./src/pageTwo/index.js'
	}
}

12、如何⽤webpack来优化前端性能?

原理:优化webpack的输出结果

  • 压缩代码删除多余的代码、注释、简化代码的写法 等等⽅式。
    • UglifyJsPlugin 和 ParallelUglifyPlugin :压缩JS⽂件,
    • cssnano :压缩css
  • 利⽤CDN加速 : 将引⽤的静态资源路径修改为CDN上对应的路径
    • output中的publicPathplugins中的stylePublicPlugin
  • Tree Shaking : 删除死代码 。在启动webpack时追加参数 --optimize-minimize
  • Code Splitting : 将代码按路由维度或者组件分块(chunk),这样做到按需加载,同时可以充分利⽤浏览器缓存
  • 提取公共第三⽅库 : SplitChunksPlugin插件来进⾏公共模块抽取,利⽤浏览器缓存可以⻓期缓存这些⽆需频繁变动的公共代码

vite(vue3)

1、Vite 是什么?它解决了什么问题?

Vite 是一个利用现代浏览器对原生ESM支持的构建工具 。它跳过了打包操作 ,提供了快速的冷启动和即时的热模块更新
解决了 :传统打包工具在开发阶段的缓慢问题

2、Vite 的工作原理是什么?

Vite 在开发阶段使用原生ESM加载方式 ,通过 index.htmltype="module" 脚本标签直接从服务器加载模块 。在构建阶段,Vite 使用 Rollup 进行打包,优化应用体积和性能。

3、Vite 如何实现按需加载?

Vite 支持动态导入 ,允许你使用 import() 语法来实现组件或模块的按需加载。

4、Vite 中的 vite.config.js 文件是做什么用的?

vite.config.jsVite 的配置文件 ,允许你自定义 Vite 的行为,如定义入口文件、基础路径、构建输出、插件等。

5、Vite 如何处理 CSS 和静态资源?

Vite 允许你直接导入 CSS 文件,并且会自动处理

对于静态资源 ,如图片、字体等,可以直接放置在 public 目录中,Vite 会提供相应的服务。

6、Vite 的插件机制是如何工作的?

Vite 允许通过插件扩展 其功能。插件可以介入 Vite 的启动、构建和插件系统 ,提供自定义的配置和行为

7、Vite 如何实现热模块替换(HMR)?

Vite 使用原生ESMimport.meta.hot 属性实现热模块替换 ,允许在不刷新页面的情况下更新模块。

8、Vite 与 Webpack 和 Rollup 的关系是怎样的?

Vite 在开发阶段利用原生ESM导入,不需要打包 ,因此比 Webpack 和 Rollup 更快。在构建阶段,Vite 使用 Rollup 进行打包,以生成优化后的资源。

9、Vite 的构建输出有哪些选项?

Vite 允许你配置构建输出 ,包括输出目录、文件名、源码映射等。

10、Vite 的开发服务器支持 HTTPS 吗?

是的,Vite 的开发服务器支持通过 https 配置项启用 HTTPS

11、Vite 如何配置多个入口文件?

在 vite.config.js 中,你可以使用 build.rollupOptions.input 配置多个入口文件

12、Vite 的性能优化有哪些方法?

Vite 的性能优化 包括使用代码分割、预构建、压缩和最小化 CSS 和 JavaScript 文件等技术。

13、Vite 的 base 配置项有什么作用?

base 配置项用于设置应用的基础路径 ,这对于部署到非根路径的应用非常有用。

14、Vite 中如何定义全局常量?

可以在 vite.config.js 中使用 define 配置项 定义全局常量

15、Vite 的构建版本和开发版本有什么区别?

开发版本使用 Vite 作为开发服务器,提供快速重载和模块热更新。

构建版本通过 Rollup 打包,优化应用性能和资源体积。

16、Vite 如何处理 TypeScript 项目?

Vite 支持 TypeScript,可以直接导入 .ts 或 .tsx 文件,并且可以结合 tsconfig.json 文件进行类型检查。

原文链接:https://blog.csdn.net/qq_29101285/article/details/138772748

ES模块(ESM)和CommonJS区别

  • 加载时机
    • CommonJS 是 同步加载,运行时解析。require() 会阻塞后续代码执行,直到模块加载完成
    • ES Module 是 静态解析,编译时解析。但支持 import() 实现异步加载(返回 Promise)。
  • 输出类型
    • CommonJS 输出的是 值的拷贝
    • ES Module 输出的是 值的引用。
  • 循环依赖处理
    • CommonJS 通过缓存机制处理循环依赖
    • ES Module 通过静态分析解决循环依赖。
  • Tree-shaking
    • ES Module 支持静态分析,可进行 Tree-shaking 优化
    • CommonJS 不支持

AMD 和 CMD 的区别是什么?

  • 依赖声明时机
    • AMD(RequireJS)前置声明依赖(依赖数组在模块定义时声明);
    • CMD(Sea.js)就近声明依赖(依赖在代码执行到需要时声明)。
  • 执行顺序
    • AMD 提前执行依赖模块
    • CMD 延迟执行依赖模块。
相关推荐
Kinghiee2 小时前
使用webpack构建vue3 ssr
前端·webpack·node.js·vue3ssr
wuhen_n2 小时前
回溯算法入门 - LeetCode经典回溯算法题
前端·javascript·算法
xcs194052 小时前
前端 vue this.$nextTick(() => {
前端·javascript·vue.js
广州华水科技2 小时前
如何在基础设施安全中有效实现GNSS位移监测的应用?
前端
大漠_w3cpluscom2 小时前
前端怎么提升自己的CSS编写能力?
前端
我是若尘2 小时前
大数据量渲染优化:分批渲染技术详解
前端
ruanCat2 小时前
pnpm 踩坑实录:用 public-hoist-pattern 拯救被严格隔离坑掉的依赖
前端·npm·node.js
yuki_uix2 小时前
渲染优化三件套:React.memo、useMemo、useCallback 的使用边界
前端·react.js
徐同保2 小时前
如何为 Node.js 多层子进程启动调试(以 OpenClaw 为例)
前端