当前位置: 首页 > article >正文

Webpack 基础

Webpack 基础

基本使用

webpack是一个静态资源打包工具
它会将一个或者多个文件作为打包的入口,将我们整个项目所有文件编译组合成一个或者多个文件输出出去。
输出的文件就是编译好的文件,就可以在浏览器端运行。
我们将webpack输出的文件叫做bundle

功能介绍

webpack本身功能是有限的:

  • 开发模式:仅能编译JS中的ES Module语法。
  • 生产模式:能编译JS中的ES Module语法,还能压缩JS代码。

开始使用

1.资源目录
 webpack_code # 项目根目录(所有指令必须在这个目录中运行)
   └── src # 项目源码目录
        |──js # js目录
        |  |—— count.js
        |  └── sum.js
        └── main.js # 项目主文件
2.创建文件
  • count.js
export default function count(x,y){
    return x + y;
}
  • sum.js
export default function sum(...args){
    return args.reduce((pre,cur)=> pre + cur,0)
}
  • main.js
import count from "./js/count"
import sum form "./js/sum"

console.log(count(2,1))
console.log(count(1,2,3,4,5))
3.下载依赖

打开终端,在项目根目录下执行指令

  • 初始化``package.json
npm init -y 
  • 下载依赖
npm i webpack webpack-cli -D
4.启用webpack
  • 开发模式
npx webpack ./src/main.js --mode=development
  • 生产模式
npx webpack ./src/main.js --mode=production

npx webpack:是用来运行本地安装webpack包的。
./src/main.js:指定webpackmain.js文件开始打包,不但会打包main.js,还会将其他依赖也一起打包进来。
--mode=production:指定模式(环境)。

5.观察输出文件

默认webpack会将文件打包输出到dist目录下。

webpack本身功能比较少,只能处理js资源,一旦遇到css等其他资源就会报错。
所有我们学习webpack,就是主要学习如何处理其他资源。

基本配置

在开始使用webpack之前,我们需要对webpack的配置有一定的认识。

五大核心概念

  • entry(入口)

指示 webpack 从哪个文件开始打包。

  • output(输出)

指示 webpack 打包完的文件输出到哪里去,如何命名。

  • loader(加载器)

webpack 本身只能处理js、json等资源,其他资源需要借助loader,webpack 才能解析。

  • plugins(插件)

扩展 webpack 功能。

  • mode(模式)

主要有两种开发模式:

  • 开发模式:development
  • 生产模式:producton

webpack 配置文件

webpack.config.js

const path = require("path")
module.exports = {
    //入口
    entry: "./src/main.js",
    // 输出
    output: {
        // 文件的输出路径
        path: path.resolve(__dirname, "dist"),
        filename: "main.js"
    },
    // 加载器
    module: {
        rules: []
    },
    // 插件
    plugins: [],
    // 模式
    mode: "development"
}

开发模式

开发模式顾名思义就是我们开发代码时使用的模式。
这个模式下我们主要做两件事:

  • 编译代码,使浏览器能识别运行。

开发时我们有样式资源、字体图标、图片资源、html资源等,webpack默认都不能处理这些资源,所以我们要加载配置来编译这些资源。

  • 代码质量检查,树立代码规范。

提前检查代码的一些隐患,让代码运行时能更加健壮。
提前检查代码规范和格式,统一团队编码风格,让代码更优雅美观。

处理样式资源

学习使用webpack处理Css、Less、Sass、Styl样式资源

介绍

webpack 本身是不能识别样式资源的,所以我们需要借助Loader来帮助webpack解析样式资源。
需要的Loader都应该去官方文档中查找对应的Loader。
webpack 官方Loader文档

处理CSS资源

  • 下载包
npm i css-loader style-loader -D

需要下载两个Loader

  • 功能介绍

    • css-loader:负责将CSS文件编译成webpack能识别的模块。
    • style-loader:会动态创建一个style标签,里面放置webpack中的CSS模块内容。
  • 配置

    module: {
        // loader的配置
        rules: [{
            test: /\.css$/,
            use: [
                // 执行的顺序,从右到左(从上到下)
                "style-loader", // 将js中css通过创建style标签添加html文件中生效
                "css-loader" // 将样式编译成commonjs的模块
            ]
        }]
    },

处理less文件

  • 下载包
npm i -D less-load
  • 功能介绍
    less-loader:负责将less文件编译成CSS文件
  • 配置
  module: {
        // loader的配置
        rules: [ {
            test: /\.less$/,
            // loader:'xxx'只能使用单个loader
            // user 使用多个loader
            use: [
                "style-loader",
                "css-loader",
                "less-loader" // 将Less 编译成css文件
            ]
        }]
    },

处理Sass和Scss资源

  • 下载包
npm i sass-loader sass -D

注意:需要下载两个

  • 功能介绍
    • sass-loader:负责将Sass文件编译成Css文件。
    • sasssass-loader依赖sass进行编译。
  • 配置
module: {
        // loader的配置
        rules: [{
            test: /\.s[ac]ss$/,
            use: [
                "style-loader",
                "css-loader",
                "sass-loader"
            ]
        }]
    },

处理styl资源

  • 下载包
npm i stylus-loader -D
  • 功能介绍

    • stylus-loader:负责将Styl文件编译成Css文件。
  • 配置

    module: {
        // loader的配置
        rules: [{
            test: /\.styl$/,
            use: [
                "style-loader",
                "css-loader",
                "stylus-loader"
            ]
        }]
    },

处理图片资源

webpack4 时,我们处理图片资源通过file-loaderurl-loader进行处理。
现在webpack已经将两个Loader功能内置到webpack

  • 配置
    module: {
        // loader的配置
        rules: [{
            test: /\.(png|jpe?g|gif|webp)$/,
            type: "asset",
            parser: {
                dataUrlCondition: {
                    // 小于 10 kb 转base64
                    // 优点:减少请求数量,缺点:打包后的结果体积增大
                    maxSize: 20 * 1024,
                }
            },
            generator: {
                // 输出图片名称
                // [hash:10] hash 值取前10位
                filename: "static/images/[hash:10][ext][query]"
            }
        }]
    },

自动清空打包内容

    output: {
        // 文件的输出路径
        path: path.resolve(__dirname, "dist"),
        filename: "js/main.js",
        clean: true
    },

处理字体图标资源

  • 下载字体文件
    • 我用 ttf 文件做测试。
    • 放在项目目录中
  • 在 css 中引入字体
@font-face {
    font-family: "HY";
    src: url("../fonts/HanYiXingKaiJian-1.ttf");
}
div {
    font-family: "HY";
}
  • 配置
    modules:{
        test: /\.ttf|worff?$/,
            generator: {
                // 输出图片名称
                // [hash:10] hash 值取前10位
                filename: "static/font/[hash:10][ext][query]"
            }
    }

处理其他资源

如遇到 音视频文件、文本文档等,我们将这些资源打包输出到dist目录中。

  • 配置
{
    test: /\.video|audio|xsl|doc$/,
    generator: {
        filename: "static/media/[hash:10][ext][query]"
    }
}

处理JS资源

webpack对JS处理是有限的,只能编译JS中的模块化语法,不能编译其他语法,导致JS不能在IE等浏览器运行,所以我们希望做一些兼容性处理。
其次,在开发中团队对代码格式是有严格要求的,我们不能由肉眼去检测代码格式,需要使用专业工具来检测。

  • 针对JS兼容性处理,我们手机用Babel做代码兼容处理。
  • 针对代码格式,我们使用ESlint来完成。

先使用 ESlint 做代码检查,然后再使用Babel做代码兼容性处理。

ESlint

可组装的JavaScript和JSX检查工具。
使用ESlint关键是使用它的配置文件,里面写的各种rule规则,将来运行ESlint时就会以写的规则对代码进行检查。

配置文件

配置文件有很多种写法:

  • .eslintrc:新建文件,位于项目根目录
    • .eslintrc
    • .eslintrc.js
    • .eslintrc.json
  • package.jsoneslintConfig不需要配置文件,在原有的文件基础上写。
    ESlint 会查找和自动读取它们,所以以上配置文件只需要存在一个即可。
具体配置

我们以 .eslintrc.js 配置文件为例:

module.exports = {
    // 解析选项
    parserOptions:{},
    // 具体检查规则
    rules:{},
    // 继承其他规则
    extends:[],
}

ESlint 规则

  • parserOptions 解析选项
{
    parserOptions:{
        ecmaVersion: 6 // ES 语法版本
        sourceType: "module" // ES 模块化
        ecmaFeatures:{
            // ES 其他特性
            // 如果是 react 项目 需要开启
            jsx:true 
        }
    }
}   
  • rule规则
    • off0 - 关闭规则
    • warn1 - 开启规则,使用警告级别的错误:warn(不会导致程序退出)。
    • error2 - 开启规则,使用错误级别的错误:error(当被触发的时候,程序会退出)。
{
    rules:{
        semi:"error", // 禁止使用分号
        'array-callback-return':'warn', // 强制数组的回调函数中有 return 语句,否则警告。
        'default-case':[
            'warn', // 要求 switch 语句中有 default分支,否则警告
            {
                commentPattern:'^no default$' // 允许在最后注释:no default ,就不会有警告。
            }
        ],
        eqeqeq:[
            'warn', // 强制使用 === 和 !==,否则警告。
            'smart' // 
        ]
    }
}
  • extends 继承
    开发中一点点写rules规则太费劲,所以有更好的办法,继承现有的规则。
    现有如下较为有名的规则:
    • Eslint官方规则:eslint:recommended
    • Vue Cli官方规则:plugin:vue/essential
    • React Cli官方规则:reat-app
{
    extends:["react-app"],
    rules:{
        // 我们的规则会覆盖掉react-app的规则
        // 所以想要修改规则直接改就行
        eqeqeq:["warn","smart"]
    }
}
在webpack中使用
  • 下载包
npm i eslint-webpack-plugin eslint -D
  • 定义Eslint配置文件
    • .eslintrc.js
    import globals from "globals";
    import pluginJs from "@eslint/js";
    import pluginVue from "eslint-plugin-vue";
    
    
    /** @type {import('eslint').Linter.Config[]} */
    export default [
        { files: ["**/*.{js,mjs,cjs,vue}"] },
        { languageOptions: { globals: globals.browser } },
        pluginJs.configs.recommended,
        ...pluginVue.configs["flat/essential"],
        {
            rules: {
            "no-var": 2 // 不能使用var定义变量
            }
         }, {
        ignorePatterns: ["./config/*", "./dist/*", "*.config.js"]
        }
    ];
    
  • 下载插件
npm init @eslint/config@latest

  • 配置eslint.config.mjs
import globals from "globals";
import pluginJs from "@eslint/js";
import pluginVue from "eslint-plugin-vue";


/** @type {import('eslint').Linter.Config[]} */
export default [
  { files: ["**/*.{js,mjs,cjs,vue}"] },
  { languageOptions: { globals: globals.browser } },
  pluginJs.configs.recommended,
  ...pluginVue.configs["flat/essential"],
  {
    rules: {
      "no-var": 2 // 不能使用var定义变量
    }
  }, {
    ignores: ["webpack.config.js", "dist/"]
  }
];
  • 配置webpack.config.js
{

    plugins: [
        new ESLintPlugin({
            context: path.resolve(__dirname, "src")
        })
    ],
}

Babel

JavaScript 编译器。
主要用于将 ES6 语法编写的代码转换为向后兼容的JavaScript语法,以便能够运行在当前和旧版本的浏览器或者其他环境中。

配置文件

配置文件有很多种写法:

  • babel.config.*:新建文件,位于项目根目录。
    • babel.config.js
    • babel.config.json
  • .babelrc.*:新建文件,位于项目根目录。
    • .babelrc
    • babelrc.js
    • bablerc.json
  • package.jsonbabel:不需要创建文件,在原有文件基础上写。
    Babel 会查找和自动读取它们,所以以上配置文件只需要存在一个即可。
具体配置

我们babel.config.js配置文件为例:

module.exports = {
    // 预设
    presets:[]
}
  • presets预设
    简单理解:就是一组Babel插件,扩展Babel功能。

  • @babel/preset-env:智能预设,允许使用最新JavaScript。

  • @babel/preset-react:用来编译React jsx 语法预设。

  • @babel/preset-typescript:用来编译TypeScript语法的预设。

webpack中的使用
  • 下载包
npm i babel-loader @babel/core @babel/preset-env -D
  • 定义Babel配置文件
    创建文件 babel.config.js
module.exports = {
    // 智能预设,编译es6语法
    presets: ["@babel/preset-env"]
}
  • webpack.config.js 配置文件
{
    module:{
            test: /\.js$/,
            // 排除node_modules中的js文件(这些文件不处理)
            exclude: /node_modules/,
            loader: "babel-loader"
    }
}

处理Html资源

下载包

npm i html-webpack-plugin -D

配置

  • webpack.config.js
{
    plugins:[
        new htmlWebpackPlugin({
            template:path.resolve(__dirname,"public/html")
        })
    ]
}

开发服务器&自动化

自动化编译代码

下载包

npm i webpack-dev-server -D

配置

  • webpack.config.js
{
    // 开发服务器不会输出资源,在内存中编译打包的
    devServer: {
        // 启动服务器域名
        host: "localhost",
        port: "3000",
        open: true
    },
}
  • 运行指令
npx webpack serve

总结

const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require("path")
module.exports = {
    //入口
    entry: "./src/main.js",
    // 输出
    output: {
        // 文件的输出路径
        path: path.resolve(__dirname, "dist"),
        filename: "main.js",
        clean: true
    },
    // 加载器
    module: {
        // loader的配置
        rules: [{
            test: /\.css$/,
            use: [
                // 执行的顺序,从右到左(从上到下)
                "style-loader", // 将js中css通过创建style标签添加html文件中生效
                "css-loader" // 将样式编译成commonjs的模块
            ]
        }, {
            test: /\.less$/,
            // loader:'xxx'只能使用单个loader
            // user 使用多个loader
            use: [
                "style-loader",
                "css-loader",
                "less-loader" // 将Less 编译成css文件
            ]
        }, {
            test: /\.s[ac]ss$/,
            use: [
                "style-loader",
                "css-loader",
                "sass-loader"
            ]
        }, {
            test: /\.styl$/,
            use: [
                "style-loader",
                "css-loader",
                "stylus-loader"
            ]
        }, {
            test: /\.(png|jpe?g|gif|webp)$/,
            type: "asset",
            parser: {
                dataUrlCondition: {
                    // 小于 10 kb 转base64
                    // 优点:减少请求数量,缺点:打包后的结果体积增大
                    maxSize: 20 * 1024,
                }
            },
            generator: {
                // 输出图片名称
                // [hash:10] hash 值取前10位
                filename: "static/images/[hash:10][ext][query]"
            }
        }, {
            test: /\.ttf|worff?$/,
            generator: {
                // [hash:10] hash 值取前10位
                filename: "static/font/[hash:10][ext][query]"
            }
        }, {
            test: /\.video|audio|xsl|doc$/,
            generator: {
                // [hash:10] hash 值取前10位
                filename: "static/media/[hash:10][ext][query]"
            }
        }, {
            test: /\.js$/,
            exclude: /node_modules/,
            loader: "babel-loader"
        }]
    },
    // 插件
    plugins: [
        new ESLintPlugin({
            context: path.resolve(__dirname, "src")
        }),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "./index.html")
        })
    ],
    devServer: {
        // 启动服务器域名
        host: "localhost",
        port: "3000",
        open: true
    },
    // 模式 
    mode: "development"
}

生产环境搭建

  • 根目录下创建文件夹config存放文件webpack.dev.jswebpack.prod.js
    • webpack.dev.js
    const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require("path")
module.exports = {
    //入口
    entry: "./src/main.js",
    // 输出
    output: {
        // 文件的输出路径
        path: undefined,
        filename: "main.js",
        clean: true
    },
    // 加载器
    module: {
        // loader的配置
        rules: [{
            test: /\.css$/,
            use: [
                // 执行的顺序,从右到左(从上到下)
                "style-loader", // 将js中css通过创建style标签添加html文件中生效
                "css-loader" // 将样式编译成commonjs的模块
            ]
        }, {
            test: /\.less$/,
            // loader:'xxx'只能使用单个loader
            // user 使用多个loader
            use: [
                "style-loader",
                "css-loader",
                "less-loader" // 将Less 编译成css文件
            ]
        }, {
            test: /\.s[ac]ss$/,
            use: [
                "style-loader",
                "css-loader",
                "sass-loader"
            ]
        }, {
            test: /\.styl$/,
            use: [
                "style-loader",
                "css-loader",
                "stylus-loader"
            ]
        }, {
            test: /\.(png|jpe?g|gif|webp)$/,
            type: "asset",
            parser: {
                dataUrlCondition: {
                    // 小于 10 kb 转base64
                    // 优点:减少请求数量,缺点:打包后的结果体积增大
                    maxSize: 20 * 1024,
                }
            },
            generator: {
                // 输出图片名称
                // [hash:10] hash 值取前10位
                filename: "static/images/[hash:10][ext][query]"
            }
        }, {
            test: /\.ttf|worff?$/,
            generator: {
                // [hash:10] hash 值取前10位
                filename: "static/font/[hash:10][ext][query]"
            }
        }, {
            test: /\.video|audio|xsl|doc$/,
            generator: {
                // [hash:10] hash 值取前10位
                filename: "static/media/[hash:10][ext][query]"
            }
        }, {
            test: /\.js$/,
            exclude: /node_modules/,
            loader: "babel-loader"
        }]
    },
    // 插件
    plugins: [
        new ESLintPlugin({
            context: path.resolve(__dirname, "../src")
        }),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "../index.html")
        })
    ],
    devServer: {
        // 启动服务器域名
        host: "localhost",
        port: "3000",
        open: true
    },
    // 模式 
    mode: "development"
}
  • webpack.prod.js
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require("path")
module.exports = {
    //入口
    entry: "./src/main.js",
    // 输出
    output: {
        // 文件的输出路径
        path: path.resolve(__dirname, "dist"),
        filename: "main.js",
        clean: true
    },
    // 加载器
    module: {
        // loader的配置
        rules: [{
            test: /\.css$/,
            use: [
                // 执行的顺序,从右到左(从上到下)
                "style-loader", // 将js中css通过创建style标签添加html文件中生效
                "css-loader" // 将样式编译成commonjs的模块
            ]
        }, {
            test: /\.less$/,
            // loader:'xxx'只能使用单个loader
            // user 使用多个loader
            use: [
                "style-loader",
                "css-loader",
                "less-loader" // 将Less 编译成css文件
            ]
        }, {
            test: /\.s[ac]ss$/,
            use: [
                "style-loader",
                "css-loader",
                "sass-loader"
            ]
        }, {
            test: /\.styl$/,
            use: [
                "style-loader",
                "css-loader",
                "stylus-loader"
            ]
        }, {
            test: /\.(png|jpe?g|gif|webp)$/,
            type: "asset",
            parser: {
                dataUrlCondition: {
                    // 小于 10 kb 转base64
                    // 优点:减少请求数量,缺点:打包后的结果体积增大
                    maxSize: 20 * 1024,
                }
            },
            generator: {
                // 输出图片名称
                // [hash:10] hash 值取前10位
                filename: "static/images/[hash:10][ext][query]"
            }
        }, {
            test: /\.ttf|worff?$/,
            generator: {
                // [hash:10] hash 值取前10位
                filename: "static/font/[hash:10][ext][query]"
            }
        }, {
            test: /\.video|audio|xsl|doc$/,
            generator: {
                // [hash:10] hash 值取前10位
                filename: "static/media/[hash:10][ext][query]"
            }
        }, {
            test: /\.js$/,
            exclude: /node_modules/,
            loader: "babel-loader"
        }]
    },
    // 插件
    plugins: [
        new ESLintPlugin({
            context: path.resolve(__dirname, "../src")
        }),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "../index.html")
        })
    ],
    // devServer: {
    //     // 启动服务器域名
    //     host: "localhost",
    //     port: "3000",
    //     open: true
    // },
    // 模式 
    mode: "production"
}
  • 修改package.json
{
    "scripts": {
        "dev": "webpack server --config ./config/webpack.dev.js",
        "build": "webpack --config ./config/webpack.prod.js"
    },
}

CSS处理

提取CSS成单独文件

CSS 文件目前是被打包到JS文件中,当JS文件加载时,会创建一个style标签来生成样式。
这样对网站来说,会出现闪屏现象,用户体验不太好。
我们应该将CSS文件提取,通过link标签引入。

  • 下载包
npm i install mini-css-extract-plugin -D
  • 配置
    webpack.prod.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  plugins: [new MiniCssExtractPlugin({

  })],
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
    ],
  },
};

CSS兼容处理

  • 下载包
npm i postcss-loader postcss postcss-preset-env -D
  • 配置
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path")
function getStyleloader(pre) {
    return [
        MiniCssExtractPlugin.loader,
        "css-loader",
        {
            loader: "postcss-loader",
            options: {
                postcssOptions: {
                    plugins: [
                        "postcss-preset-env"
                    ]
                }
            }
        },
        pre
    ].filter(Boolean)
}
module.exports = {
    //入口
    entry: "./src/main.js",
    // 输出
    output: {
        // 文件的输出路径
        path: path.resolve(__dirname, "dist"),
        filename: "main.js",
        clean: true
    },
    // 加载器
    module: {
        // loader的配置
        rules: [{
            test: /\.css$/,
            use: getStyleloader()
        }, {
            test: /\.less$/,
            // loader:'xxx'只能使用单个loader
            // user 使用多个loader
            use: getStyleloader("less-loader")
        }, {
            test: /\.s[ac]ss$/,
            use: getStyleloader("sass-loader")
        }, {
            test: /\.styl$/,
            use: getStyleloader("stylus-loader")
        }, {
            test: /\.(png|jpe?g|gif|webp)$/,
            type: "asset",
            parser: {
                dataUrlCondition: {
                    // 小于 10 kb 转base64
                    // 优点:减少请求数量,缺点:打包后的结果体积增大
                    maxSize: 20 * 1024,
                }
            },
            generator: {
                // 输出图片名称
                // [hash:10] hash 值取前10位
                filename: "static/images/[hash:10][ext][query]"
            }
        }, {
            test: /\.ttf|worff?$/,
            generator: {
                // [hash:10] hash 值取前10位
                filename: "static/font/[hash:10][ext][query]"
            }
        }, {
            test: /\.video|audio|xsl|doc$/,
            generator: {
                // [hash:10] hash 值取前10位
                filename: "static/media/[hash:10][ext][query]"
            }
        }, {
            test: /\.js$/,
            exclude: /node_modules/,
            loader: "babel-loader"
        }]
    },
    // 插件
    plugins: [
        new ESLintPlugin({
            context: path.resolve(__dirname, "../src")
        }),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "../index.html")
        }),
        new MiniCssExtractPlugin({
            filename: "static/css/index.css"
        })
    ],
    // devServer: {
    //     // 启动服务器域名
    //     host: "localhost",
    //     port: "3000",
    //     open: true
    // },
    // 模式 
    mode: "production"
}
  • package.json
{
    "browserslist": [
        "last 2 version",
        "> 1%",
        "not dead"
    ]
}

CSS压缩

  • 下载包
npm i css-minimizer-webpack-plugin -D
  • 配置
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin")
module.exports = {
    plugins: [
        new CssMinimizerPlugin()
    ],
}

html压缩

默认生产模式已经开启了html压缩和js压缩,不需要额外配置。


http://www.kler.cn/a/592451.html

相关文章:

  • Minecraft命令总结(持续更新)
  • python本地连接minio
  • 【Android】安卓 Java下载ZIP文件并解压(笔记)
  • 知识图谱知识库汇总
  • 算法刷题区域部分反转
  • Git 新建本地分支并关联到远程仓库
  • RG-S3760应用协议配置
  • 基于javaweb的SpringBoot药房管理系统设计与实现(源码+文档+部署讲解)
  • 逆向入门 汇编语言IDA的基本使用
  • 【java面型对象进阶】------继承实例
  • VBA技术资料MF281:驱动器列表和类型
  • 学习threejs,构建THREE.ParametricGeometry参数化函数生成几何体
  • 基于 Quest 摄像头数据开发的原理介绍【Unity Meta Quest MR 开发教程】
  • 微前端 qiankun vite vue3
  • 使用码云搭建CocoaPods远程私有库
  • 人事档案管理系统基于Spring BootSSM
  • LS-NET-006-思科MDS 9148S 查看内存
  • 【微服务】基于Lambda ESM的预留模式调整Kafka ESM吞吐量的实战
  • Spring Boot集成MyBatis与MySQL
  • Swagger-告别手写文档