Webpack: 核心配置结构

概述

Webpack 是一种 「配置」 驱动的构建工具,所以站在应用的角度,必须深入学习 Webpack 的各项配置规则,才能灵活应对各种构建需求。本文将作为小册应用系列的一个总结,汇总与应用配置相关的各项知识点,包括:

  1. 剖析配置结构规则,解释对象、数组、函数三种形态的写法,以及各自应对的场景;
  2. 详细讲解环境治理的意义,以及如何借助多文件实现环境治理;
  3. 完整、清晰地介绍若干核心配置项:entry/output/target/mode,帮助你更深入理解配置规则。

配置结构详解

在前面章节中,我们已经编写了许多 Webpack 配置示例,其大多数都以单文件导出单个配置对象方式实现,类似:

module.exports = {entry: './src/index.js',// 其它配置...
};

实际上,Webpack 还支持以数组、函数方式配置运行参数,以适配不同场景应用需求,它们之间大致上区别:

  • 单个配置对象:比较常用的一种方式,逻辑简单,适合大多数业务项目;
  • 配置对象数组:每个数组项都是一个完整的配置对象,每个对象都会触发一次单独的构建,通常用于需要为同一份代码构建多种产物的场景,如 Library;
  • 函数:Webpack 启动时会执行该函数获取配置,我们可以在函数中根据环境参数(如 NODE_ENV)动态调整配置对象。

下面我们着重介绍数组、函数两种方式。

使用配置数组:

导出数组的方式很简单,如:

// webpack.config.js
module.exports = [{entry: './src/index.js',// 其它配置...
}, {entry: './src/index.js',// 其它配置...
}];

使用数组方式时,Webpack 会在启动后创建多个 Compilation 实例,并行执行构建工作,但需要注意,Compilation 实例间基本上不作通讯,这意味着这种并行构建对运行性能并没有任何正向收益,例如某个 Module 在 Compilation 实例 A 中完成解析、构建后,在其它 Compilation 中依然需要完整经历构建流程,无法直接复用结果。

数组方式主要用于应对“同一份代码打包出多种产物”的场景,例如在构建 Library 时,我们通常需要同时构建出 ESM/CMD/UMD 等模块方案的产物,如:

// webpack.config.js
module.exports = [{output: {filename: './dist-amd.js',libraryTarget: 'amd',},name: 'amd',entry: './app.js',mode: 'production',},{output: {filename: './dist-commonjs.js',libraryTarget: 'commonjs',},name: 'commonjs',entry: './app.js',mode: 'production',},
];
  • 提示:使用配置数组时,还可以通过 --config-name 参数指定需要构建的配置对象,例如上例配置中若执行 npx webpack --config-name='amd',则仅使用数组中 name='amd' 的项做构建。

此时适合使用配置数组方式解决;若是“多份代码打包多份产物”的场景,则建议使用 entry 配置多个应用入口。

使用数组方式时,我们还可以借助 webpack-merge 工具简化配置逻辑,如:

const { merge } = require("webpack-merge");const baseConfig = {output: {path: "./dist"},name: "amd",entry: "./app.js",mode: "production",
};module.exports = [merge(baseConfig, {output: {filename: "[name]-amd.js",libraryTarget: "amd",},}),merge(baseConfig, {output: {filename: "./[name]-commonjs.js",libraryTarget: "commonjs",},}),
];
  • 提示:webpack-merge 是 Webpack 生态内专门用于合并配置对象的工具,后面我们还会展开讲解使用方法。

示例中将公共配置抽取为 baseConfig 对象,之后配合 webpack-merge 创建不同目标数组项,这种方式可有效减少重复的配置代码,非常推荐使用。

使用配置函数:

配置函数方式要求在配置文件中导出一个函数,并在函数中返回 Webpack 配置对象,或配置数组,或 Promise 对象,如:

module.exports = function(env, argv) {// ...return {entry: './src/index.js',// 其它配置...}
}

运行时,Webpack 会传入两个环境参数对象:

  • env:通过 --env 传递的命令行参数,适用于自定义参数,例如:
命令:env 参数值:
npx webpack --env prod{ prod: true }
npx webpack --env prod --env min{ prod: true, min: true }
npx webpack --env platform=app --env production{ platform: “app”, production: true }
npx webpack --env foo=bar=app{ foo: “bar=app”}
npx webpack --env app.platform=“staging” --env app.name=“test”{ app: { platform: “staging”, name: “test” }
  • argv:命令行 Flags 参数,支持 entry/output-path/mode/merge 等。

配置函数 这种方式的意义在于,允许用户根据命令行参数动态创建配置对象,可用于实现简单的多环境治理策略,例如:

// npx webpack --env app.type=miniapp --mode=production
module.exports = function (env, argv) {return {mode: argv.mode ? "production" : "development",devtool: argv.mode ? "source-map" : "eval",output: {path: path.join(__dirname, `./dist/${env.app.type}`,filename: '[name].js'},plugins: [new TerserPlugin({terserOptions: {compress: argv.mode === "production", },}),],};
};

示例支持通过命令行传入 env.app.typeargv.mode 值,决定最终配置结构,我们可以为不同场景传入不同命令行参数,从而实现环境隔离效果。

不过这种方式并不常用,一是因为需要在配置函数内做许多逻辑判断,复杂场景下可能可读性会很低,维护成本高;二是强依赖于命令行参数,可能最终需要写出一串很长的运行命令,应用体验较差。目前社区比较流行通过不同配置文件区分不同环境的运行配置,配合 --config 参数实现环境治理,下面我们会展开讲解这种方案。

最后简单总结下,Webpack 支持三种配置方式:对象、数组、函数,其中对象方式最简单,且能够应对大多数业务开发场景,所以使用率最高;数组方式主要用于构建 Library 场景;函数方式灵活性较高,可用于实现一些简单的环境治理策略。同学们可根据实际场景,择优选用。

环境治理策略

在现代前端工程化实践中,通常需要将同一个应用项目部署在不同环境(如生产环境、开发环境、测试环境)中,以满足项目参与各方的不同需求。这就要求我们能根据部署环境需求,对同一份代码执行各有侧重的打包策略,例如:

  • 开发环境需要使用 webpack-dev-server 实现 Hot Module Replacement;
  • 测试环境需要带上完整的 Soucemap 内容,以帮助更好地定位问题;
  • 生产环境需要尽可能打包出更快、更小、更好的应用代码,确保用户体验。

Webpack 中有许多实现环境治理的方案,比如上面介绍过的,使用“配置函数”配合命令行参数动态计算配置对象。除此之外,业界比较流行将不同环境配置分别维护在单独的配置文件中,如:

.
└── config├── webpack.common.js├── webpack.development.js├── webpack.testing.js└── webpack.production.js

之后配合 --config 选项指定配置目标,如:

npx webpack --config webpack.development.js

这种模式下通常会将部分通用配置放在基础文件中,如上例的 webpack.common.js,之后在其它文件中引入该模块并使用 webpack-merge 合并配置对象。

webpack-merge 是一个专为 Webpack 设计的数据合并(merge)的工具,功能逻辑与 Lodash 的 merge 函数、 Object.assign 等相似,但支持更多特性,如:

  • 支持数组属性合并,例如:

    merge({ arr: [1] }, { arr: [2] }) === { arr: [1, 2] }
    
  • 支持函数属性合并,例如:

    const res = merge({ func: () => console.log(1) },{ func: () => console.log(2) }
    );
    res.func();
    // => 1,2 
    
  • 支持设定对象合并策略,支持 match/append/prepend/replace/merge 规则;

  • 支持传入自定义对象合并函数,等等。

这些特性能更好地支持 Webpack 这种高度复杂的数据合并场景,例如对于 module.rules 数组,若只是使用 Object.assign 做合并,则只会导致后面对象属性替换了前面对象属性;而使用 webpack-merge 能够实现两个数组项合并,更符合预期。

接下来,我们用一个示例,简单串一下与 webpack-merge 实现环境管理的过程。首先我们需要将通用配置放在公共文件中,如:

// webpack.common.js
const path = require("path");
const HTMLWebpackPlugin = require("html-webpack-plugin");module.exports = {entry: { main: "./src/index.js" },output: {filename: "[name].js",path: path.resolve(__dirname, "dist"),},module: {rules: [{test: /\.js$/,use: ["babel-loader"],},],},plugins: [new HTMLWebpackPlugin()],
};

其次,需要安装 webpack-merge 做配置合并操作:

yarn add -D webpack-merge

之后,创建对应环境配置文件,如 webpack.development.js,并输入开发环境专用配置代码,如:

// webpack.development.js
const { merge } = require("webpack-merge");
const baseConfig = require("./webpack.common");// 使用 webpack-merge 合并配置对象
module.exports = merge(baseConfig, {mode: "development",devtool: "source-map",devServer: { hot: true },
});

最后,执行构建命令并通过 --config 参数传入配置文件路径,如:

npx webpack --config=webpack.development.js

至此,样例大致搭建完毕,接下来我们还可以继续为更多构建环境配备特定的配置文件,流程同上,此处不再赘述。

核心配置项汇总

在前面章节中,我们已经基于各种应用场景综合讲解了 Webpack 方方面面的应用方法,其中涉及多达上百种配置项,不太可能一一详细讲解,但大致上可以划分下图中展示的几种分类:

请添加图片描述

包括:流程配置、性能优化类配置、日志类配置、开发效率类配置等,这里面较常用,需要着重学习的配置有:

  • entry:声明项目入口文件,Webpack 会从这个文件开始递归找出所有文件依赖;
  • output:声明构建结果的存放位置;
  • target:用于配置编译产物的目标运行环境,支持 webnodeelectron 等值,不同值最终产物会有所差异;
  • mode:编译模式短语,支持 developmentproduction 等值,Webpack 会根据该属性推断默认配置;
  • optimization:用于控制如何优化产物包体积,内置 Dead Code Elimination、Scope Hoisting、代码混淆、代码压缩等功能;
  • module:用于声明模块加载规则,例如针对什么类型的资源需要使用哪些 Loader 进行处理;
  • plugin:Webpack 插件列表。

其中,optimization/module/plugin 属性将在后续章节做专门介绍,此处先不展开。接下来我们将集中讲解 entry/output/target/mode 属性,帮你更全面、立体、透彻地理解 Webpack 配置项逻辑。

entry 配置详解

Webpack 的基本运行逻辑是从 「入口文件」 开始,递归加载、构建所有项目资源,所以几乎所有项目都必须使用 entry 配置项明确声明项目入口。entry 配置规则比较复杂,支持如下形态:

  • 字符串:指定入口文件路径;
  • 对象:对象形态功能比较完备,除了可以指定入口文件列表外,还可以指定入口依赖、Runtime 打包方式等;
  • 函数:动态生成 Entry 配置信息,函数中可返回字符串、对象或数组;
  • 数组:指明多个入口文件,数组项可以为上述介绍的文件路径字符串、对象、函数形式,Webpack 会将数组指明的入口全部打包成一个 Bundle。

例如:

module.exports = {//...entry: {// 字符串形态home: './home.js',// 数组形态shared: ['react', 'react-dom', 'redux', 'react-redux'],// 对象形态personal: {import: './personal.js',filename: 'pages/personal.js',dependOn: 'shared',chunkLoading: 'jsonp',asyncChunks: true},// 函数形态admin: function() {return './admin.js';}},
};

这其中,「对象」 形态的配置逻辑最为复杂,支持如下配置属性:

  • import:声明入口文件,支持路径字符串或路径数组(多入口);
  • dependOn:声明该入口的前置依赖 Bundle;
  • runtime:设置该入口的 Runtime Chunk,若该属性不为空,Webpack 会将该入口的运行时代码抽离成单独的 Bundle;
  • filename:效果与 output.filename 类同,用于声明该模块构建产物路径;
  • library:声明该入口的 output.library 配置,一般在构建 NPM Library 时使用;
  • publicPath:效果与 output.publicPath 相同,用于声明该入口文件的发布 URL;
  • chunkLoading:效果与 output.chunkLoading 相同,用于声明异步模块加载的技术方案,支持 false/jsonp/require/import 等值;
  • asyncChunks:效果与 output.asyncChunks 相同,用于声明是否支持异步模块加载,默认值为 true

而这些属性中,dependOnruntime 最为晦涩难懂,有必要构造实例,展开讲解。

使用 entry.dependOn 声明入口依赖:

dependOn 属性用于声明前置 Bundle 依赖,从效果上看能够减少重复代码,优化构建产物质量。例如:

module.exports = {// ...entry: {main: "./src/index.js",foo: { import: "./src/foo.js", dependOn: "main" },},
};

示例中,foo 入口的 dependOn 属性指向 main 入口,此时 Webpack 认为:客户端在加载 foo 产物之前必然会加载 main,因此可以将重复的模块代码、运行时代码等都放到 main 产物,减少不必要的重复,最终打包结果:
请添加图片描述

左边为 main 产物,包含所有模块、运行时代码,与普通 Bundle 无异;右边为 foo 产物,代码结构非常清爽。作为对比,若不指定 dependOn 属性,则构建结果:
请添加图片描述

可以看出两边内容并无差异。

dependOn 适用于哪些有明确入口依赖的场景,例如我们构建了一个主框架 Bundle,其中包含了项目基本框架(如 React),之后还需要为每个页面单独构建 Bundle,这些页面代码也都依赖于主框架代码,此时可用 dependOn 属性优化产物内容,减少代码重复。

使用 entry.runtime 管理运行时代码:

为支持产物代码在各种环境中正常运行,Webpack 会在产物文件中注入一系列运行时代码,用以支撑起整个应用框架。运行时代码的多寡取决于我们用到多少特性,例如:

  • 需要导入导出文件时,将注入 __webpack_require__.r 等;
  • 使用异步加载时,将注入 __webpack_require__.l 等;
  • 等等。

不要小看运行时代码量,极端情况下甚至有可能超过业务代码总量!为此,必要时我们可以尝试使用 runtime 配置将运行时抽离为独立 Bundle,例如:

const path = require("path");module.exports = {mode: "development",devtool: false,entry: {main: { import: "./src/index.js", runtime: "common-runtime" },foo: { import: "./src/foo.js", runtime: "common-runtime" },},output: {clean: true,filename: "[name].js",path: path.resolve(__dirname, "dist"),},
};

示例中,mainfoo 入口均将 runtime 声明为 common-runtime,此时 Webpack 会将这两个入口的运行时代码都抽取出来,放在 common-runtime Bundle 中,效果:

请添加图片描述

entry.runtime 是一种常用的应用性能优化手段,建议大家多做尝试、使用。

使用 output 声明输出方式

Webpack 的 output 配置项用于声明:如何输出构建结果,比如产物放在什么地方、文件名是什么、文件编码等。output 支持许多子配置项,包括:

  • output.path:声明产物放在什么文件目录下;
  • output.filename:声明产物文件名规则,支持 [name]/[hash] 等占位符;
  • output.publicPath:文件发布路径,在 Web 应用中使用率较高;
  • output.clean:是否自动清除 path 目录下的内容,调试时特别好用;
  • output.library:NPM Library 形态下的一些产物特性,例如:Library 名称、模块化(UMD/CMD 等)规范;
  • output.chunkLoading:声明加载异步模块的技术方案,支持 false/jsonp/require 等方式。
  • 等等。

对于 Web 应用场景,多数情况下我们只需要使用 path/filename/publicPath 即可满足需求,其它属性使用率不高,篇幅关系,此处不再赘述。

使用 target 设置构建目标

虽然多数时候 Webpack 都被用于打包 Web 应用,但实际上 Webpack 还支持构建 Node、Electron、NW.js、WebWorker 等应用形态,这一特性主要通过 target 配置控制,支持如下数值:

  • node[[X].Y]:编译为 Node 应用,此时将使用 Node 的 require 方法加载其它 Chunk,支持指定 Node 版本,如:node12.13
  • async-node[[X].Y]:编译为 Node 应用,与 node 相比主要差异在于:async-node 方式将以异步(Promise)方式加载异步模块(node 时直接使用 require)。支持指定 Node 版本,如:async-node12.13
  • nwjs[[X].Y]:编译为 NW.js 应用;
  • node-webkit[[X].Y]:同 nwjs
  • electron[[X].Y]-main:构建为 Electron 主进程;
  • electron[[X].Y]-renderer:构建为 Electron 渲染进程;
  • electron[[X].Y]-preload:构建为 Electron Preload 脚本;
  • web:构建为 Web 应用;
  • esX:构建为特定版本 ECMAScript 兼容的代码,支持 es5es2020 等;
  • browserslist:根据浏览器平台与版本,推断需要兼容的 ES 特性,数据来源于 Browserslist 项目,用法如:browserslist: 'last 2 major versions'

不同构建目标会根据平台特性打包出略有差异的结果(主要体现在运行时与 NPM Library),例如对于下面这种使用了异步导入的代码:

// foo.js
export default "foo";// index.js 
import("./foo").then(console.log);

使用如下配置,同时构建 nodeweb 版本:

const path = require("path");
const { merge } = require("webpack-merge");const baseConfig = {mode: "development",target: "web",devtool: false,entry: {main: { import: "./src/index.js" },},output: {clean: true,path: path.resolve(__dirname, "dist"),},
};module.exports = [merge(baseConfig, { target: "web", output: { filename: "web-[name].js" } }),merge(baseConfig, { target: "node", output: { filename: "node-[name].js" } }),
];

之后,执行构建命令,结果:
请添加图片描述

可以看到左边 web 版本中需要注入使用 JSONP 异步加载 JS 文件的运行时代码;而右边 node 版本则可以直接使用 Node 环境下的 require 实现异步加载,因此不需要注入相关运行时。

使用 mode 短语

Webpack 内置 了许多构建优化策略,我们可以通过 mode 配置项切换默认优化规则,支持如下值:

  • production:默认值,生产模式,使用该值时 Webpack 会自动帮我们开启一系列优化措施:Three-Shaking、Terser 压缩代码、SplitChunk 提起公共代码,通常用于生产环境构建;
  • development:开发模式,使用该值时 Webpack 会保留更语义化的 Module 与 Chunk 名称,更有助于调试,通常用于开发环境构建;
  • none:关闭所有内置优化规则。

mode 规则比较简单,一般在开发模式使用 mode = 'development',生产模式使用 mode = 'production' 即可。

总结

至此,关于 Webpack 配置规则的重要知识点就补充完毕了,我们主要需要理解:

  • Webpack 配置文件支持导出对象、数组、函数三种形态,其中对象形式最为常用,足够应对多数业务项目场景;数组形式适用于需要为同一份代码同时构建多种产物的场景,如 NPM Library;函数形态适用于需要动态生成配置规则的场景;
  • 为方便管理配置逻辑,我们通常需要引入一些环境治理策略,目前业界比较常用单独配置文件管理单个构建环境;
  • entry 配置项支持字符串、对象、函数、数组等方式,其中对象形式下的 dependOn/runtime 规则比较复杂,建议深入学习;
  • output 用于声明构建产物的输出规则;
  • target 用于设置构建目标,不同目标会导致产物内容有轻微差异,支持 Node、Web、Electron、WebWorker 等场景;
  • mode 构建模式,支持 development/production/none 三种值。

结合前面若干应用介绍的章节,相信已经帮你搭建起一套体系化的应用方法论,已经足以应付大多数业务场景。后续章节我们将转入更高阶的内容,包括:如何开发 Loader、Plugin;如何优化构建与应用性能;Webpack 构建原理等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/38408.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高并发场景下的热点key问题探析与应对策略

目录 一、问题描述 二、发现机制 三、解决策略分析 (一)解决策略一:多级缓存策略 客户端本地缓存 代理节点本地缓存 (二)解决策略二:多副本策略 (三)解决策略三:热点…

XJTUSE-数据结构-homework1

任务 1 题目: 排序算法设计: 需要写Selection、Shell、Quicksort 和 Mergesort四种排序算法,书上讲述比较全面而且不需要进行额外的优化,下面我简要地按照自己的理解讲述。 Selection(选择排序)&#xff…

关于Redisson分布式锁的用法

关于Redisson分布式锁的用法 Redisson是一个基于Redis的Java分布式对象和服务框架,它提供了多种分布式锁的实现,包括可重入锁、公平锁、读写锁等。Redisson实现分布式锁的核心原理主要依赖于Redis的数据结构和Redisson框架提供的高级功能。以下详细讲解…

深度学习11-20

1.神经元的个数对结果的影响: (http://cs.stanford.edu/people/karpathy/convnetjs/demo/classify2d.html) (1)神经元3个的时候 (2)神经元是10个的时候 神经元个数越多,可能会产生…

第3章-数据类型和运算符

#本章目标 掌握Python中的保留字与标识符 理解Python中变量的定义及使用 掌握Python中基本数据类型 掌握数据类型之间的相互转换 掌握eval()函数的使用 了解不同的进制数 掌握Python中常用的运算符及优先级1,保留字与标识符 保留字 指在Python中被赋予特定意义的一…

[C++][设计模式][备忘录模式]详细讲解

目录 1.动机2.模式定义3.要点总结4.代码感受 1.动机 在软件构建过程中,某些对象的状态转换过程中,可能由于某中需要,要求程序能够回溯到对象之前处于某个点的状态。 如果使用一些公开接口来让其他对象得到对象的状态,便会暴露对象…

pygame下载安装流程

方案一:直接下载 使用cmd打开窗口: 使用命令:pip install pygame即可下载最新pygame安装包 方案二:下载指定版本 我们需要去python官网查看对应包和发布版本: python官网 进去后点击PyPI,查找python发布…

初阶数据结构之堆讲解

本篇文章带大家学习的是堆,还请各位观众老爷给个三连 正片开始 堆的概念 如果有一个关键码的集合 K { , , , … , } ,把它的所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中,并满…

【Redis】主从复制

https://www.bilibili.com/video/BV1cr4y1671t?p101 https://blog.csdn.net/weixin_54232666/article/details/128825763 单节点Redis的并发能力是有上限的,要进一步提高Redist的并发能力,就需要搭建主从集群,实现读写分离。 主从搭建 这…

访客(UV)、点击量(PV)、IP、访问量(VV)概念

1、https://www.cnblogs.com/QingPingZm/articles/13855808.htmlhttps://www.cnblogs.com/QingPingZm/articles/13855808.html

监控电脑的软件有哪些?精选8大监控电脑的软件

根据当前市场反馈和功能评价,以下是八款备受推崇的电脑监控软件推荐,适合不同企业和组织的监控与管理需求: 1.安企神监控软件 特点:全面的局域网监控工具,擅长网络设备监控、网络性能管理和故障诊断。提供员工电脑屏幕…

计算机网络:408考研|湖科大教书匠|原理参考模型II|学习笔记

系列目录 计算机网络总纲领 计算机网络特殊考点 计算机网络原理参考模型I 计算机网络原理参考模型II 目录 系列目录更新日志前言应用层(Application Layer)一、应用层概述二、客户/服务器方式和对等方式三、动态主机配置协议(DHCP, Dynamic Host Configuration Protocol)四、域…

微机原理与接口技术:重点内容|计算机系统|学习笔记

系列目录 前言 只将最重要的知识点考点列出来方便学习复习 目录 系列目录前言第1章 微型计算机概述第2章 16位和32位微处理机🌟16位微处理器 8086 第3章 Pentium 的指令系统常用指令 第4章 存储器、存储管理和高速缓存技术第5章 微型计算机和外设的数据传输第6章 串…

LeetCode-213. 打家劫舍 II【数组 动态规划】

LeetCode-213. 打家劫舍 II【数组 动态规划】 题目描述:解题思路一:分三种情况,一:不考虑头尾;二:考虑头不考虑尾;三:考虑尾不考虑头。解题思路二:优化空间解题思路三&am…

Android笔记-adb keycode大全

使用方法 用adb发送按键事件时,可以使用下面表中的枚举值或者直接使用数值,比如 adb shell input keyevent KEYCODE_HOME 或者 adb shell input keyevent 3 下面按三种排序方法列出所有按键的 keycode, 分别是: 按功能分 按枚…

LLM端侧部署系列 | 陈天奇MLC-LLM重磅升级:基于机器学习编译的通用LLM部署引擎

引言 简介 MLCEngine的聊天功能 OpenAI风格API 云端REST API Python API iOS SDK Android SDK WebLLM SDK 小结 结构化生成 支持各种平台 优化引擎性能 总结 引言 流星透疏水,走月逆行云。 小伙伴们好,我是《小窗幽记机器学习》的小编&am…

关于onlyoffice回调函数的问题

参考文档1:https://api.onlyoffice.com/zh/editors/callback 在官方文档中描述的十,文档存储服务的回调函数,必须要返回 {"error": 0}表示成功,否则将提示错误信息。 但是经过实测,我们只需要正常的返回2…

每日一题——Python实现PAT乙级1090 危险品装箱(举一反三+思想解读+逐步优化)4千字好文

一个认为一切根源都是“自己不够强”的INTJ 个人主页:用哲学编程-CSDN博客专栏:每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 题目链接:https://pintia.cn/problem-sets/994805260223102976/exam/problems/typ…

基于SSM的校园闲置物品交易平台

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于SSM的校园闲置物品交易平台,java项目…

Advanced RAG 09:『提示词压缩』技术综述

编者按: 如何最大限度地发挥 LLMs 的强大能力,同时还能控制其推理成本?这是当前业界研究的一个热点课题。 针对这一问题,本期精心选取了一篇关于"提示词压缩"(Prompt Compression)技术的综述文章。正如作者所说&#xf…