面试题答案
一键面试开发环境打包策略
- 代码拆分:
- 使用 Webpack 的
splitChunks
插件进行代码拆分,将第三方库和业务代码分开打包。在webpack.config.js
中配置如下:
module.exports = { //...其他配置 optimization: { splitChunks: { chunks: 'all' } } };
- 这样可以使得第三方库只需要在首次加载时下载,之后开发过程中业务代码更新时,只需要加载变动的部分,提高开发效率。
- 使用 Webpack 的
- 压缩:开发环境可以不进行压缩,因为压缩会增加构建时间。若要配置简单的压缩,可使用
terser - webpack - plugin
插件,在webpack.config.js
中配置如下:
但在开发环境建议注释掉该部分配置以加快构建。const TerserPlugin = require('terser - webpack - plugin'); module.exports = { //...其他配置 optimization: { minimizer: [ new TerserPlugin() ] } };
- 懒加载:使用 ES6 的动态
import()
语法实现懒加载。例如:
这样在开发过程中,只有当访问到对应的路由时,才会加载相关组件,提高开发时页面的加载速度。// 假设这是一个路由组件加载 const router = new VueRouter({ routes: [ { path: '/home', component: () => import('./components/Home.vue') } ] });
生产环境打包策略
- 代码拆分:
- 进一步细化
splitChunks
配置,将不同功能模块拆分成单独的文件。例如:
module.exports = { //...其他配置 optimization: { splitChunks: { chunks: 'all', cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name:'vendors', chunks: 'all' }, commons: { name: 'commons', chunks: 'initial', minChunks: 2 } } } } };
vendor
组将第三方库打包在一起,commons
组将多个入口文件的公共代码提取出来,减少重复代码,优化打包体积。
- 进一步细化
- 压缩:
- 启用
terser - webpack - plugin
进行 JavaScript 代码压缩,并开启并行压缩提高效率。在webpack.config.js
中配置如下:
const TerserPlugin = require('terser - webpack - plugin'); module.exports = { //...其他配置 optimization: { minimizer: [ new TerserPlugin({ parallel: true }) ] } };
- 对于 CSS 代码,使用
css - minimizer - webpack - plugin
进行压缩。先安装该插件npm install css - minimizer - webpack - plugin - - save - dev
,然后在webpack.config.js
中配置:
const MiniCssExtractPlugin = require('mini - css - extract - plugin'); const CssMinimizerPlugin = require('css - minimizer - webpack - plugin'); module.exports = { //...其他配置 module: { rules: [ { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css - loader'] } ] }, optimization: { minimizer: [ new CssMinimizerPlugin() ] }, plugins: [ new MiniCssExtractPlugin() ] };
- 启用
- 懒加载:和开发环境类似,使用 ES6 的动态
import()
语法实现懒加载。同时,可以结合路由的预加载(在路由即将跳转时提前加载相关组件)进一步优化加载速度。例如在 Vue Router 中,可以使用router.beforeEach
钩子函数进行预加载:
这样在用户即将跳转到某个路由时,提前加载相关组件,提高页面的加载速度。router.beforeEach((to, from, next) => { const matched = router.getMatchedComponents(to); const prevMatched = router.getMatchedComponents(from); let diffed = false; const activated = matched.filter((c, i) => { return diffed || (diffed = (prevMatched[i]!== c)); }); if (!activated.length) { return next(); } activated.forEach(component => { if (typeof component === 'function') { return component().then(next).catch(next); } }); });