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

webpack打包一个文件,做了哪些事情

用webpack打包一个文件,在webpack内部做了哪些事情,用代码详细介绍一下

当你使用 Webpack 打包一个文件时,Webpack 内部会进行一系列操作来实现模块加载、代码转换、依赖分析、模块打包等功能。以下是使用 Webpack 打包一个简单 JavaScript 文件时,Webpack 内部可能会做的一些事情,以及对应的代码示例:

  1. 解析入口文件和依赖

    • Webpack 首先会解析指定的入口文件,分析文件中的依赖关系。

      // entry.js
      import dependency from './dependency.js';
      console.log('Hello from entry file');
      
  2. 依赖分析和模块解析

    • Webpack 会递归地分析入口文件和其依赖的模块,构建模块之间的依赖图。

      // dependency.js
      export default "Hello from dependency file";
      
  3. 加载器和转换

    • 如果有配置加载器(loader),Webpack 会根据配置对模块内容进行加载和转换。

      // webpack.config.js
      module.exports = {module: {rules: [{test: /\.js$/,use: 'babel-loader',exclude: /node_modules/}]}
      };
      
  4. 插件执行

    • Webpack 会触发各阶段生命周期事件,执行各插件中定义的逻辑。

      // webpack.config.js
      const MyPlugin = {apply(compiler) {compiler.hooks.run.tap('MyPlugin', compilation => {console.log('Webpack is running...');});}
      };
      module.exports = {plugins: [MyPlugin]
      };
      
  5. 输出文件

    • 最终,Webpack 会生成打包后的文件,包含打包后的代码和资源。

      // 输出的打包后文件
      // 包含经过转换和打包后的代码
      (function(modules) {// Webpack 实现的模块加载函数...
      })({"entry.js": function(module, exports, __webpack_require__) {var dependency = __webpack_require__("dependency.js");console.log('Hello from entry file');},"dependency.js": function(module, exports) {module.exports = "Hello from dependency file";}
      });
      

以上是使用 Webpack 打包一个简单 JavaScript 文件时,Webpack 内部可能会做的一些事情,并提供了相应的代码示例来说明。Webpack 的内部流程非常复杂,包含了更多的细节和处理过程,但以上代码示例可以帮助你初步了解 Webpack 内部的一些核心功能和流程。

用webpack打包一个文件,在webpack内部做了哪些事情,用代码详细介绍一下,其中着重讲解一下加载loader和plugins做了什么

当使用 Webpack 打包一个文件时,Webpack 内部会进行一系列操作,其中加载 loader 和执行 plugins 是重要的步骤。下面是一个详细的代码示例,展示 Webpack 在加载 loader 和执行 plugins 这两个阶段的具体操作:

假设有以下文件结构:

  • src/index.js:入口文件
  • src/utils.js:一个需要通过 loader 转换的模块

Webpack 配置文件 webpack.config.js

const path = require('path');
module.exports = {entry: './src/index.js',output: {path: path.resolve(__dirname, 'dist'),filename: 'bundle.js',},module: {rules: [{test: /\.js$/,use: 'babel-loader',exclude: /node_modules/,},],},plugins: [function MyPlugin() {this.apply = compiler => {compiler.hooks.beforeRun.tap('MyPlugin', () => {console.log('MyPlugin is running before the compilation starts...');});};},],
};
  1. 加载 loader(babel-loader)

    • 当 Webpack 遇到文件需要通过 loader 处理时,会根据配置中的规则来加载对应的 loader,对模块内容进行转换。
  2. 执行 plugins

    • 在 Webpack 执行过程中,会触发不同的生命周期钩子,插件可以通过这些钩子来执行各种操作。在下面的示例中,我们定义了一个简单的插件 MyPlugin,在 Webpack 的 beforeRun 钩子中打印一条消息。

下面是一个文件的示例内容:

src/index.js

import message from './utils.js';console.log(message);

src/utils.js

export default 'Hello, from utils!';

在运行 Webpack 打包时,Webpack 内部会按照以下顺序执行:

  • 加载入口文件 src/index.js,通过 loader 处理其中的依赖和代码;
  • 加载模块 src/utils.js,同样通过 loader 处理;
  • 执行插件 MyPlugin 中定义的操作,在编译开始之前打印消息;
  • 最终输出打包后的 bundle.js 文件到 dist 文件夹中。

通过以上示例,可以看到 Webpack 在加载 loader 和执行 plugins 这两个阶段的工作过程,以及如何通过配置文件来控制和定制这些步骤。加载 loader 可以实现对模块内容的转换,而执行 plugins 则可以在不同的编译阶段执行自定义逻辑,从而灵活扩展和控制 Webpack 的打包过程。

用代码详细介绍loader可以做什么

Loader 是 Webpack 中用于将非 JavaScript 模块转换为 JavaScript 模块的工具。它们允许你在 import 或 require 模块的时候预处理文件。以下是一个简单的示例,演示了 loader 可以做的一些事情:

假设有一个简单的文本文件 data.txt

Hello, this is some text from data.txt file.

现在我们使用一个自定义的 loader reverse-text-loader 来对 data.txt 中的文本内容进行翻转处理,并将翻转后的内容导入到 JavaScript 文件中。以下是示例代码:

  1. 创建 reverse-text-loader.js,用于定义 loader 的转换逻辑:

    // reverse-text-loader.js
    module.exports = function(source) {// 将文本内容进行反转处理return source.split('').reverse().join('');
    };
    
  2. 配置 Webpack 使用自定义的 loader:

    // webpack.config.js
    const path = require('path');module.exports = {entry: './src/index.js',output: {path: path.resolve(__dirname, 'dist'),filename: 'bundle.js',},module: {rules: [{test: /\.txt$/,use: path.resolve(__dirname, 'reverse-text-loader.js'),},],},
    };
    
  3. 创建一个入口文件 index.js,并导入 data.txt 文件:

    // index.js
    import reversedText from './data.txt';console.log(reversedText);
    
  4. 运行 Webpack 进行打包:

当运行 Webpack 时,它会使用我们定义的 reverse-text-loaderdata.txt 中的文本内容进行翻转处理,最后输出翻转后的内容到 bundle.js 文件中。在这个示例中,我们展示了 loader 可以做的一件事情:对导入的文件内容进行处理,并将处理后的内容转换为 JavaScript 模块。

通过以上示例,你可以看到 loader 的作用是非常灵活的,你可以根据需求自定义 loader 来处理不同类型的文件,实现各种转换和增强功能,从而扩展 Webpack 的打包能力。

loader有哪些类型,分别做什么,用代码解释

Webpack 中的 Loader 可以用于对不同类型的模块进行转换处理,从而让 Webpack 能够处理各种不同格式的文件。以下是一些常见的 Loader 类型以及它们的作用,同时提供一些代码示例来说明它们的用途:

  1. babel-loader:将 ES6+ 代码转换为 ES5 代码,使得现代 JavaScript 代码能够在不同环境中运行。
// webpack.config.js
module: {rules: [{test: /\.js$/,exclude: /node_modules/,use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env']}}}]
}
  1. style-loader 和 css-loader:用于处理 CSS 文件,将 CSS 转换为 JavaScript 模块,以便在浏览器中动态加载样式。
// webpack.config.js
module: {rules: [{test: /\.css$/,use: ['style-loader', 'css-loader']}]
}
  1. file-loader 和 url-loader:处理文件资源,如图片、字体等,将其转换为 URL 或 base64 格式。
// webpack.config.js
module: {rules: [{test: /\.(png|jpg|gif)$/,use: [{loader: 'file-loader',options: {name: '[name].[ext]',outputPath: 'images/'}}]}]
}
  1. url-loader:类似于 file-loader,但可以根据文件大小决定是返回 base64 格式还是 URL 格式。
// webpack.config.js
module: {rules: [{test: /\.(png|jpg|gif)$/,use: [{loader: 'url-loader',options: {limit: 8192 // 文件大小小于 8KB 时返回 base64 格式}}]}]
}
  1. sass-loader 和 less-loader:处理 SCSS 或 LESS 文件,将其转换为 CSS。
// webpack.config.js
module: {rules: [{test: /\.scss$/,use: ['style-loader', 'css-loader', 'sass-loader']}]
}

以上是一些常见的 Loader 类型及其作用,通过配置不同类型的 Loader,可以实现对各种不同格式的文件进行处理和转换,从而扩展 Webpack 的功能和应用范围。不同类型的 Loader 可以根据需要组合使用,以适应项目中不同类型的模块处理需求。

Webpack源码有哪些功能模块,都是做什么的,用代码详细介绍

Webpack 的源码包含多个重要功能模块,下面我将详细介绍每个模块的作用,并给出相应的代码示例来说明它们的功能:

  1. Parser(解析器):解析模块代码,分析模块之间的依赖关系。
const { Parser } = require('webpack');const parser = new Parser();// 解析模块代码
const ast = parser.parseModule('import example from "./example.js";');
  1. DependencyGraph(依赖图):构建模块之间的依赖关系图,确定加载顺序。
const { DependencyGraph } = require('webpack');const depGraph = new DependencyGraph();// 构建依赖关系图
const dependencies = depGraph.addModuleDependencies(module, dependencies);
  1. NormalModuleFactory(普通模块工厂):创建模块对象,并加载依赖模块。
const { NormalModuleFactory } = require('webpack');const moduleFactory = new NormalModuleFactory();// 创建模块对象
const module = moduleFactory.create(data, callback);
  1. Chunk(代码块):生成代码块,代表一组模块的集合。
const { Compilation } = require('webpack');const chunk = new Compilation().addChunk('main');// 将模块添加到代码块
chunk.addModule(module);
  1. Resolver(解析器):根据模块请求的路径,确定模块的绝对路径。
const { ResolverFactory } = require('webpack');const resolver = ResolverFactory.create();// 解析模块路径
const resolvedPath = resolver.resolve({}, '/path/to/module');
  1. Compiler(编译器):编译整个项目,将输入的模块转换为输出的 Chunk。
const { Compiler } = require('webpack');const compiler = new Compiler();// 运行编译器
compiler.run((err, stats) => {if (err) {console.error(err);} else {console.log(stats);}
});
  1. Plugins(插件系统):扩展 Webpack 的功能,执行自定义逻辑。
const MyPlugin = require('./my-plugin');compiler.apply(new MyPlugin());
  1. Loaders(加载器):对资源文件进行处理,将其转换为模块。
module.exports = {module: {rules: [{test: /\.js$/,use: ['babel-loader']}]}
};

以上是对 Webpack 源码中各功能模块的介绍,并给出了相应的代码示例来说明它们的作用和使用方式。这些功能模块共同构建了 Webpack 的打包流程,实现了模块的解析、依赖处理、代码生成等一系列重要功能。

用代码详细介绍plugin可以做什么,他们的原理是什么

在 Webpack 中,插件(plugins)是用来扩展和定制构建流程的工具,能够在整个构建过程中实现各种功能。插件可以监听到 Webpack 在不同阶段的生命周期事件,并在适当的时机执行自定义的逻辑,以达到特定的目的。以下是插件可以做的事情以及它们的原理:

  1. 修改输出文件内容或文件名:插件可以在生成最终输出文件时对内容进行修改,或者根据自定义规则生成不同的文件名。
// 一个简单的例子,通过修改 bundle 文件添加一行注释
class AddCommentPlugin {apply(compiler) {compiler.hooks.emit.tap('AddCommentPlugin', compilation => {for (const file of Object.keys(compilation.assets)) {compilation.assets[file] = new ConcatSource(`/* Add comment by AddCommentPlugin */\n`,compilation.assets[file]);}});}
}
  1. 优化构建结果:插件可以对输出文件进行优化,例如代码压缩、去除冗余代码、资源压缩等。
// 使用 UglifyJsPlugin 压缩 JavaScript 代码
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');module.exports = {// 其他配置plugins: [new UglifyJsPlugin()],
};
  1. 资源管理:通过插件可以对不同类型的静态资源进行处理和优化,例如文件复制、图片压缩、文件名修改等。
// 使用 CopyWebpackPlugin 复制静态资源
const CopyWebpackPlugin = require('copy-webpack-plugin');module.exports = {// 其他配置plugins: [new CopyWebpackPlugin({patterns: [{ from: 'assets', to: 'dist/assets' }],}),],
};
  1. 环境变量注入:插件可以向代码中注入全局变量或环境变量,以便在代码中使用。
// 使用 DefinePlugin 定义环境变量
const webpack = require('webpack');module.exports = {// 其他配置plugins: [new webpack.DefinePlugin({'process.env.NODE_ENV': JSON.stringify('production'),}),],
};

插件的核心原理:是基于 WebpackTapable 插件系统,插件可以利用各种生命周期钩子(hooks)来注册自定义逻辑代码,在构建过程中执行相应的操作。当 Webpack 在编译过程中触发对应的生命周期事件时,插件注册的回调函数就会被执行,从而实现对构建过程的干预和定制。

总的来说,Webpack 插件是一种扩展机制,通过监听Webpack的生命周期事件和钩子来实现对构建过程的干预和定制,使开发者能够更加灵活地定制构建流程、优化构建结果和满足项目需求。

三种注册插件的方法tapAsync、tapPromise和tap的区别是什么

在 Webpack 中,taptapAsynctapPromise 是注册插件的方法,它们的主要区别在于处理异步操作的能力和返回值类型:

  1. taptap 是最常用的注册插件的方法,用于同步执行逻辑。它注册的插件是一个普通的同步函数,无法处理异步操作。
compiler.hooks.someHook.tap('MyPlugin', (params) => {// 同步执行的插件逻辑
});
  1. tapAsynctapAsync 用于注册处理异步操作的插件。插件函数接受一个回调函数作为最后一个参数,用于通知 Webpack 异步操作的完成。
compiler.hooks.someHook.tapAsync('MyAsyncPlugin', (params, callback) => {// 异步执行的插件逻辑setTimeout(() => {callback();}, 1000);
});
  1. tapPromisetapPromise 用于注册返回 Promise 对象的插件,适用于处理异步操作且支持 Promise。插件函数返回一个 Promise 对象,Webpack 在 Promise 执行完成后继续执行下一个插件。
compiler.hooks.someHook.tapPromise('MyPromisePlugin', (params) => {return new Promise((resolve, reject) => {// 异步执行的插件逻辑setTimeout(() => {resolve();}, 1000);});
});

总结来说,tap 用于同步执行插件逻辑,tapAsync 用于处理异步操作,并通过回调函数通知 Webpack 完成,tapPromise 用于处理异步操作并返回 Promise 对象。根据插件逻辑的需要选择合适的方法进行注册插件,以确保插件可以正确地执行并与 Webpack 生态系统良好地集成。

const webpack = require('webpack');
const compiler = webpack({/* webpack配置 */
});
// 在编写插件时,通常会使用 tap 方法注册插件
// 还可以使用 tapAsync、tapPromise 等方法进行异步操作。
compiler.hooks.entryOption.tap('MyPlugin', () => {});
compiler.hooks.beforeCompile.tapAsync('MyPlugin', (params, callback) => {callback();
});
compiler.hooks.someHook.tapPromise('MyPromisePlugin', params => {return new Promise(resolve => {asyncOperation().then(() => {resolve();});});
});

什么时候用tapAsync,什么时候用tapPromise

Webpack 插件开发中,选择使用 tapAsync 还是 tapPromise 取决于插件逻辑是否需要进行异步操作,并且符合 Promise 的使用场景:

  1. 使用 tapAsync 的情况:
    • 当插件逻辑需要进行异步操作(如读取文件、发送网络请求等)且需要在操作完成后通知 Webpack 继续执行下一个插件时,应该选择 tapAsync
    • 如果插件的逻辑中包含异步回调函数,并且需要手动调用回调函数来通知 Webpack 完成插件执行时,应该使用 tapAsync
compiler.hooks.someHook.tapAsync('MyAsyncPlugin', (params, callback) => {// 异步操作asyncOperation(() => {// 操作完成后调用回调callback();});
});
  1. 使用 tapPromise 的情况:
    • 当插件逻辑中需要进行异步操作,并且适合使用 Promise 来管理异步流程时,应该选择 tapPromise
    • 如果插件逻辑中的异步操作返回 Promise 对象,可以直接返回 Promise 来告知 Webpack 异步操作的完成,此时应该使用 tapPromise
compiler.hooks.someHook.tapPromise('MyPromisePlugin', (params) => {return new Promise((resolve, reject) => {// 异步操作asyncOperation().then(() => {resolve();}).catch((error) => {reject(error);});});
});

总的来说,根据插件逻辑是否需要异步操作、是否符合 Promise 的使用场景来选择 tapAsynctapPromise。合理选择合适的注册方法可以使插件逻辑更清晰、更容易维护,并与 Webpack 插件系统良好地结合。

webpack 所有的生命周期钩子,详细讲解

Webpack 提供了多个生命周期钩子(Lifecycle Hooks)来让开发者介入打包流程,实现定制化的打包逻辑。以下是Webpack中常用的生命周期钩子及其作用:

  1. beforeRun:在 Webpack 构建启动之前执行的钩子,此时 Webpack 准备开始读取配置并启动构建过程。

  2. run:Webapck 构建启动后、创建编译对象之前执行的钩子,表示编译即将开始。

  3. watchRun:当使用 watch 模式下执行的钩子,表示每次重新编译前将会执行。

  4. normalModuleFactory:用于创建模块工厂时执行的钩子,可以用来改变模块创建方法。

  5. contextModuleFactory:用于创建上下文模块工厂时执行的钩子,可以用来改变上下文模块创建方法。

  6. beforeCompile:在编译开始之前执行的钩子,在这里可以执行一些操作以准备编译过程。

  7. compile:编译开始时执行的钩子,表示 Webpack 正在处理模块及其依赖。

  8. thisCompilation:在每次新的编译中,生成新的 Compilation 对象之前调用。

  9. compilation:在每次新的编译开始时创建新的 Compilation 对象时执行,表示一个新的编译已经开始。

  10. make:在开始创建块之前执行的钩子。

  11. afterCompile:在编译完成后执行的钩子,编译完成指 webpack 内部所有模块及其依赖已经编译完成。

  12. emit:在准备生成资源到输出目录之前执行的钩子。

  13. afterEmit:资源已经生成到输出目录后执行的钩子。

  14. done:Webpack 构建完成并且输出结果后执行的钩子。可以在这里执行一些清理工作或者输出构建信息。

这些生命周期钩子可以用于开发插件,通过监听不同的生命周期钩子并注册相应的回调函数来实现对Webpack构建过程的定制化操作。通过灵活运用这些生命周期钩子,开发者可以扩展Webpack的功能,满足项目特定的需求。

相关文章:

webpack打包一个文件,做了哪些事情

用webpack打包一个文件,在webpack内部做了哪些事情,用代码详细介绍一下 当你使用 Webpack 打包一个文件时,Webpack 内部会进行一系列操作来实现模块加载、代码转换、依赖分析、模块打包等功能。以下是使用 Webpack 打包一个简单 JavaScript …...

设计模式学习笔记 - 设计原则 - 6.KISS原则和YAGNI原则

前言 今天,将两个设计原则:KISS 原则和 YANGI 原则。其中,KISS 原则比较经典,耳熟能详,但 YANGI 你可能没怎么听过,不过它理解起来也不难。 理解这个两个原则的时候,经常会有一个共同的问题&a…...

【Vue3-vite】动态导入路由

route文件结构 router moduleindex.ts 路由定义 // 需要导入的路由如下: const routes [{path: /manage,name: manage,component: () > import(/views/home/index.vue),children: manageRoutes,}]index.ts实现从module中自动导入 // 动态导入 const routeFil…...

C++——string类

前言:哈喽小伙伴们,从这篇文章开始我们将进行若干个C中的重要的类容器的学习。本篇文章将讲解第一个类容器——string。 目录 一.什么是string类 二.string类常见接口 1.string类对象的常见构造 2.string类对象的容量操作 3. string类对象的访问及遍…...

进制转换md5绕过 [安洵杯 2019]easy_web1

打开题目 在查看url的时候得到了一串类似编码的东西,源码那里也是一堆base64,但是转换成图片就是网页上我们看见的那个表情包 ?imgTXpVek5UTTFNbVUzTURabE5qYz0&cmd 我们可以先试把前面的img那串解码了 解码的时候发现长度不够,那我们…...

.kat6.l6st6r勒索病毒的最新威胁:如何恢复您的数据?

导言: 在当今数字化时代,数据安全变得至关重要。然而,随着网络威胁不断增加,勒索病毒已成为企业和个人面临的严重威胁之一。其中,.kat6.l6st6r勒索病毒是最新的变种之一,它能够加密您的数据文件&#xff0…...

Day 6.有名信号量(信号灯)、网络的相关概念和发端

有名信号量 1.创建: semget int semget(key_t key, int nsems, int semflg); 功能:创建一组信号量 参数:key:IPC对像的名字 nsems:信号量的数量 semflg:IPC_CREAT 返回值:成功返回信号量ID…...

MySQL 常用优化方式

MySQL 常用优化方式 sql 书写顺序与执行顺序SQL设计优化使用索引避免索引失效分析慢查询合理使用子查询和临时表列相关使用 日常SQL优化场景limit语句隐式类型转换嵌套子查询混合排序查询重写 sql 书写顺序与执行顺序 (7) SELECT (8) DISTINCT <select_list> (1) FROM &…...

算法刷题day22:双指针

目录 引言概念一、牛的学术圈I二、最长连续不重复序列三、数组元素的目标和四、判断子序列五、日志统计六、统计子矩阵 引言 关于这个双指针算法&#xff0c;主要是用来处理枚举子区间的事&#xff0c;时间复杂度从 O ( N 2 ) O(N^2) O(N2) 降为 O ( N ) O(N) O(N) &#xf…...

山人求道篇:八、模型的偏差与交易认知

原文引用https://mp.weixin.qq.com/s/xvxatVseHK62U7aUXS1B4g “ CTA策略一波亏完全年,除了交易执行错误导致的以外,这类策略都是多因子策略,一般会用机器学习组合多因子得出一个信号来进行交易。规则型策略几乎不会出现一波做反亏完全年的情况。这是有以下几个原因的: 多…...

MySQL 元数据锁及问题排查(Metadata Locks MDL)

"元数据"是用来描述数据对象定义的&#xff0c;而元数据锁&#xff08;Metadata Lock MDL&#xff09;即是加在这些定义上。通常我们认为非锁定一致性读&#xff08;简单select&#xff09;是不加锁的&#xff0c;这个是基于表内数据层面&#xff0c;其依然会对表的元…...

JS中的函数

1、函数形参的默认值 JavaScript函数有一个特别的地方&#xff0c;无论在函数定义中声明了多少形参&#xff0c;都可以传入任意数量的参数&#xff0c;也可以在定义函数时添加针对参数数量的处理逻辑&#xff0c;当已定义的形参无对应的传入参数时&#xff0c;为其指定一个默认…...

微信小程序开发常用的布局

在微信小程序开发中&#xff0c;常用的布局主要包括以下几种&#xff1a; Flex 布局&#xff1a;Flex 布局是一种弹性盒子布局&#xff0c;通过设置容器的属性来实现灵活的布局方式。它可以在水平或垂直方向上对子元素进行对齐、排列和分布。Flex 布局非常适用于创建响应式布局…...

Effective C++ 学习笔记 条款10 令operator=返回一个reference to *this

关于赋值&#xff0c;有趣的是你可以把它们写成连锁形式&#xff1a; int x, y, z; x y z 15; // 赋值连锁形式同样有趣的是&#xff0c;赋值采用右结合律&#xff0c;所以上述连锁赋值被解析为&#xff1a; x (y (z 15));这里15先被赋值给z&#xff0c;然后其结果&…...

算法简单试题

一、选择题 01.一个算法应该是( B ). A.程序 B.问题求解步骤的描述 C.要满足五个基本特性 D.A和C 02&#xff0e;某算法的时间复杂度为O(n)&#xff0c;则表示该…...

CSS 自测题 -- 用 flex 布局绘制骰子(一、二、三【含斜三点】、四、五、六点)

一点 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>css flex布局-画骰子</title><sty…...

蓝桥集训之牛的学术圈 I

蓝桥集训之牛的学术圈 I 核心思想&#xff1a;二分 确定指数x后 判断当前c[i]是否>x(满足条件) 并记录次数同时记录 1后满足条件的个数最后取bns和m的最小值 为满足条件的元素个数ansbns为当前指数x下 满足条件的元素个数 #include <iostream>#include <cstring…...

软件设计师软考题目解析21 --每日五题

想说的话&#xff1a;要准备软考了。0.0&#xff0c;其实我是不想考的&#xff0c;但是吧&#xff0c;由于本人已经学完所有知识了&#xff0c;只是被学校的课程给锁在那里了&#xff0c;不然早找工作去了。寻思着反正也无聊&#xff0c;就考个证玩玩。 本人github地址&#xf…...

python读写json文件详解

在Python中&#xff0c;可以使用json模块来读写JSON格式的文件。下面是一个详细的示例&#xff0c;演示了如何读写JSON文件&#xff1a; import json# 写入JSON文件 data {"name": "John","age": 30,"city": "New York" }…...

#include<ros/ros.h>头文件报错

快捷键 ctrl shift B 调用编译&#xff0c;选择:catkin_make:build&#xff09;(要先在vscode上添加扩展&#xff1a;ros) 可以点击配置设置为默认&#xff0c;修改.vscode/tasks.json 文件 修改.vscode/tasks.json 文件&#xff0c;否则ros.h头文件会报错 内容修改为以下内…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...