webpack进阶(一)

embedded/2024/11/19 7:52:08/

一、起步

1、基本安装

首先我们创建一个目录,初始化 npm,然后 在本地安装 webpack,接着安装 webpack-cli(此工具用于在命令行中运行 webpack):

mkdir webpack-demo
cd webpack-demo
npm init -y
npm install webpack webpack-cli --save-dev

现在,我们将创建以下目录结构、文件和内容:

project

  webpack-demo|- package.json
+ |- index.html
+ |- /src
+   |- index.js

src/index.js

function component() {const element = document.createElement('div');// https://www.lodashjs.com/// lodash(目前通过一个 script 引入)对于执行这一行是必需的element.innerHTML = _.join(['Hello', 'webpack'], ' ');return element;
}document.body.appendChild(component());

index.html

<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>起步</title><script src="https://unpkg.com/lodash@4.17.20"></script></head><body><script src="./src/index.js"></script></body>
</html>

我们还需要调整 package.json 文件,以便确保我们安装包是 private(私有的),并且移除 main 入口。这可以防止意外发布你的代码。

package.json

 {"name": "webpack-demo","version": "1.0.0","description": "",
-  "main": "index.js",
+  "private": true,"scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"keywords": [],"author": "","license": "ISC","devDependencies": {"webpack": "^5.4.0","webpack-cli": "^4.2.0"}}

启动项目

npx http-server

在此示例中,<script> 标签之间存在隐式依赖关系。在 index.js 文件执行之前,还需要在页面中先引入 lodash。这是因为 index.js 并未显式声明它需要 lodash,只是假定推测已经存在一个全局变量 _

使用这种方式去管理 JavaScript 项目会有一些问题:

  • 无法直接体现,脚本的执行依赖于外部库。
  • 如果依赖不存在,或者引入顺序错误,应用程序将无法正常运行。
  • 如果依赖被引入但是并没有使用,浏览器将被迫下载无用代码。

让我们使用 webpack 来管理这些脚本。

2、创建一个bundle

首先,我们稍微调整下目录结构,创建分发代码(./dist)文件夹用于存放分发代码,源代码(./src)文件夹仍存放源代码。

project

  webpack-demo|- package.json
+ |- /dist
+   |- index.html
- |- index.html|- /src|- index.js

要在 index.js 中打包 lodash 依赖,我们需要在本地安装 library:

npm install --save lodash

src/index.js

+import _ from 'lodash';
+function component() {const element = document.createElement('div');-  // lodash(目前通过一个 script 引入)对于执行这一行是必需的
+  // lodash,现在通过一个 script 引入element.innerHTML = _.join(['Hello', 'webpack'], ' ');return element;}document.body.appendChild(component());

dist/index.html

 <!DOCTYPE html><html><head><meta charset="utf-8" /><title>起步</title>
-    <script src="https://unpkg.com/lodash@4.17.20"></script></head><body>
-    <script src="./src/index.js"></script>
+    <script src="main.js"></script></body></html>

开始打包

$ npx webpack

3、模块

ES2015 中的 importexport 语句已经被标准化。虽然大多数浏览器还无法支持它们,但是 webpack 却能够提供开箱即用般的支持。

事实上,webpack 在幕后会将代码“转译”,以便旧版本浏览器可以执行。如果你检查 dist/main.js,你可以看到 webpack 具体如何实现,这是独创精巧的设计!除了 importexportwebpack 还能够很好地支持多种其他模块语法,更多信息请查看 模块 API。

注意,webpack 不会更改代码中除 importexport 语句以外的部分。如果你在使用其它 ES2015 特性,请确保你在 webpack loader 系统 中使用了 Babel

请查看编译后的代码。

4、使用一个配置文件

project

  webpack-demo|- package.json
+ |- webpack.config.js|- /dist|- index.html|- /src|- index.js

webpack.config.js

javascript">const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'main.js',path: path.resolve(__dirname, 'dist'),},
};

现在,让我们通过新的配置文件再次执行构建:

5、npm scripts

package.json

 {"name": "webpack-demo","version": "1.0.0","description": "","private": true,"scripts": {
-    "test": "echo \"Error: no test specified\" && exit 1"
+    "test": "echo \"Error: no test specified\" && exit 1",
+    "build": "webpack"},"keywords": [],"author": "","license": "ISC","devDependencies": {"webpack": "^5.4.0","webpack-cli": "^4.2.0"},"dependencies": {"lodash": "^4.17.20"}}

现在运行以下命令:

$ npm run build

二、管理资源

1、设置

在开始之前,让我们对项目做一个小的修改:

dist/index.html

 <!DOCTYPE html><html><head><meta charset="utf-8" />
-    <title>起步</title>
+    <title>管理资源</title></head><body>
-    <script src="main.js"></script>
+    <script src="bundle.js"></script></body></html>

webpack.config.js

 const path = require('path');module.exports = {entry: './src/index.js',output: {
-    filename: 'main.js',
+    filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},};

2、加载 CSS

为了在 JavaScript 模块中 import 一个 CSS 文件,你需要安装 style-loader 和 css-loader,并在 module 配置 中添加这些 loader:

npm install --save-dev style-loader css-loader

webpack.config.js

 const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},
+  module: {
+    rules: [
+      {
+        test: /\.css$/i,
+        use: ['style-loader', 'css-loader'],
+      },
+    ],
+  },};

我们尝试一下,通过在项目中添加一个新的 style.css 文件,并将其 import 到我们的 index.js 中:

project

  webpack-demo|- package.json|- webpack.config.js|- /dist|- bundle.js|- index.html|- /src
+   |- style.css|- index.js|- /node_modules

src/style.css

.hello {color: red;
}

src/index.js

 import _ from 'lodash';
+import './style.css';function component() {const element = document.createElement('div');// Lodash, now imported by this scriptelement.innerHTML = _.join(['Hello', 'webpack'], ' ');
+  element.classList.add('hello');return element;}document.body.appendChild(component());

现在运行 build 命令:

$ npm run build

3、加载 images 图像

假如,现在我们正在下载 CSS,但是像 background 和 icon 这样的图像,要如何处理呢?在 webpack 5 中,可以使用内置的 Asset Modules,我们可以轻松地将这些内容混入我们的系统中:

webpack.config.js

 const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},module: {rules: [{test: /\.css$/i,use: ['style-loader', 'css-loader'],},
+      {
+        test: /\.(png|svg|jpg|jpeg|gif)$/i,
+        type: 'asset/resource',
+      },],},};

我们向项目添加一个图像,然后看它是如何工作的,你可以使用任何你喜欢的图像:

project

  webpack-demo|- package.json|- webpack.config.js|- /dist|- bundle.js|- index.html|- /src
+   |- icon.png|- style.css|- index.js|- /node_modules

src/index.js

 import _ from 'lodash';import './style.css';
+import Icon from './icon.png';function component() {const element = document.createElement('div');// Lodash, now imported by this scriptelement.innerHTML = _.join(['Hello', 'webpack'], ' ');element.classList.add('hello');+  // 将图像添加到我们已经存在的 div 中。
+  const myIcon = new Image();
+  myIcon.src = Icon;
+
+  element.appendChild(myIcon);
+return element;}document.body.appendChild(component());

src/style.css

 .hello {color: red;
+  background: url('./icon.png');}

重新构建并再次打开 index.html 文件:

$ npm run build

4、加载 fonts 字体

那么,像字体这样的其他资源如何处理呢?使用 Asset Modules 可以接收并加载任何文件,然后将其输出到构建目录。这就是说,我们可以将它们用于任何类型的文件,也包括字体。让我们更新 webpack.config.js 来处理字体文件:

webpack.config.js

 const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},module: {rules: [{test: /\.css$/i,use: ['style-loader', 'css-loader'],},{test: /\.(png|svg|jpg|jpeg|gif)$/i,type: 'asset/resource',},
+      {
+        test: /\.(woff|woff2|eot|ttf|otf)$/i,
+        type: 'asset/resource',
+      },],},};

在项目中添加一些字体文件:

project

  webpack-demo|- package.json|- webpack.config.js|- /dist|- bundle.js|- index.html|- /src
+   |- my-font.woff
+   |- my-font.woff2|- icon.png|- style.css|- index.js|- /node_modules

配置好 loader 并将字体文件放在合适的位置后,你可以通过一个 @font-face 声明将其混合。本地的 url(...) 指令会被 webpack 获取处理,就像它处理图片一样:

src/style.css

+@font-face {
+  font-family: 'MyFont';
+  src: url('./my-font.woff2') format('woff2'),
+    url('./my-font.woff') format('woff');
+  font-weight: 600;
+  font-style: normal;
+}
+.hello {color: red;
+  font-family: 'MyFont';background: url('./icon.png');}

现在,让我们重新构建,然后看下 webpack 是否处理了我们的字体:

$ npm run build

三、管理输出

到目前为止,我们都是在 index.html 文件中手动引入所有资源,然而随着应用程序增长,并且一旦开始 在文件名中使用 hash 并输出 多个 bundle,如果继续手动管理 index.html 文件,就会变得困难起来。然而,通过一些插件可以使这个过程更容易管控。

1、预先准备

首先,调整一下我们的项目:

project

  webpack-demo|- package.json|- webpack.config.js|- /dist|- /src|- index.js
+   |- print.js|- /node_modules

我们在 src/print.js 文件中添加一些逻辑:

src/print.js

export default function printMe() {console.log('I get called from print.js!');
}

并且在 src/index.js 文件中使用这个函数:

src/index.js

 import _ from 'lodash';
+import printMe from './print.js';function component() {const element = document.createElement('div');
+  const btn = document.createElement('button');element.innerHTML = _.join(['Hello', 'webpack'], ' ');+  btn.innerHTML = 'Click me and check the console!';
+  btn.onclick = printMe;
+
+  element.appendChild(btn);
+return element;}document.body.appendChild(component());

还要更新 dist/index.html 文件,来为 webpack 分离入口做好准备:

dist/index.html

 <!DOCTYPE html><html><head><meta charset="utf-8" />
-    <title>管理资源</title>
+    <title>管理输出</title>
+    <script src="./print.bundle.js"></script></head><body>
-    <script src="bundle.js"></script>
+    <script src="./index.bundle.js"></script></body></html>

现在调整配置。我们将在 entry 添加 src/print.js 作为新的入口起点(print),然后修改 output,以便根据入口起点定义的名称,动态地产生 bundle 名称:

webpack.config.js

 const path = require('path');module.exports = {
-  entry: './src/index.js',
+  entry: {
+    index: './src/index.js',
+    print: './src/print.js',
+  },output: {
-    filename: 'bundle.js',
+    filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),},};

执行 npm run build

我们可以看到,webpack 生成 print.bundle.jsindex.bundle.js 文件,这也和我们在 index.html 文件中指定的文件名称相对应。如果你在浏览器中打开 index.html,就可以看到在点击按钮时会发生什么。

但是,如果我们更改了我们的一个入口起点的名称,甚至添加了一个新的入口,会发生什么?会在构建时重新命名生成的 bundle,但是我们的 index.html 文件仍然引用旧的名称。让我们用 HtmlWebpackPlugin 来解决这个问题。

2、设置 HtmlWebpackPlugin

首先安装插件,并且调整 webpack.config.js 文件:

npm install --save-dev html-webpack-plugin

webpack.config.js

 const path = require('path');
+const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {entry: {index: './src/index.js',print: './src/print.js',},
+  plugins: [
+    new HtmlWebpackPlugin({
+      title: '管理输出',
+    }),
+  ],output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),},};

在我们构建之前,你应该了解,虽然在 dist/ 文件夹我们已经有了 index.html 这个文件,然而 HtmlWebpackPlugin 还是会默认生成它自己的 index.html 文件。也就是说,它会用新生成的 index.html 文件,替换我们的原有文件。

如果在代码编辑器中打开 index.html,你会看到 HtmlWebpackPlugin 创建了一个全新的文件,所有的 bundle 会自动添加到 html 中。

3、清理 /dist 文件夹

你可能已经注意到,由于遗留了之前的指南和代码示例,我们的 /dist 文件夹显得相当杂乱。webpack 将生成文件并放置在 /dist 文件夹中,但是它不会追踪哪些文件是实际在项目中用到的。

通常比较推荐的做法是,在每次构建前清理 /dist 文件夹,这样只会生成用到的文件。让我们实现这个需求。

clean-webpack-plugin 是一个流行的清理插件,安装和配置它。

npm install --save-dev clean-webpack-plugin

webpack.config.js

 const path = require('path');const HtmlWebpackPlugin = require('html-webpack-plugin');
+const { CleanWebpackPlugin } = require('clean-webpack-plugin');module.exports = {entry: {index: './src/index.js',print: './src/print.js',},plugins: [
+    new CleanWebpackPlugin(),new HtmlWebpackPlugin({title: 'Output Management',}),],output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),},};

现在,执行 npm run build,检查 /dist 文件夹。如果一切顺利,现在只会看到构建后生成的文件,而没有旧文件!

4、manifest

你可能会很感兴趣,webpackwebpack 插件似乎“知道”应该生成哪些文件。答案是,webpack 通过 manifest,可以追踪所有模块到输出 bundle 之间的映射。如果你想要知道如何以其他方式来控制 webpack 输出,了解 manifest 是个好的开始。

通过 WebpackManifestPlugin 插件,可以将 manifest 数据提取为一个容易使用的 json 文件。

首先安装 webpack-manifest-plugin:

npm install webpack-manifest-plugin --save-dev

webpack.config.js

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
+const { WebpackManifestPlugin } = require('webpack-manifest-plugin')module.exports = {mode: 'development',entry: {index: './src/index.js',print: './src/print.js',},plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin({title: '管理输出',}),
+   new WebpackManifestPlugin()],output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),}
};

现在,执行 npm run build,会发现 dist/manifest.json文件,文件内容如下:

{"index.js": "autoindex.bundle.js","print.js": "autoprint.bundle.js","index.html": "autoindex.html"
}

四、开发环境

如果你一直跟随之前的指南,应该对一些 webpack 基础知识有着很扎实的理解。在我们继续之前,先来看看如何设置一个开发环境,使我们的开发体验变得更轻松一些。

在开始前,我们先将 mode 设置为 'development',并将 title 设置为 'Development'

webpack.config.js

 const path = require('path');const HtmlWebpackPlugin = require('html-webpack-plugin');const { CleanWebpackPlugin } = require('clean-webpack-plugin');module.exports = {
+  mode: 'development',entry: {index: './src/index.js',print: './src/print.js',},plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin({
-      title: 'Output Management',
+      title: 'Development',}),],output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),},};

1、使用 source-map

webpack 打包源代码时,可能会很难追踪到 error(错误) 和 warning(警告) 在源代码中的原始位置。例如,如果将三个源文件(a.js, b.jsc.js)打包到一个 bundle(bundle.js)中,而其中一个源文件包含一个错误,那么堆栈跟踪就会直接指向到 bundle.js。你可能需要准确地知道错误来自于哪个源文件,所以这种提示这通常不会提供太多帮助。

为了更容易地追踪 error 和 warning,JavaScript 提供了 source maps 功能,可以将编译后的代码映射回原始源代码。如果一个错误来自于 b.js,source map 就会明确的告诉你。

(1) devtool 配置说明表

devtoolperformanceproductionqualitycomment
(none)build: fastest rebuild: fastestyesbundleRecommended choice for production builds with maximum performance.
evalbuild: fast rebuild: fastestnogeneratedRecommended choice for development builds with maximum performance.
eval-cheap-source-mapbuild: ok rebuild: fastnotransformedTradeoff choice for development builds.
eval-cheap-module-source-mapbuild: slow rebuild: fastnooriginal linesTradeoff choice for development builds.
eval-source-mapbuild: slowest rebuild: oknooriginalRecommended choice for development builds with high quality SourceMaps.
cheap-source-mapbuild: ok rebuild: slownotransformed
cheap-module-source-mapbuild: slow rebuild: slownooriginal lines
source-mapbuild: slowest rebuild: slowestyesoriginalRecommended choice for production builds with high quality SourceMaps.
inline-cheap-source-mapbuild: ok rebuild: slownotransformed
inline-cheap-module-source-mapbuild: slow rebuild: slownooriginal lines
inline-source-mapbuild: slowest rebuild: slowestnooriginalPossible choice when publishing a single file
eval-nosources-cheap-source-mapbuild: ok rebuild: fastnotransformedsource code not included
eval-nosources-cheap-module-source-mapbuild: slow rebuild: fastnooriginal linessource code not included
eval-nosources-source-mapbuild: slowest rebuild: oknooriginalsource code not included
inline-nosources-cheap-source-mapbuild: ok rebuild: slownotransformedsource code not included
inline-nosources-cheap-module-source-mapbuild: slow rebuild: slownooriginal linessource code not included
inline-nosources-source-mapbuild: slowest rebuild: slowestnooriginalsource code not included
nosources-cheap-source-mapbuild: ok rebuild: slownotransformedsource code not included
nosources-cheap-module-source-mapbuild: slow rebuild: slownooriginal linessource code not included
nosources-source-mapbuild: slowest rebuild: slowestyesoriginalsource code not included
hidden-nosources-cheap-source-mapbuild: ok rebuild: slownotransformedno reference, source code not included
hidden-nosources-cheap-module-source-mapbuild: slow rebuild: slownooriginal linesno reference, source code not included
hidden-nosources-source-mapbuild: slowest rebuild: slowestyesoriginalno reference, source code not included
hidden-cheap-source-mapbuild: ok rebuild: slownotransformedno reference
hidden-cheap-module-source-mapbuild: slow rebuild: slownooriginal linesno reference
hidden-source-mapbuild: slowest rebuild: slowestyesoriginalno reference. Possible choice when using SourceMap only for error reporting purposes.
  • 开发环境推荐配置

    以下选项非常适合开发环境:

    eval - 每个模块都使用 eval() 执行,并且都有 //@ sourceURL。此选项会非常快地构建。主要缺点是,由于会映射到转换后的代码,而不是映射到原始代码(没有从 loader 中获取 source map),所以不能正确的显示行数。

    eval-source-map - 每个模块使用 eval() 执行,并且 source map 转换为 DataUrl 后添加到 eval() 中。初始化 source map 时比较慢,但是会在重新构建时提供比较快的速度,并且生成实际的文件。行数能够正确映射,因为会映射到原始代码中。它会生成用于开发环境的最佳品质的 source map。

    eval-cheap-source-map - 类似 eval-source-map,每个模块使用 eval() 执行。这是 “cheap(低开销)” 的 source map,因为它没有生成列映射(column mapping),只是映射行数。它会忽略源自 loader 的 source map,并且仅显示转译后的代码,就像 eval devtool。

    eval-cheap-module-source-map - 类似 eval-cheap-source-map,并且,在这种情况下,源自 loader 的 source map 会得到更好的处理结果。然而,loader source map 会被简化为每行一个映射(mapping)。

  • 生产环境推荐配置

    这些选项通常用于生产环境中:

    (none)(省略 devtool 选项) - 不生成 source map。这是一个不错的选择。

    source-map - 整个 source map 作为一个单独的文件生成。它为 bundle 添加了一个引用注释,以便开发工具知道在哪里可以找到它。

    hidden-source-map - 与 source-map 相同,但不会为 bundle 添加引用注释。如果你只想 source map 映射那些源自错误报告的错误堆栈跟踪信息,但不想为浏览器开发工具暴露你的 source map,这个选项会很有用。

    nosources-source-map - 创建的 source map 不包含 sourcesContent(源代码内容)。它可以用来映射客户端上的堆栈跟踪,而无须暴露所有的源代码。你可以将 source map 文件部署到 web 服务器。

(2) 配置示例

webpack 仓库中包含一个 显示所有 devtool 变体效果的示例。这些例子或许会有助于你理解这些差异之处。

example.coffee

# Taken from http://coffeescript.org/# Objects:
math =root:   Math.sqrtsquare: squarecube:   (x) -> x * square x# Splats:
race = (winner, runners...) ->print winner, runners

webpack.config.js

var path = require("path");module.exports = ["eval","eval-cheap-source-map","eval-cheap-module-source-map","eval-source-map","cheap-source-map","cheap-module-source-map","inline-cheap-source-map","inline-cheap-module-source-map","source-map","inline-source-map","hidden-source-map","nosources-source-map"
].map(devtool => ({mode: "development",entry: {bundle: "coffee-loader!./example.coffee"},output: {path: path.join(__dirname, "dist"),filename: `./[name]-${devtool}.js`},devtool,optimization: {runtimeChunk: true}
}));

Generated source-maps

  • source-map.js and source-map.js.map
(self["webpackChunk"] = self["webpackChunk"] || []).push([[0],[
/* 0 */
/*!*********************************************************************!*\!*** ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee ***!\*********************************************************************/
/*! unknown exports (runtime-defined) */
/*! runtime requirements:  */
/***/ (() => {// Taken from http://coffeescript.org/// Objects:
var math, race;math = {root: Math.sqrt,square: square,cube: function(x) {return x * square(x);}
};// Splats:
race = function(winner, ...runners) {return print(winner, runners);
};/***/ })
],
0,[[0,1]]]);
//# sourceMappingURL=bundle-source-map.js.map
{"version":3,"sources":["webpack:///./example.coffee"],"names":[],"mappings":";;;;;;;;;AAEU;;;AAAA;;AACV,OACE;EAAA,MAAQ,IAAI,CAAC,IAAb;EACA,QAAQ,MADR;EAEA,MAAQ,SAAC,CAAD;WAAO,IAAI,OAAO,CAAP;EAAX;AAFR,EAFQ;;;AAOV,OAAO,SAAC,MAAD,KAAS,OAAT;SACL,MAAM,MAAN,EAAc,OAAd;AADK","file":"./bundle-source-map.js","sourcesContent":["# Taken from http://coffeescript.org/\n\n# Objects:\nmath =\n  root:   Math.sqrt\n  square: square\n  cube:   (x) -> x * square x\n\n# Splats:\nrace = (winner, runners...) ->\n  print winner, runners\n"],"sourceRoot":""}
  • hidden-source-map.js and hidden-source-map.js.map
(self["webpackChunk"] = self["webpackChunk"] || []).push([[0],[
/* 0 */
/*!*********************************************************************!*\!*** ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee ***!\*********************************************************************/
/*! unknown exports (runtime-defined) */
/*! runtime requirements:  */
/***/ (() => {// Taken from http://coffeescript.org/// Objects:
var math, race;math = {root: Math.sqrt,square: square,cube: function(x) {return x * square(x);}
};// Splats:
race = function(winner, ...runners) {return print(winner, runners);
};/***/ })
],
0,[[0,1]]]);
{"version":3,"sources":["webpack:///./example.coffee"],"names":[],"mappings":";;;;;;;;;AAEU;;;AAAA;;AACV,OACE;EAAA,MAAQ,IAAI,CAAC,IAAb;EACA,QAAQ,MADR;EAEA,MAAQ,SAAC,CAAD;WAAO,IAAI,OAAO,CAAP;EAAX;AAFR,EAFQ;;;AAOV,OAAO,SAAC,MAAD,KAAS,OAAT;SACL,MAAM,MAAN,EAAc,OAAd;AADK","file":"./bundle-hidden-source-map.js","sourcesContent":["# Taken from http://coffeescript.org/\n\n# Objects:\nmath =\n  root:   Math.sqrt\n  square: square\n  cube:   (x) -> x * square x\n\n# Splats:\nrace = (winner, runners...) ->\n  print winner, runners\n"],"sourceRoot":""}
  • inline-source-map.js
(self["webpackChunk"] = self["webpackChunk"] || []).push([[0],[
/* 0 */
/*!*********************************************************************!*\!*** ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee ***!\*********************************************************************/
/*! unknown exports (runtime-defined) */
/*! runtime requirements:  */
/***/ (() => {// Taken from http://coffeescript.org/// Objects:
var math, race;math = {root: Math.sqrt,square: square,cube: function(x) {return x * square(x);}
};// Splats:
race = function(winner, ...runners) {return print(winner, runners);
};/***/ })
],
0,[[0,1]]]);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9leGFtcGxlLmNvZmZlZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFFVTs7O0FBQUE7O0FBQ1YsT0FDRTtFQUFBLE1BQVEsSUFBSSxDQUFDLElBQWI7RUFDQSxRQUFRLE1BRFI7RUFFQSxNQUFRLFNBQUMsQ0FBRDtXQUFPLElBQUksT0FBTyxDQUFQO0VBQVg7QUFGUixFQUZROzs7QUFPVixPQUFPLFNBQUMsTUFBRCxLQUFTLE9BQVQ7U0FDTCxNQUFNLE1BQU4sRUFBYyxPQUFkO0FBREsiLCJmaWxlIjoiLi9idW5kbGUtaW5saW5lLXNvdXJjZS1tYXAuanMiLCJzb3VyY2VzQ29udGVudCI6WyIjIFRha2VuIGZyb20gaHR0cDovL2NvZmZlZXNjcmlwdC5vcmcvXG5cbiMgT2JqZWN0czpcbm1hdGggPVxuICByb290OiAgIE1hdGguc3FydFxuICBzcXVhcmU6IHNxdWFyZVxuICBjdWJlOiAgICh4KSAtPiB4ICogc3F1YXJlIHhcblxuIyBTcGxhdHM6XG5yYWNlID0gKHdpbm5lciwgcnVubmVycy4uLikgLT5cbiAgcHJpbnQgd2lubmVyLCBydW5uZXJzXG4iXSwic291cmNlUm9vdCI6IiJ9
  • nosources-source-map.js.map
{"version":3,"sources":["webpack:///./example.coffee"],"names":[],"mappings":";;;;;;;;;AAEU;;;AAAA;;AACV,OACE;EAAA,MAAQ,IAAI,CAAC,IAAb;EACA,QAAQ,MADR;EAEA,MAAQ,SAAC,CAAD;WAAO,IAAI,OAAO,CAAP;EAAX;AAFR,EAFQ;;;AAOV,OAAO,SAAC,MAAD,KAAS,OAAT;SACL,MAAM,MAAN,EAAc,OAAd;AADK","file":"./bundle-nosources-source-map.js","sourceRoot":""}
  • eval-source-map.js
/** ATTENTION: An "eval-source-map" devtool has been used.* This devtool is neither made for production nor for readable output files.* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)* or disable the default devtool with "devtool: false".* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).*/
(self["webpackChunk"] = self["webpackChunk"] || []).push([[0],[
/* 0 */
/*!*********************************************************************!*\!*** ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee ***!\*********************************************************************/
/*! unknown exports (runtime-defined) */
/*! runtime requirements:  */
/***/ (() => {eval("// Taken from http://coffeescript.org/\n\n// Objects:\nvar math, race;\n\nmath = {\n  root: Math.sqrt,\n  square: square,\n  cube: function(x) {\n    return x * square(x);\n  }\n};\n\n// Splats:\nrace = function(winner, ...runners) {\n  return print(winner, runners);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vZXhhbXBsZS5jb2ZmZWU/MjQxNiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFVTs7O0FBQUEsSUFBQSxJQUFBLEVBQUE7O0FBQ1YsSUFBQSxHQUNFO0VBQUEsSUFBQSxFQUFRLElBQUksQ0FBQyxJQUFiO0VBQ0EsTUFBQSxFQUFRLE1BRFI7RUFFQSxJQUFBLEVBQVEsUUFBQSxDQUFDLENBQUQsQ0FBQTtXQUFPLENBQUEsR0FBSSxNQUFBLENBQU8sQ0FBUDtFQUFYO0FBRlIsRUFGUTs7O0FBT1YsSUFBQSxHQUFPLFFBQUEsQ0FBQyxNQUFELEVBQUEsR0FBUyxPQUFULENBQUE7U0FDTCxLQUFBLENBQU0sTUFBTixFQUFjLE9BQWQ7QUFESyIsInNvdXJjZXNDb250ZW50IjpbIiMgVGFrZW4gZnJvbSBodHRwOi8vY29mZmVlc2NyaXB0Lm9yZy9cblxuIyBPYmplY3RzOlxubWF0aCA9XG4gIHJvb3Q6ICAgTWF0aC5zcXJ0XG4gIHNxdWFyZTogc3F1YXJlXG4gIGN1YmU6ICAgKHgpIC0+IHggKiBzcXVhcmUgeFxuXG4jIFNwbGF0czpcbnJhY2UgPSAod2lubmVyLCBydW5uZXJzLi4uKSAtPlxuICBwcmludCB3aW5uZXIsIHJ1bm5lcnNcbiJdLCJmaWxlIjoiMC5qcyJ9\n//# sourceURL=webpack-internal:///0\n");/***/ })
],
0,[[0,1]]]);
  • eval.js
/** ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").* This devtool is neither made for production nor for readable output files.* It uses "eval()" calls to create a separate source file in the browser devtools.* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)* or disable the default devtool with "devtool: false".* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).*/
(self["webpackChunk"] = self["webpackChunk"] || []).push([[0],[
/* 0 */
/*!*********************************************************************!*\!*** ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee ***!\*********************************************************************/
/*! unknown exports (runtime-defined) */
/*! runtime requirements:  */
/***/ (() => {eval("// Taken from http://coffeescript.org/\n\n// Objects:\nvar math, race;\n\nmath = {\n  root: Math.sqrt,\n  square: square,\n  cube: function(x) {\n    return x * square(x);\n  }\n};\n\n// Splats:\nrace = function(winner, ...runners) {\n  return print(winner, runners);\n};\n\n\n//# sourceURL=webpack:///./example.coffee?../../node_modules/coffee-loader/dist/cjs.js");/***/ })
],
0,[[0,1]]]);
  • eval-cheap-source-map.js
/** ATTENTION: An "eval-source-map" devtool has been used.* This devtool is neither made for production nor for readable output files.* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)* or disable the default devtool with "devtool: false".* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).*/
(self["webpackChunk"] = self["webpackChunk"] || []).push([[0],[
/* 0 */
/*!*********************************************************************!*\!*** ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee ***!\*********************************************************************/
/*! unknown exports (runtime-defined) */
/*! runtime requirements:  */
/***/ (() => {eval("// Taken from http://coffeescript.org/\n\n// Objects:\nvar math, race;\n\nmath = {\n  root: Math.sqrt,\n  square: square,\n  cube: function(x) {\n    return x * square(x);\n  }\n};\n\n// Splats:\nrace = function(winner, ...runners) {\n  return print(winner, runners);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2V4YW1wbGUuY29mZmVlP2VlNTgiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gVGFrZW4gZnJvbSBodHRwOi8vY29mZmVlc2NyaXB0Lm9yZy9cblxuLy8gT2JqZWN0czpcbnZhciBtYXRoLCByYWNlO1xuXG5tYXRoID0ge1xuICByb290OiBNYXRoLnNxcnQsXG4gIHNxdWFyZTogc3F1YXJlLFxuICBjdWJlOiBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIHggKiBzcXVhcmUoeCk7XG4gIH1cbn07XG5cbi8vIFNwbGF0czpcbnJhY2UgPSBmdW5jdGlvbih3aW5uZXIsIC4uLnJ1bm5lcnMpIHtcbiAgcmV0dXJuIHByaW50KHdpbm5lciwgcnVubmVycyk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///0\n");/***/ })
],
0,[[0,1]]]);
  • eval-cheap-module-source-map.js
/** ATTENTION: An "eval-source-map" devtool has been used.* This devtool is neither made for production nor for readable output files.* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)* or disable the default devtool with "devtool: false".* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).*/
(self["webpackChunk"] = self["webpackChunk"] || []).push([[0],[
/* 0 */
/*!*********************************************************************!*\!*** ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee ***!\*********************************************************************/
/*! unknown exports (runtime-defined) */
/*! runtime requirements:  */
/***/ (() => {eval("// Taken from http://coffeescript.org/\n\n// Objects:\nvar math, race;\n\nmath = {\n  root: Math.sqrt,\n  square: square,\n  cube: function(x) {\n    return x * square(x);\n  }\n};\n\n// Splats:\nrace = function(winner, ...runners) {\n  return print(winner, runners);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vZXhhbXBsZS5jb2ZmZWU/MjQxNiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFVTs7O0FBQUEsSUFBQSxJQUFBLEVBQUE7O0FBQ1YsSUFBQSxHQUNFO0VBQUEsSUFBQSxFQUFRLElBQUksQ0FBQyxJQUFiO0VBQ0EsTUFBQSxFQUFRLE1BRFI7RUFFQSxJQUFBLEVBQVEsUUFBQSxDQUFDLENBQUQsQ0FBQTtXQUFPLENBQUEsR0FBSSxNQUFBLENBQU8sQ0FBUDtFQUFYO0FBRlIsRUFGUTs7O0FBT1YsSUFBQSxHQUFPLFFBQUEsQ0FBQyxNQUFELEVBQUEsR0FBUyxPQUFULENBQUE7U0FDTCxLQUFBLENBQU0sTUFBTixFQUFjLE9BQWQ7QUFESyIsInNvdXJjZXNDb250ZW50IjpbIiMgVGFrZW4gZnJvbSBodHRwOi8vY29mZmVlc2NyaXB0Lm9yZy9cblxuIyBPYmplY3RzOlxubWF0aCA9XG4gIHJvb3Q6ICAgTWF0aC5zcXJ0XG4gIHNxdWFyZTogc3F1YXJlXG4gIGN1YmU6ICAgKHgpIC0+IHggKiBzcXVhcmUgeFxuXG4jIFNwbGF0czpcbnJhY2UgPSAod2lubmVyLCBydW5uZXJzLi4uKSAtPlxuICBwcmludCB3aW5uZXIsIHJ1bm5lcnNcbiJdLCJmaWxlIjoiMC5qcyJ9\n//# sourceURL=webpack-internal:///0\n");/***/ })
],
0,[[0,1]]]);
  • cheap-module-source-map.js.map
{"version":3,"file":"./bundle-cheap-module-source-map.js","sources":["webpack:///./example.coffee"],"sourcesContent":["# Taken from http://coffeescript.org/\n\n# Objects:\nmath =\n  root:   Math.sqrt\n  square: square\n  cube:   (x) -> x * square x\n\n# Splats:\nrace = (winner, runners...) ->\n  print winner, runners\n"],"mappings":";;;;;;;;;AAEA;AACA;;AADA;AACA;AAAA;AACA;AACA;AACA;AAAA;AAAA;AAFA;AACA;;AAIA;AACA;AADA;AACA;AACA;A;;A","sourceRoot":""}
  • cheap-source-map.js.map
{"version":3,"file":"./bundle-cheap-source-map.js","sources":["webpack:///./example.coffee"],"sourcesContent":["// Taken from http://coffeescript.org/\n\n// Objects:\nvar math, race;\n\nmath = {\n  root: Math.sqrt,\n  square: square,\n  cube: function(x) {\n    return x * square(x);\n  }\n};\n\n// Splats:\nrace = function(winner, ...runners) {\n  return print(winner, runners);\n};\n"],"mappings":";;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;A","sourceRoot":""}

(3) 演练

对于本指南,我们将使用 inline-source-map 选项,这有助于解释说明示例意图(此配置仅用于示例,不要用于生产环境):

webpack.config.js

 const path = require('path');const HtmlWebpackPlugin = require('html-webpack-plugin');const { CleanWebpackPlugin } = require('clean-webpack-plugin');module.exports = {mode: 'development',entry: {index: './src/index.js',print: './src/print.js',},
+  devtool: 'inline-source-map',plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin({title: 'Development',}),],output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),},};

现在,让我们来做一些调试,在 print.js 文件中生成一个错误:

src/print.js

 export default function printMe() {
-  console.log('I get called from print.js!');
+  cosnole.log('I get called from print.js!');}

**运行 npm run build**

现在,在浏览器中打开生成的 index.html 文件,点击按钮,并且在控制台查看显示的错误。错误应该如下:

Uncaught ReferenceError: cosnole is not definedat HTMLButtonElement.printMe (print.js:2)

我们可以看到,此错误包含有发生错误的文件(print.js)和行号(2)的引用。这是非常有帮助的,因为现在我们可以确切地知道,所要解决问题的位置。

2、选择一个开发工具

在每次编译代码时,手动运行 npm run build 会显得很麻烦。

webpack 提供几种可选方式,帮助你在代码发生变化后自动编译代码:

多数场景中,你可能需要使用 webpack-dev-server,但是不妨探讨一下以上的所有选项。

(1) 使用 watch mode(观察模式)

你可以指示 webpack “watch” 依赖图中所有文件的更改。如果其中一个文件被更新,代码将被重新编译,所以你不必再去手动运行整个构建。

我们添加一个用于启动 webpack watch mode 的 npm scripts:

package.json

 {"name": "webpack-demo","version": "1.0.0","description": "","private": true,"scripts": {"test": "echo \"Error: no test specified\" && exit 1",
+    "watch": "webpack --watch","build": "webpack"},"keywords": [],"author": "","license": "ISC","devDependencies": {"clean-webpack-plugin": "^3.0.0","html-webpack-plugin": "^4.5.0","webpack": "^5.4.0","webpack-cli": "^4.2.0"},"dependencies": {"lodash": "^4.17.20"}}

如果不想在 watch 触发增量构建后删除 index.html 文件,可以在 CleanWebpackPlugin 中配置 cleanStaleWebpackAssets 选项 来实现:

webpack.config.js

 const path = require('path');const HtmlWebpackPlugin = require('html-webpack-plugin');const { CleanWebpackPlugin } = require('clean-webpack-plugin');module.exports = {mode: 'development',entry: {index: './src/index.js',print: './src/print.js',},devtool: 'inline-source-map',plugins: [
-    new CleanWebpackPlugin(),
+    new CleanWebpackPlugin({ cleanStaleWebpackAssets: false }),new HtmlWebpackPlugin({title: 'Development',}),],output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),},};

现在,你可以在命令行中运行 npm run watch,然后就会看到 webpack 是如何编译代码。 然而,你会发现并没有退出命令行。这是因为此 script 当前还在 watch 你的文件。

现在,webpack 观察文件的同时,先移除我们之前加入的错误:

src/print.js

 export default function printMe() {
-  cosnole.log('I get called from print.js!');
+  console.log('I get called from print.js!');}

现在,保存文件并检查 terminal(终端) 窗口。应该可以看到 webpack 自动地重新编译修改后的模块!

唯一的缺点是,为了看到修改后的实际效果,你需要刷新浏览器。如果能够自动刷新浏览器就更好了,因此接下来我们会尝试通过 webpack-dev-server 实现此功能。

webpackdevserver_1320">(2) 使用 webpack-dev-server

webpack-dev-server 为你提供了一个简单的 web server,并且具有 live reloading(实时重新加载) 功能。设置如下:

npm install --save-dev webpack-dev-server

修改配置文件,告知 dev server,从什么位置查找文件:

webpack.config.js

 const path = require('path');const HtmlWebpackPlugin = require('html-webpack-plugin');const { CleanWebpackPlugin } = require('clean-webpack-plugin');module.exports = {mode: 'development',entry: {index: './src/index.js',print: './src/print.js',},devtool: 'inline-source-map',
+  devServer: {
+    contentBase: './dist',
+  },plugins: [new CleanWebpackPlugin({ cleanStaleWebpackAssets: false }),new HtmlWebpackPlugin({title: 'Development',}),],output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),},};

以上配置告知 webpack-dev-server,将 dist 目录下的文件 serve 到 localhost:8080 下。

我们添加一个可以直接运行 dev server 的 script:

package.json

 {"name": "webpack-demo","version": "1.0.0","description": "","private": true,"scripts": {"test": "echo \"Error: no test specified\" && exit 1","watch": "webpack --watch",
+    "start": "webpack serve --open","build": "webpack"},"keywords": [],"author": "","license": "ISC","devDependencies": {"clean-webpack-plugin": "^3.0.0","html-webpack-plugin": "^4.5.0","webpack": "^5.4.0","webpack-cli": "^4.2.0","webpack-dev-server": "^3.11.0"},"dependencies": {"lodash": "^4.17.20"}}

现在,在命令行中运行 npm start,我们会看到浏览器自动加载页面。如果你更改任何源文件并保存它们,web server 将在编译代码后自动重新加载。试试看!

webpackdevmiddleware_1398">(3) 使用 webpack-dev-middleware

webpack-dev-middleware 是一个封装器(wrapper),它可以把 webpack 处理过的文件发送到一个 server。 webpack-dev-server 在内部使用了它,然而它也可以作为一个单独的 package 来使用,以便根据需求进行更多自定义设置。下面是一个 webpack-dev-middleware 配合 express server 的示例。

首先,安装 expresswebpack-dev-middleware

npm install --save-dev express webpack-dev-middleware

现在,我们需要调整 webpack 配置文件,以确保 middleware(中间件) 功能能够正确启用:

webpack.config.js

 const path = require('path');const HtmlWebpackPlugin = require('html-webpack-plugin');const { CleanWebpackPlugin } = require('clean-webpack-plugin');module.exports = {mode: 'development',entry: {index: './src/index.js',print: './src/print.js',},devtool: 'inline-source-map',devServer: {contentBase: './dist',},plugins: [new CleanWebpackPlugin({ cleanStaleWebpackAssets: false }),new HtmlWebpackPlugin({title: 'Development',}),],output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),
+    publicPath: '/',},};

我们将会在 server 脚本使用 publicPath,以确保文件资源能够正确地 serve 在 http://localhost:3000 下,稍后我们会指定 port number(端口号)。接下来是设置自定义 express server:

project

  webpack-demo|- package.json|- webpack.config.js
+ |- server.js|- /dist|- /src|- index.js|- print.js|- /node_modules

server.js

javascript">const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');const app = express();
const config = require('./webpack.config.js');
const compiler = webpack(config);// 告知 express 使用 webpack-dev-middleware,
// 以及将 webpack.config.js 配置文件作为基础配置。
app.use(webpackDevMiddleware(compiler, {publicPath: config.output.publicPath,})
);// 将文件 serve 到 port 3000。
app.listen(3000, function () {console.log('Example app listening on port 3000!\n');
});

现在,添加一个 npm script,以使我们更方便地运行 server:

package.json

 {"name": "webpack-demo","version": "1.0.0","description": "","private": true,"scripts": {"test": "echo \"Error: no test specified\" && exit 1","watch": "webpack --watch","start": "webpack serve --open",
+    "server": "node server.js","build": "webpack"},"keywords": [],"author": "","license": "ISC","devDependencies": {"clean-webpack-plugin": "^3.0.0","express": "^4.17.1","html-webpack-plugin": "^4.5.0","webpack": "^5.4.0","webpack-cli": "^4.2.0","webpack-dev-middleware": "^4.0.2","webpack-dev-server": "^3.11.0"},"dependencies": {"lodash": "^4.17.20"}}

现在,在 terminal(终端) 中执行 npm run server,将会有类似如下信息输出:

Example app listening on port 3000!
...
<i> [webpack-dev-middleware] asset index.bundle.js 1.38 MiB [emitted] (name: index)
<i> asset print.bundle.js 6.25 KiB [emitted] (name: print)
<i> asset index.html 274 bytes [emitted]
<i> runtime modules 1.9 KiB 9 modules
<i> cacheable modules 530 KiB
<i>   ./src/index.js 406 bytes [built] [code generated]
<i>   ./src/print.js 83 bytes [built] [code generated]
<i>   ./node_modules/lodash/lodash.js 530 KiB [built] [code generated]
<i> webpack 5.4.0 compiled successfully in 709 ms
<i> [webpack-dev-middleware] Compiled successfully.
<i> [webpack-dev-middleware] Compiling...
<i> [webpack-dev-middleware] assets by status 1.38 MiB [cached] 2 assets
<i> cached modules 530 KiB (javascript) 1.9 KiB (runtime) [cached] 12 modules
<i> webpack 5.4.0 compiled successfully in 19 ms
<i> [webpack-dev-middleware] Compiled successfully.

现在,打开浏览器,访问 http://localhost:3000。应该看到 webpack 应用程序已经运行!


http://www.ppmy.cn/embedded/138725.html

相关文章

STM32设计防丢防摔智能行李箱

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 随着科技的不断发展&#xff0c;嵌入式系统、物联网技术、智能设备…

微信小程序——01开发前的准备和开发工具

一、踏上小程序开发之旅前的准备 &#xff08;一&#xff09;小程序账号注册 开启注册流程 首先&#xff0c;在浏览器中打开 “微信公众平台”&#xff08;微信公众平台&#xff09;。进入平台后&#xff0c;你会看到右上角有一个 “立即注册” 按钮&#xff0c;点击它&#x…

深入理解 JavaScript 中的 Array.find() 方法:原理、性能优势与实用案例详解

目录 深入理解 JavaScript 中的 Array.find() 方法&#xff1a;原理、性能优势与实用案例详解 一、引言&#xff1a;为什么要使用Array.find() 二、Array.find()的使用与技巧 1、基础语法 2、返回值 3、使用技巧 三、Array.find()的优势与实际应用案例 1、利用返回引用…

精通rust宏系列教程-入门篇

Rust最令人敬畏和强大的特性之一是它使用和创建宏的能力。不幸的是&#xff0c;用于创建宏的语法可能相当令人生畏&#xff0c;并且对于新开发人员来说&#xff0c;这些示例可能会令人不知所措。我向你保证Rust宏非常容易理解&#xff0c;本文将为你介绍如何创建自己的宏。 什么…

【星海随笔】分布式管理Zookeeper

高可用集群 地址&#xff1a;https://archive.apache.org/dist/zookeeper TPS既每秒系统吞吐量 QPS即每秒查询率 Zookeeper的选举机制 确保所有节点对外表现为一个统一的服务。 选举机制分为两个阶段&#xff1a;Leader选举和投票确认 Zookeeper 的选举机制确保集群中的所有节…

C# OpenCV 通过高度图去筛选轮廓

//输入图像 threshCropMap.ImWrite("D:\\test\\threshCropMap_BeforeFilterByBlob.bmp"); //设定我们要筛选的高度 var ResultHeight 60; //创建对应高度的图像&#xff0c;由于是高度信息图&#xff0c;所有要使用32位来存放数据 Mat mat new Mat(filter.Rows, fi…

单片机学习笔记 4. 蜂鸣器滴~滴~滴~

更多单片机学习笔记&#xff1a;单片机学习笔记 1. 点亮一个LED灯单片机学习笔记 2. LED灯闪烁单片机学习笔记 3. LED灯流水灯 目录 0、实现的功能 1、Keil工程 1-1 蜂鸣器工作原理 1-2 三极管工作原理 1-3 蜂鸣器原理图 2、代码实现 0、实现的功能 使蜂鸣器滴~滴~滴~ 1…

ue5入门教程:Pawn

一、Pawn的基本概念 定义&#xff1a;Pawn是由玩家或AI控制的所有Actor的基类。它包含了物理实体、移动和控制这三个核心要素。关系&#xff1a;默认情况下&#xff0c;控制器&#xff08;Controller&#xff09;和Pawn之间是一对一的关系。控制器负责处理玩家的输入&#xff…