webpack 以及 git

文章探讨了前端开发中的一些关键概念,包括如何布局多个logo图标,理解js闭包以优化API调用,以及webpack的codesplit实现按需加载。此外,讨论了let和const的区别,React废弃的生命周期方法,以及如何控制setState的同步性。还提到了umi和dva框架与原生redux的差异,以及mobx和redux的状态管理对比。最后,简述了性能优化策略和WebSocket协议,以及git的常用命令操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 要求有若干个logo图标, 在一块区域进行展示, 要求每行固定展示五个并且间距要均匀 ,不得直接设置width,

  2. js闭包的理解
    节流就是闭包

  3. 比如百度搜索 ,如果每次用户键入信息都调用api接口 ,合理吗, 如何优化,

  4. 了解webpack吗? 说说什么是code spilt,

  5. let和const,

  6. react要放弃哪些生命周期? 为什么?
    componentWillMount
    componentWillUpdate
    componentsWillRecieveProps
    试想,假如你在 componentWillxxx 里发起了一个付款请求。由于 render 阶段里的生命周期都可以重复执行,在 componentWillxxx 被打断 + 重启多次后,就会发出多个付款请求。
    比如说,这件商品单价只要 10 块钱,用户也只点击了一次付款。但实际却可能因为 componentWillxxx 被打断 + 重启多次而多次调用付款接口,最终付了 50 块钱;又或者你可能会习惯在 componentWillReceiveProps 里操作 DOM(比如说删除符合某个特征的元素),那么 componentWillReceiveProps 若是执行了两次,你可能就会一口气删掉两个符合该特征的元素。

  7. react setState何时为同步 何时为异步(或者说如何让它同步产生结果),https://blog.51cto.com/u_15127495/2662267
    在这里插入图片描述
    在这里插入图片描述

    1. 用过umi或者dva吗 ,它给你原生使用redux带来的不同在于什么?
    1. 用过mobx吗 说说他和redux的异同,
      在这里插入图片描述
    1. 说说你都会做哪些方面的优化,
    1. 简述一下webSocket

    1. 在这里插入图片描述
      https://blog.youkuaiyun.com/weixin_40746230/article/details/125195436

在这里插入图片描述

https://mp.weixin.qq.com/s?__biz=MjM5MDA2MTI1MA==&mid=2649112452&idx=3&sn=29e5901263eae442e1829be1220d266a&chksm=be581829892f913f930b5c6a5d7c31f335dfd919b93545bdd1e06c18f5413d220f1882401f04&scene=27
在这里插入图片描述

查看所有分支简化的提交历史记录git reflog
git reset --hard
git branch查看分支
创建并切换分支git checkout -b 分支名称
git branch -d 分支名称 删除分支
git remote add origin 地址 添加远程地址
git fetch只是将远程仓库的最新的版本下载到本地,但是不会自动merge,相当于工作区中的文件并没有更新
git pull会从远程仓库获取到最新的版本并merge到本地。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
https://blog.youkuaiyun.com/weixin_53509920/article/details/120359395

打包代码时会将所有 js 文件打包到一个文件中,体积太大了。我们如果只要渲染首页,就应该只加载首页的 js 文件,其他文件不应该加载。

所以我们需要将打包生成的文件进行代码分割,生成多个 js 文件,渲染哪个页面就只加载某个 js 文件,这样加载的资源就少,速度就更快。

代码分割(Code Split)主要做了两件事:

  1. 分割文件:将打包生成的文件进行分割,生成多个 js 文件。
  2. 按需加载:需要哪个文件就加载哪个文件。

新建文件

├── public
├── src
| ├── app.js
| └── main.js
├── package.json
└── webpack.config.js

webpack.config.js 配置

const path = require(‘path’);
const HtmlWebpackPlugin = require(“html-webpack-plugin”);

module.exports = {
// 单入口
// entry: ‘./src/main.js’,
// 多入口
entry:{
main: ‘./src/main.js’,
app: ‘./src/app.js’,
},
output: {
path: path.resolve(__dirname, “dist”),
// [name]是webpack命名规则,使用chunk的name作为输出的文件名。
// 什么是chunk?打包的资源就是chunk,输出出去叫bundle。
// chunk的name是啥呢?
//比如: entry中xxx: “./src/xxx.js”, name就是xxx。注意是前面的xxx,和文件名无关。
// 为什么需要这样命名呢?如果还是之前写法main.js,那么打包生成两个js文件都会叫做main.js会发生覆盖。(实际上会直接报错的)
filename: “[name].js”,
// clear: true,
},
plugins: [
new HtmlWebpackPlugin({
template:path.resolve(__dirname,“public/index.html”),
}),
],
mode: “production”,
};
下载依賴

npm init -y 生成 package.json

npm i webpack webpack-cli html-webpack-plugin -D 生成node包 html-webpack-plugin 插件

打包 npx webpack

多入口使用同一段代码 优化 // 代码分割配置 splitChunks
const path = require(‘path’);
const HtmlWebpackPlugin = require(“html-webpack-plugin”);

module.exports = {
// 单入口
// entry: ‘./src/main.js’,
// 多入口
entry:{
main: ‘./src/main.js’,
app: ‘./src/app.js’,
},
output: {
path: path.resolve(__dirname, “dist”),
// [name]是webpack命名规则,使用chunk的name作为输出的文件名。
// 什么是chunk?打包的资源就是chunk,输出出去叫bundle。
// chunk的name是啥呢?
//比如: entry中xxx: “./src/xxx.js”, name就是xxx。注意是前面的xxx,和文件名无关。
// 为什么需要这样命名呢?如果还是之前写法main.js,那么打包生成两个js文件都会叫做main.js会发生覆盖。(实际上会直接报错的)
filename: “[name].js”,
// clear: true,
},
plugins: [
new HtmlWebpackPlugin({
template:path.resolve(__dirname,“public/index.html”),
}),
],
mode: “production”,
optimization: {
// 代码分割配置
splitChunks: {
chunks: “all”, // 对所有模块都进行分割
// 以下是默认值
// minSize: 20000, // 分割代码最小的大小
// minRemainingSize: 0, // 类似于minSize,最后确保提取的文件大小不能为0
// minChunks: 1, // 至少被引用的次数,满足条件才会代码分割
// maxAsyncRequests: 30, // 按需加载时并行加载的文件的最大数量
// maxInitialRequests: 30, // 入口js文件最大并行请求数量
// enforceSizeThreshold: 50000, // 超过50kb一定会单独打包(此时会忽略minRemainingSize、maxAsyncRequests、maxInitialRequests)
// cacheGroups: { // 组,哪些模块要打包到一个组
// defaultVendors: { // 组名
// test: /[\/]node_modules[\/]/, // 需要打包到一起的模块
// priority: -10, // 权重(越大越高)
// reuseExistingChunk: true, // 如果当前 chunk 包含已从主 bundle 中拆分出的模块,则它将被重用,而不是生成新的模块
// },
// default: { // 其`他没有写的配置会使用上面的默认值
// minChunks: 2, // 这里的minChunks权重更大
// priority: -20,
// reuseExistingChunk: true,
// },
// },
// 修改配置
cacheGroups: {
// 组,哪些模块要打包到一个组
// defaultVendors: { // 组名
// test: /[\/]node_modules[\/]/, // 需要打包到一起的模块
// priority: -10, // 权重(越大越高)
// reuseExistingChunk: true, // 如果当前 chunk 包含已从主 bundle 中拆分出的模块,则它将被重用,而不是生成新的模块
// },
default: {
// 其他没有写的配置会使用上面的默认值
minSize: 0, // 我们定义的文件体积太小了,所以要改打包的最小文件体积
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
},
},
};
按需加载动态导入
如果有一些初始加载用不上的资源 就不需要一上来就加载

  1. 修改文件
  • main.js
import { sum } from './math.js';
// import count from "./count.js";
console.log("hello main");
console.log(sum(1,2,3));
// document.getElementById('btn').οnclick=function(){
// 	console.log(count(2,1));
// };
document.getElementById('btn').onclick=function(){
	  // 动态导入 --> 实现按需加载
	  // 即使只被引用了一次,也会代码分割
	import('./count').then(
	(res)=>{
	  console.log('模块动态加载成功',res);
	})
	.catch((err)=>{
		console.log('模块加载失败',err);
	})
};
  • app.js
console.log("hello app");
  • public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Code Split</title>
  </head>
  <body>
    <h1>hello webpack</h1>
    <button id="btn">计算</button>
  </body>
</html>
export default function count(x,y){
	return x-y;
	
}
单入口
开发时我们可能是单页面应用(SPA),只有一个入口(单入口)。那么我们需要这样配置:

js/math.js
 
export function mul(...args){
	 return args.reduce((p,c)=>p+c,0);
}
import count  from "./js/count.js";
import sum from "./js/sum.js";
//要想webpack打包资源必须引入该资源
import "./css/iconfont.css";
import "./css/index.css";
import "./less/index.less";
import "./sass/index.sass";
import "./sass/test1.scss";
import "./styl/index.styl";
const result=count(2,1);
console.log(result);
console.log(sum(1,2,3,4));
 
document.getElementById("btn").οnclick=function(){
	  // eslint会对动态导入语法报错,需要修改eslint配置文件
	  // webpackChunkName: "math":这是webpack动态导入模块命名的方式
	import(/*webpackChunkName: "math"*/"./js/math").then(({mul})=>{
		 console.log(mul(3,3));
	});
}
 
 
if(module.hot){
	
	//判断是否支持热模块 替换功能
	module.hot.accept("./js/count.js");
	module.hot.accept("./js/sum.js");
}
 eslint会对动态导入语法报错,需要修改eslint配置文件

module.exports = {
  // 继承 Eslint 规则
  extends: ["eslint:recommended"],
  env: {
    node: true, // 启用node中全局变量
    browser: true, // 启用浏览器中全局变量
  },
  parserOptions: {
    ecmaVersion: 6, //es6
    sourceType: "module", //es module
  },
  rules: {
    "no-var": 2, // 不能使用 var 定义变量
  },
  plugins:["import"],//解決动态导入语法报错
};
打包生成带数字文件名 修改文件名 精准定位 文件  原单入口   webpack.prod.js 配置

module.exports = {
...
  output: {
    path: path.resolve(__dirname, "../dist"), // 生产模式需要输出
    filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
	chunkFilename:'static/js/[name].js', //打包输出的其他文件命名
    clean: true,
  },
....
}
CodeSplit 统一命名  图片 JS  样式 命名
const os = require("os");
const path = require("path");
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
 
// cpu核数
const threads = os.cpus().length;
 
// 获取处理样式的Loaders
const getStyleLoaders = (preProcessor) => {
  return [
    MiniCssExtractPlugin.loader,
    "css-loader",
    {
      loader: "postcss-loader",
      options: {
        postcssOptions: {
          plugins: [
            "postcss-preset-env", // 能解决大多数样式兼容性问题
          ],
        },
      },
    },
    preProcessor,
  ].filter(Boolean);
};
 
module.exports = {
  entry: "./src/main.js", //相对路径
  output: {
	  //所有文件输出路径
	  //__dirname node.js 的变量,代表当前文件夹的目录
    path: path.resolve(__dirname, "../dist"), // 绝对路径
	// 入口文件打包输出文件名
    filename: "static/js/[name].js", 
	//打包输出的其他文件命名
	chunkFilename:'static/js/[name].chunk.js', 
	//图片 字体等通过type:asset处理资源命名
	assetModuleFilename:"static/media/[hash:8][ext][query]",
	//自动清空上次打包内容
	//原理:在打包前,将path整个目录清空,再进行打包
    clean: true,
  },
  module: {
    rules: [
      {
        oneOf: [
          {
            // 用来匹配 .css 结尾的文件
            test: /\.css$/,
            // use 数组里面 Loader 执行顺序是从右到左
            use: getStyleLoaders(),
          },
          {
            test: /\.less$/,
            use: getStyleLoaders("less-loader"),
          },
          {
            test: /\.s[ac]ss$/,
            use: getStyleLoaders("sass-loader"),
          },
          {
            test: /\.styl$/,
            use: getStyleLoaders("stylus-loader"),
          },
          {
            test: /\.(png|jpe?g|gif|svg)$/,
            type: "asset",
            parser: {
              dataUrlCondition: {
                maxSize: 10 * 1024, // 小于10kb的图片会被base64处理
              },
            },
            // generator: {
            //   // 将图片文件输出到 static/imgs 目录中
            //   // 将图片文件命名 [hash:8][ext][query]
            //   // [hash:8]: hash值取8位
            //   // [ext]: 使用之前的文件扩展名
            //   // [query]: 添加之前的query参数
            //   filename: "static/imgs/[hash:8][ext][query]",
            // },
          },
          {
            test: /\.(ttf|woff2?|mp3|mp4|avi)$/,
            type: "asset/resource",
			//复用
            // generator: {
            //   filename: "static/media/[hash:8][ext][query]",
            // },
          },
          {
            test: /\.js$/,
            // exclude: /node_modules/, // 排除node_modules代码不编译
            include: path.resolve(__dirname, "../src"), // 也可以用包含
            use: [
              {
                loader: "thread-loader", // 开启多进程
                options: {
                  workers: threads, // 数量
                },
              },
              {
                loader: "babel-loader",
                options: {
                  cacheDirectory: true, // 开启babel编译缓存
                  cacheCompression: false, // 缓存文件不要压缩
                  plugins: ["@babel/plugin-transform-runtime"], // 减少代码体积
                },
              },
            ],
          },
        ],
      },
    ],
  },
  plugins: [
    new ESLintWebpackPlugin({
      // 指定检查文件的根目录
      context: path.resolve(__dirname, "../src"),
      exclude: "node_modules", // 默认值
      cache: true, // 开启缓存
      // 缓存目录
      cacheLocation: path.resolve(
        __dirname,
        "../node_modules/.cache/.eslintcache"
      ),
      threads, // 开启多进程
    }),
    new HtmlWebpackPlugin({
      // 以 public/index.html 为模板创建文件
      // 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
      template: path.resolve(__dirname, "../public/index.html"),
    }),
    // 提取css成单独文件
    new MiniCssExtractPlugin({
      // 定义输出文件名和目录
      filename: "static/css/[name].css",
	  chunkFilename:"static/css/[name].chunk.css", //动态导入的CSS命名
    }),
    // css压缩
    // new CssMinimizerPlugin(),
  ],
  optimization: {
    minimizer: [
      // css压缩也可以写到optimization.minimizer里面,效果一样的
      new CssMinimizerPlugin(),
      // 当生产模式会默认开启TerserPlugin,但是我们需要进行其他配置,就要重新写了
      new TerserPlugin({
        parallel: threads, // 开启多进程
      }),
      // 压缩图片
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.imageminGenerate,
          options: {
            plugins: [
              ["gifsicle", { interlaced: true }],
              ["jpegtran", { progressive: true }],
              ["optipng", { optimizationLevel: 5 }],
              [
                "svgo",
                {
                  plugins: [
                    "preset-default",
                    "prefixIds",
                    {
                      name: "sortAttrs",
                      params: {
                        xmlnsOrder: "alphabetical",
                      },
                    },
                  ],
                },
              ],
            ],
          },
        },
      }),
    ],
    // 代码分割配置
    splitChunks: {
      chunks: "all", // 对所有模块都进行分割
      // 其他内容用默认配置即可
    },
  },
  // devServer: {
  //   host: "localhost", // 启动服务器域名
  //   port: "3000", // 启动服务器端口号
  //   open: true, // 是否自动打开浏览器
  // },
  mode: "production",
  devtool: "source-map",

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值