【webpack4系列】webpack基础用法(二)
文章目录
- entry
- output
- loader
- plugin
- mode
- 前端构建基础配置
- 关联HTML插件html-webpack-plugin
- 构建 CSS
- 解析 ES6和React JSX
- 解析 ES6
- 解析 React JSX
- 解析CSS、Less和Sass
- 解析CSS
- 解析Less
- 解析sass
- 解析图片和字体
- 资源解析:解析图片
- 资源解析:解析字体
- 资源解析:使用url-loader
- webpack中的文件监听
- webpack中的热更新及原理分析
- 热更新:webpack-dev-server
- 热更新:使⽤ webpack-dev-middleware
- 文件指纹策略:chunkhash、contenthash和hash
- 文件指纹如何生成
- 文件指纹设置
- HTML 、CSS和JavaScript代码压缩
- JS压缩
- CSS压缩
- HTML压缩
webpack 本质上是一个打包工具,它会根据代码的内容解析模块依赖,帮助我们把多个模块的代码打包。
一切文件:JavaScript、CSS、SCSS、图片、模板,在 Webpack 眼中都是一个个模块,这样的好处是能清晰的描述出各个模块之间的依赖关系,以方便 Webpack 对模块进行组合和打包。 经过 Webpack 的处理,最终会输出浏览器能使用的静态资源。
entry
webpack 构建的入口entry,webpack 会读取这个文件,并从它开始解析依赖,在内部构件一个依赖图,这个依赖图会引用项目中使用到的各个模块,然后进行打包,生成一个或者多个 bundle 文件。
我们常见的项目中,如果是单页面应用,那么入口只有一个;如果是多个页面的项目,那么通常是一个页面会对应一个构建入口。
单⼊⼝:entry 是⼀个字符串,如下代码:
module.exports = {entry: './src/index.js'
};
上述代码等价于:
module.exports = {entry: {main: './src/index.js'}
}
多⼊口:entry 是⼀个对象,如下代码:
module.exports = {entry: {app: './src/app.js',home: './src/home.js'}
};
还有一种场景比较少用到,即是多个文件作为一个入口来配置,webpack 会解析多个文件的依赖然后打包到一起:
// 使用数组来对多个文件进行打包
module.exports = {entry: {main: ['./src/foo.js','./src/bar.js']}
}
动态 entry
const path = require('path');
const fs = require('fs');// src/pages 目录为页面入口的根目录
const pagesRoot = path.resolve(__dirname, './src/pages');
// fs 读取 pages 下的所有文件夹来作为入口,使用 entries 对象记录下来
const entries = fs.readdirSync(pagesRoot).reduce((entries, page) => {// 文件夹名称作为入口名称,值为对应的路径,可以省略 `index.js`,webpack 默认会寻找目录下的 index.js 文件entries[page] = path.resolve(pagesRoot, page);return entries;
}, {});module.exports = {// 将 entries 对象作为入口配置entry: entries,// ...
};
output
output用来告诉 webpack 如何将编译后的文件输出到磁盘。webpack 构建生成的文件名、路径等都是可以配置的,在配置文件中使用 output 字段来进行设置:
module.exports = {// ...output: {path: path.resolve(__dirname, 'dist'),filename: 'bundle.js',},
}// 或者使用 entry 的名称
module.exports = {entry: {main: './src/index.js' // main 为 entry 的名称},output: {filename: '[name].js', // 使用 [name] 来引用 entry 名称,在这里即为 mainpath: path.join(__dirname, '/dist/[hash]'),// 路径中使用 hash,每次构建时会有一个不同 hash 值,可以用于避免发布新版本时浏览器缓存导致代码没有更新// 文件名中也可以使用 hash},
}
loader
我们在前端构建中会遇见需要使用各式各样的文件,例如 css 代码,图片,模板代码等。webpack 中提供一种处理多种文件格式的机制,便是使用 loader。我们可以把 loader 理解为是一个转换器,负责把某种文件格式的内容转换成 webpack 可以支持打包的模块。例如我们需要 css-loader 来处理 .css 文件(这里其实还需要 style-loader),最终把不同格式的文件都解析成 js 代码,以便打包后在浏览器中运行。
webpack 开箱即用只支持 JS 和 JSON 两种文件类型,通过 Loaders 去支持其它文件类型并且把它们转化成有效的模块,并且可以添加到依赖图中。
本身是一个函数,接受源文件作为参数,返回转换的结果。
常见的 Loaders 有哪些?
- babel-loader:转换ES6、ES7等JS新特性语法
- css-loader:支持.css文件的加载和解析
- less-loader:将less文件转换成css
- ts-loader:将TS转换成JS
- file-loader:进行图片、字体等的打包
- raw-loader:将文件以字符串的形式导入
- thread-loader:多线程打包JS和CSS
示例,处理CSS,一般要安装style-loader、css-loader:
其中webpack4.x安装style-loader2.x、css-loader3.x:
npm i css-loader@3 style-loader@2 -D
如果要使用babel-loader,使用webpack4.x,要安装npm install babel-loader@8 @babel/core @babel/preset-env
babel的一系列工具链说明:
- @babel/core:babel核心包,babel-loader的核心依赖。
- @babel/preset-env:ES语法分析包。
注:es6到es5的语法转换是以插件的形式实现的,可以是自己的插件也可以是官方提供的插件如箭头函数转换插件@babel/plugin-transform-arrow-functions。
由此我们可以看出,我们需要转换哪些新的语法,都可以将相关的插件一一列出,但是这其实非常复杂,因为我们往往需要根据兼容的浏览器的不同版本来确定需要引入哪些插件,为了解决这个问题,babel给我们提供了一个预设插件组,即@babel/preset-env,可以根据选项参数来灵活地决定提供哪些插件。
- @babel/polyfill:@babel/preset-env只是提供了语法转换的规则,但是它并不能弥补浏览器缺失的一些新的功能,如一些内置的方法和对象,如Promise,Array.from等,此时就需要polyfill来做js得垫片,弥补低版本浏览器缺失的这些新功能。
我们需要注意的是,polyfill的体积是很大的,如果我们不做特殊说明,它会把你目标浏览器中缺失的所有的es6的新的功能都做垫片处理。但是我们没有用到的那部分功能的转换其实是无意义的,造成打包后的体积无谓的增大,所以通常,我们会在presets的选项里,配置"useBuiltIns": “usage”,这样一方面只对使用的新功能做垫片,另一方面,也不需要我们单独引入import '@babel/polyfill’了,它会在使用的地方自动注入。
- babel-loader:理解成一个加载器,webpack通过babel-loader这个中间桥梁告诉webpack怎样去调用@babel/core、@babel/preset-env 、@babel/polyfill这些规则(语法转换和弥补缺失)去编译js。
- @babel/plugin-transform-runtime:polyfill的垫片是在全局变量上挂载目标浏览器缺失的功能,因此在开发类库,第三方模块或者组件库时,就不能再使用babel-polyfill了,否则可能会造成全局污染,此时应该使用transform-runtime。transform-runtime的转换是非侵入性的,也就是它不会污染你的原有的方法。遇到需要转换的方法它会另起一个名字,否则会直接影响使用库的业务代码。
故开发类库,第三方模块或者组件库时使用transform-runtime
,平常的项目使用babel-polyfill
即可.
rules的配置如下:
module: {rules:[{test: /\.css$/,use: ['style-loader','css-loader']},{test: /\.jsx?$/, // 匹配文件路径的正则表达式,通常我们都是匹配文件类型后缀exclude: /node_modules/, // 排除掉node_modules这个文件夹的js文件include: [path.resolve(__dirname,'src') // 指定哪些路径下的文件需要经过 loader 处理],use: { // 指定使用的 loaderloader: 'babel-loader', // babel-loader 可以使用 babel 来将 ES6 代码转译为浏览器可以执行的的 ES5 代码options: {presets: ['@babel/preset-env']}}}]
}
plugin
插件⽤于 bundle ⽂件的优化,资源管理和环境变量注⼊,作⽤于整个构建过程。
常用的plugin:
- CommonsChunkPlugin:将chunks相同的模块代码提取成公共js,webpack4.x版本使用optimization.SplitChunks
- cleanWebpackPlugin:清理构建目录
- ExtractTextWebpackPlugin:将CSS从bundle文件里提取成一个独立的CSS文件(webpack3.x版本),webpack4.x版本使用mini-css-extract-plugin
- CopyWebpackPlugin:将文件或者文件夹拷贝到构建的输出目录
- HtmlWebpackPlugin:创建html文件去承载输出的bundle(webpack4.x使用4.x版本HtmlWebpackPlugin)
- UglifyjsWebpackPlugin:压缩JS
- ZipWebpackPlugin:将打包出的资源生成一个zip包
const HtmlWebpackPlugin = require('html-webpack-plugin')module.exports = {plugins: [new HtmlWebpackPlugin({template: './src/index.html'}),]
}
在 webpack 的构建流程中,plugin 用于处理更多其他的一些构建任务。可以这么理解,模块代码转换的工作由 loader 来处理,除此之外的其他任何工作都可以交由 plugin 来完成。
例如,使用 copy-webpack-plugin 来复制其他不需要 loader 处理的文件,只需在配置中通过 plugins 字段添加新的 plugin 即可:
webpack4.x安装copy-webpack-plugin@6 版本
new CopyWebpackPlugin({patterns: [{from: path.resolve(__dirname, "../static"),to: 'static',globOptions: {ignore: [".*"]}}]
})
mode
mode,构建模式是 webpack4引入的新概念,用于方便快捷地指定一些常用的默认优化配置。
mode取值:
- development:开发环境
- production:生产环境
- none :不需要任何默认优化配置
示例:
module.exports = {mode: 'development', // 指定构建模式为 development// ...
}
development 和 production 模式的区别:
- 这两个模式会使用 DefinePlugin 来将 process.env.NODE_ENV 的值分别设置为 development 和 production,方便开发者在项目业务代码中判断当前构建模式。
- production 模式会启用TerserPlugin来压缩JS代码,让生成的代码文件更小。
- development 模式会启用 devtools: ‘eval’ 配置,提升构建和再构建的速度。
前端构建基础配置
关联HTML插件html-webpack-plugin
webpack4.x对应的html-webpack-plugin@4
npm install html-webpack-plugin@4 -D
webpack配置:
const HtmlWebpackPlugin = require('html-webpack-plugin')module.exports = {plugins: [new HtmlWebpackPlugin({template: './src/index.html'}),]
}
构建 CSS
webpack4.x安装style-loader2.x、css-loader3.x
安装:
npm i css-loader@3 style-loader@2 -D
配置中引入 loader 来解析和处理 CSS 文件:
module: {rules: [{test: /\.css$/,include: [path.resolve(__dirname, 'src')],use: ['style-loader', 'css-loader'],}]
}
- css-loader 负责解析 CSS 代码,主要是为了处理 CSS 中的依赖,例如 @import 和 url() 等引用外部文件的声明;
- style-loader 会将 css-loader 解析的结果转变成 JS 代码,运行时动态插入 style 标签来让 CSS 代码生效。
如果需要单独把 CSS 文件分离出来,我们需要使用 mini-css-extract-plugin 插件。
注:v4 版本之后才开始使用 mini-css-extract-plugin,之前的版本是使用 extract-text-webpack-plugin。
安装mini-css-extract-plugin
插件:
npm i mini-css-extract-plugin -D
配置:
解析 ES6和React JSX
解析 ES6
webpack4.x安装@babel/core,@babel/preset-env,babel-loader@8
npm i @babel/core @babel/preset-env babel-loader@8 -D
在根路径下新建一个.babelrc
文件,增加ES6的babel preset配置,代码如下:
{"preset": ["@babel/preset-env"]
}
webpack.config.js配置:
module: {rules: [{test: /\.js$/,use: 'babel-loader'} ]
}
解析 React JSX
安装:
npm i @babel/preset-react -D
npm i react react-dom -S
在.babelrc文件中添加react相关配置:
{"presets": ["@babel/preset-env", "@babel/preset-react"]
}
编写一个示例代码JS,例如src/search.js:
'use strict'import React from 'react'
import ReactDOM from 'react-dom'class Search extends React.Component {render() {return <div>Search Text</div>}
}ReactDOM.render(<Search />, document.getElementById('root'))
然后编译后 引用编译后的JS查看效果即可。其中在dist中编写的search.html示例需要添加root这个dom节点。
解析CSS、Less和Sass
解析CSS
解析css,需要安装style-loader
和css-loader
。
其中webpack4.x
安装style-loader2.x
、css-loader3.x
:
npm i css-loader@3 style-loader@2 -D
版本参考:https://github.com/webpack-contrib/style-loader/blob/v2.0.0/package.json
rules配置:
{test: /.css$/,use: ['style-loader', 'css-loader']
}
解析Less
解析less,需要安装less、less-loader。
其中webpack4.x
建议安装less-loader@6(less-loader@7.0.1也支持webpack4.x)
npm i less less-loader@6 -D
版本参考:https://github.com/webpack-contrib/less-loader/blob/v6.2.0/package.json
rules配置如下:
{test: /.less$/,use: ['style-loader', 'css-loader', 'less-loader']
}
解析sass
webpack4.x安装依赖:
npm i sass-loader@7.3.1 node-sass@4.14.1 sass-resources-loader@2 sass-resources-loader@2.2.4 -D
element-ui依赖的sass-loder跟node-sass版本:
npm i sass-loader@10.2.0 sass@1.29.0 -D
rules配置:
{test: /.scss$/,use: ['style-loader', 'css-loader','sass-loader']
}
解析图片和字体
资源解析:解析图片
解析图片,可以安装file-loader,其中file-loader最新版本为6.2.0,支持webpack4.x。
npm i file-loader -D
版本参考:https://github.com/webpack-contrib/file-loader/blob/v6.2.0/package.json
rules配置如下:
{test: /.(png|jpe?g|gif)$/,use: 'file-loader'
}
资源解析:解析字体
rules配置如下:
{test: /.(woff|woff2|eot|otf|ttf)$/,use: 'file-loader'
},
css参考样式:
@font-face {font-family: 'SourceHeavy';src: url('./images/SourceHeavy.otf') format('truetype');
}.search-text {font-size: 20px;color: #f00;font-family: 'SourceHeavy';
}
资源解析:使用url-loader
url-loader 也可以处理图⽚和字体,可以设置较⼩资源⾃动 base64,其中url-loader内部实现也是使用的file-loader。
目前url-loader最新版本为4.1.1,支持webpack4.x.
npm i url-loader -D
版本参考:https://github.com/webpack-contrib/url-loader/blob/master/package.json
rules配置(把之前关于图片的file-loader配置替换):
{test: /.(png|jpe?g|gif)$/,use: [{ loader: 'url-loader', options: { limit: 10240 } }],}
webpack中的文件监听
⽂件监听是在发现源码发⽣变化时,⾃动重新构建出新的输出⽂件。
webpack 开启监听模式,有两种⽅式:
- 启动 webpack 命令时,带上 --watch 参数
- 在配置 webpack.config.js 中设置 watch: true
在package.json中添加命令如下:
"scripts": {"watch": "webpack --watch"},
注:唯⼀缺陷:每次需要⼿动刷新浏览器。
⽂件监听的原理分析:
轮询判断⽂件的最后编辑时间是否变化。
某个⽂件发⽣了变化,并不会⽴刻告诉监听者,⽽是先缓存起来,等 aggregateTimeout
module.export = {//默认 false,也就是不开启watch: true,//只有开启监听模式时,watchOptions才有意义wathcOptions: {//默认为空,不监听的文件或者文件夹,支持正则匹配ignored: /node_modules/,//监听到变化发生后会等300ms再去执行,默认300msaggregateTimeout: 300,//判断文件是否发生变化是通过不停询问系统指定文件有没有变化实现的,默认每秒问1000次poll: 1000}
}
webpack中的热更新及原理分析
热更新:webpack-dev-server
- webpack-dev-server不刷新浏览器
- webpack-dev-server不输出⽂件,⽽是放在内存中
- 使⽤ HotModuleReplacementPlugin插件
webpack4.x对应安装的webpack-dev-server版本3.x。
npm i webpack-dev-server@3 -D
package.json配置:
"scripts": {"dev": "webpack-dev-server --open"
}
其中open是构建完成之后,自动开启浏览器。
在webpack.config.js配置:
'use strict'const webpack = require('webpack');module.exports = {// 其他省略mode: 'development',plugins: [new webpack.HotModuleReplacementPlugin()],devServer: {contentBase: './dist',hot: true}
}
热更新的原理分析:
- Webpack Compile:将JS编译成Bundle
- HMR Server: 将热更新的⽂件输出给HMR Rumtime Bundle server: 提供⽂件在浏览器的访问
- HMR Rumtime: 会被注⼊到浏览器,更新⽂件的变化
- bundle.js: 构建输出的⽂件
热更新:使⽤ webpack-dev-middleware
- WDM 将 webpack 输出的⽂件传输给服务器
- 适⽤于灵活的定制场景
示例:
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);app.use(webpackDevMiddleware(compiler, {publicPath: config.output.publicPath
}));
app.listen(3000, function () {console.log('Example app listening on port 3000!\n');
});
文件指纹策略:chunkhash、contenthash和hash
注:文件指纹只能用于生产环境。
文件指纹如何生成
- Hash:和整个项⽬的构建相关,只要项⽬⽂件有修改,整个项⽬构建的hash值就会更改
- Chunkhash:和webpack 打包的chunk 有关,不同的entry 会⽣成不同的chunkhash值
- Contenthash:根据⽂件内容来定义hash ,⽂件内容不变,则contenthash不变
文件指纹设置
- JS文件:设置output的filename,使⽤[chunkhash]。
output: {path: path.join(__dirname, 'dist'),filename: '[name]_[chunkhash:8].js'}
- CSS文件:设置MiniCssExtractPlugin的filename,使⽤[contenthash]
webpack4.x
安装的mini-css-extract-plugin@1.0.0
npm i mini-css-extract-plugin@1.0.0 -D
配置:
const MiniCssExtractPlugin = require('mini-css-extract-plugin')module.exports = {// 其他省略mode: 'production',module: {rules: [{test: /.css$/,use: [MiniCssExtractPlugin.loader, 'css-loader'],},{test: /.less$/,use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader'],}]},plugins: [new MiniCssExtractPlugin({filename: '[name]_[contenthash:8].css',}),],
}
插件参考地址:https://github.com/webpack-contrib/mini-css-extract-plugin/blob/v1.0.0/package.json
- 图片文件:设置file-loader的name,使⽤[hash]
const MiniCssExtractPlugin = require('mini-css-extract-plugin')module.exports = {// 其他省略mode: 'production',module: {rules: [{test: /.(png|jpe?g|gif)$/,use: [{loader: 'file-loader',options: { name: '[name]_[hash:8].[ext]' },},],},{test: /.(woff|woff2|eot|otf|ttf)$/,use: [{loader: 'file-loader',options: { name: '[name]_[hash:8].[ext]' },},]}]}
}
HTML 、CSS和JavaScript代码压缩
JS压缩
webpack4及以后内置了uglifyjs-webpack-plugin
CSS压缩
需要安装optimize-css-assets-webpack-plugin
,同时使⽤cssnano
。
说明:optimize-css-assets-webpack-plugin插件目前官网最新版本5.0.8,使用的webpack为^4.44.1。
npm i optimize-css-assets-webpack-plugin@5 cssnano@4 -D
插件配置地址:https://github.com/NMFR/optimize-css-assets-webpack-plugin/blob/master/package.json
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')module.exports = {// 其他省略mode: 'production',plugins: [new OptimizeCssAssetsPlugin({assetNameRegExp: /\.css$/g,cssProcessor: require('cssnano'),}),],
}
HTML压缩
安装html-webpack-plugin,并设置压缩参数。
其中webpack4.x对应的html-webpack-plugin@4。
npm i html-webpack-plugin@4 -D
webpack配置:
const HtmlWebpackPlugin = require('html-webpack-plugin')module.exports = {plugins: [new HtmlWebpackPlugin({template: path.join(__dirname, 'src/index.html'),filename: 'index.html',chunks: ['index'],inject: true,minify: {html5: true,collapseWhitespace: true,preserveLineBreaks: false,minifyCSS: true,minifyJS: true,removeComments: false,},}),new HtmlWebpackPlugin({template: path.join(__dirname, 'src/search.html'),filename: 'search.html',chunks: ['search'],inject: true,minify: {html5: true,collapseWhitespace: true,preserveLineBreaks: false,minifyCSS: true,minifyJS: true,removeComments: false,},}),],
}
webpack.dev.js完整配置:
'use strict'const path = require('path')
const webpack = require('webpack')module.exports = {entry: {index: './src/index.js',search: './src/search.js',},output: {path: path.join(__dirname, 'dist'),filename: '[name].js',},mode: 'development',module: {rules: [{test: /.js$/,use: 'babel-loader',},{test: /.css$/,use: ['style-loader', 'css-loader'],},{test: /.less$/,use: ['style-loader', 'css-loader', 'less-loader'],},{test: /.(png|jpe?g|gif)$/,use: [{ loader: 'url-loader', options: { limit: 10240 } }],},{test: /.(woff|woff2|eot|otf|ttf)$/,use: 'file-loader',},],},plugins: [new webpack.HotModuleReplacementPlugin(),new HtmlWebpackPlugin({template: path.join(__dirname, 'src/index.html'),filename: 'index.html',chunks: ['index'],inject: true,minify: {html5: true,collapseWhitespace: true,preserveLineBreaks: false,minifyCSS: true,minifyJS: true,removeComments: false,},}),new HtmlWebpackPlugin({template: path.join(__dirname, 'src/search.html'),filename: 'search.html',chunks: ['search'],inject: true,minify: {html5: true,collapseWhitespace: true,preserveLineBreaks: false,minifyCSS: true,minifyJS: true,removeComments: false,},}),],devServer: {contentBase: './dist',hot: true,},
}
webpack.prod.js完整配置:
'use strict'const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')module.exports = {entry: {index: './src/index.js',search: './src/search.js',},output: {path: path.join(__dirname, 'dist'),filename: '[name]_[chunkhash:8].js',},mode: 'production',module: {rules: [{test: /.js$/,use: 'babel-loader',},{test: /.css$/,use: [MiniCssExtractPlugin.loader, 'css-loader'],},{test: /.less$/,use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader'],},{test: /.(png|jpe?g|gif)$/,use: [{loader: 'file-loader',options: { name: '[name]_[hash:8].[ext]' },},],},{test: /.(woff|woff2|eot|otf|ttf)$/,use: [{loader: 'file-loader',options: { name: '[name]_[hash:8].[ext]' },},],},],},plugins: [new MiniCssExtractPlugin({filename: '[name]_[contenthash:8].css',}),new OptimizeCssAssetsPlugin({assetNameRegExp: /\.css$/g,cssProcessor: require('cssnano'),}),new HtmlWebpackPlugin({template: path.join(__dirname, 'src/index.html'),filename: 'index.html',chunks: ['index'],inject: true,minify: {html5: true,collapseWhitespace: true,preserveLineBreaks: false,minifyCSS: true,minifyJS: true,removeComments: false,},}),new HtmlWebpackPlugin({template: path.join(__dirname, 'src/search.html'),filename: 'search.html',chunks: ['search'],inject: true,minify: {html5: true,collapseWhitespace: true,preserveLineBreaks: false,minifyCSS: true,minifyJS: true,removeComments: false,},}),],
}
package.json:
{"name": "webpacktest","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "webpack --config webpack.prod.js","watch": "webpack --watch","dev": "webpack-dev-server --config webpack.dev.js --open"},"keywords": [],"author": "","license": "ISC","devDependencies": {"@babel/core": "^7.22.10","@babel/preset-env": "^7.22.10","@babel/preset-react": "^7.22.5","babel-loader": "^8.3.0","css-loader": "^3.6.0","cssnano": "^4.1.11","file-loader": "^6.2.0","html-webpack-plugin": "^4.5.2","less": "^4.2.0","less-loader": "^6.2.0","mini-css-extract-plugin": "^1.0.0","optimize-css-assets-webpack-plugin": "^5.0.8","react": "^18.2.0","react-dom": "^18.2.0","style-loader": "^2.0.0","url-loader": "^4.1.1","webpack": "^4.46.0","webpack-cli": "^3.3.12","webpack-dev-server": "^3.11.3"}
}
.babelrc配置:
{"presets": ["@babel/preset-env", "@babel/preset-react"]
}
相关文章:

【webpack4系列】webpack基础用法(二)
文章目录 entryoutputloaderpluginmode前端构建基础配置关联HTML插件html-webpack-plugin构建 CSS 解析 ES6和React JSX解析 ES6解析 React JSX 解析CSS、Less和Sass解析CSS解析Less解析sass 解析图片和字体资源解析:解析图片资源解析:解析字体资源解析&…...
Python Pyvis库创建交互式网络图 高级功能详解
文章目录 动态网络图图布局调整扩展到大规模网络动态网络图 Pyvis支持创建动态网络图,通过时间轴展示网络图的演化过程。 需要使用set_options函数,参数必须为json格式。动态网络图支持添加点和边。 下面是一个简单的动态网络图示例: # 动态网络图示例 from pyvis.networ…...

Linux服务器上安装git lfs命令
有时候,需要批量下载数据集时要用到git lfs命令 首先,使用pip install git-lfs安装,会发现使用时仍然提示:git: lfs is not a git command. See git --help. 这就意味着安装不成功。 因此,需要通过如下途径手动安装&a…...

S100A9:鸡支原体感染中的免疫调控“双面间谍”【AbMole】
在生物学研究的广阔天地里,总有一些分子扮演着令人意想不到的角色。今天,我们要探索的主角是S100A9蛋白,一种在鸡支原体感染过程中展现出惊人双重功能的分子。这项来自华中农业大学动物科技学院与兽医学院的最新研究成果,揭示了S1…...

黑神话悟空黑风山攻略
在黑神话悟空中,玩家一开始来到黑风山的地图就会站在前山土地庙。 下面小编将会根据黑风山地图的地标来进行路线攻略推荐, 玩家可以一边查看游戏地图一边了解这些路线的动线是怎样的。 在苍狼林前山捡到药材老山参,跟随金色光线找到附近的土…...

Android 11 FileProvider的使用和限制
概述: 从Android 7开始,将不允许在app之间,使用file uri,即file://的方式,传递一个file,否则会抛出异常:FileUriExposedException ,其解决方案,就是使用FileProvider,用c…...
闭包+面试真题
对闭包的理解 闭包是内层函数使用外层变量 (子级可以访问父级的变量,但是父级不可以访问子级的) 闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,创建的函数可以访问到当前函数的局部…...

Java企业面试题3
1. break和continue的作用(智*图) break:用于完全退出一个循环(如 for, while)或一个 switch 语句。当在循环体内遇到 break 语句时,程序会立即跳出当前循环体,继续执行循环之后的代码。continue:用于跳过…...
第3章C/C++流程控制
第3章C/C流程控制 循环语句for循环语句【例题3.14】 求123....100。使用for语句实现循环。【例题3.15】 打印出所有“水仙花数”。【例题3.16】 输出一个金字塔图形。 跳转语句break语句【3.20】输入若干个整数,计算已输入整数之和,直到输入负数为止。 c…...

这是一款很棒的AI录音机——Plaud NotePin,但是它注定失败
Plaud NotePin是一款设计精巧的AI录音设备,它以药丸形状的机身和169美元的售价吸引了市场的注意。这款设备的主要卖点在于它的多功能性,能够转录、总结并提取音频中的关键信息。它的录音和转录功能建立在成熟的技术之上,从微型麦克风到语音转…...

self-play RL学习笔记
让AI用随机的路径尝试新的任务,如果效果超预期,那就更新神经网络的权重,使得AI记住多使用这个成功的事件,再开始下一次的尝试。——llya Sutskever 这两天炸裂朋友圈的OpenAI草莓大模型o1和此前代码能力大幅升级的Claude 3.5&…...

【机器学习】OpenCV入门与基础知识
🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 💫个人格言: "如无必要,勿增实体" 文章目录 OpenCV入门与基础知识简介安装与环境配置WindowsLinuxmacOS 核心数据结构MatSca…...

JUC学习笔记(二)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 四、共享模型之内存4.1 Java 内存模型4.2 可见性退不出的循环解决方法可见性 vs 原子性模式之 Balking1.定义2.实现 4.3 有序性原理之指令级并行1. 名词2.鱼罐头的故…...

炫酷HTML蜘蛛侠登录页面
全篇使用HTML、CSS、JavaScript,建议有过基础的进行阅读。 一、预览图 二、HTML代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-w…...

算法里面的离散化
一、离散化(discretization)在算法和数据结构中指的是将连续的输入数据映射到离散的值或者范围,从而使得处理和计算变得更高效。通常用于处理大范围或者无限可能的输入,以便将其转化为有限的、可以有效处理的范围。 离散化的定义…...

Https AK--(ssl 安全感满满)
免责声明:本文仅做分享! 目录 https探测 openssl Openssl连接服务器获取基本信息 连接命令: 指定算法连接: 测试弱协议连接是否可以连接: 得到的内容包括: sslscan 在线查询证书 https AK type 中间人AK sslsplit 工具…...

ERROR: Failed building wheel for cython_bbox | pip install cython_bbox 失败【解决方案】
🥇 版权: 本文由【墨理学AI】原创首发、各位读者大大、敬请查阅、感谢三连 🎉 声明: 作为全网 AI 领域 干货最多的博主之一,❤️ 不负光阴不负卿 ❤️ 文章目录 win11 系统 pip3 install cython_bbox 失败报错如下解决方法:1 下载…...
逻辑与位运算的双面舞者:、、|、||深度解析
深入解析&、&&、|、||:逻辑与位运算的奥秘之旅 在编程的世界里,&、&&、|、||这四种运算符扮演着至关重要的角色。它们不仅仅是简单的符号,更是连接程序逻辑、实现复杂功能的桥梁。本文旨在深入探讨这四者的区别与联…...

中断门+陷阱门
中断门: 中断描述符在IDT表里面 kd> dq idtr 80b95400 83e48e000008bfc0 83e48e000008c150 80b95410 0000850000580000 83e4ee000008c5c0 80b95420 83e4ee000008c748 83e48e000008c8a8 80b95430 83e48e000008ca1c 83e48e000008d018 80b95440 000085000050…...

RTMP直播播放器的几种选择
如何选择RTMP播放器? 在选择RTMP播放器时,需要综合考虑多个因素,以确保选择的播放器能够满足实际需求并提供良好的用户体验。以下是一些选择RTMP播放器的建议: 1. 功能需求 低延迟:对于直播场景,低延迟是…...
【Redis】Cluster集群
目录 1、背景2、核心特性【1】数据分片【2】高可用【3】去中心化【4】客户端重定向 3、集群架构【1】最小规模【2】节点角色【3】通信协议 4、数据分片与路由【1】哈希槽分配【2】客户端路由逻辑 5、故障恢复6、适用场景 1、背景 Redis Cluster是Redis官方提供的分布式解决方案…...

贝叶斯深度学习!华科大《Nat. Commun.》发表BNN重大突破!
华科大提出基于贝叶斯深度学习的超分辨率成像,成功被Nat. Commun.收录。可以说,这是贝叶斯神经网络BNN近期最值得关注的成果之一了。另外还有AAAI 2025上的Bella新框架,计算成本降低了99.7%,也非常值得研读。 显然鉴于BNN“不确定…...
Python爬虫实战:Yelp餐厅数据采集完整教程
前言 在数据分析和商业智能领域,餐厅和商户信息的采集是一个常见需求。Yelp作为全球知名的本地商户评论平台,包含了大量有价值的商户信息。本文将详细介绍如何使用Python开发一个高效的Yelp数据爬虫,实现商户信息的批量采集。 技术栈介绍 …...

量子比特实现方式
经典计算机是通过电子电路运转起来的。使用硅制半导体制成的名为晶体管的小元件发挥了开关的作用,将其与金属布线组合起来即可实现逻辑门,再将逻辑门集成起来就能制造出经典计算机。量子计算机的制造过程则要复杂许多,因为量子计算机既需要量…...

高精度滚珠导轨在医疗设备中的多元应用场景
在医疗行业不断追求高效、精准与安全的今天,医疗设备的性能优化至关重要。每一个精密部件都像是设备这个庞大“生命体”中的细胞,共同维持着设备的稳定运行。滚珠导轨,这一看似不起眼却功能强大的传动元件,正悄然在医疗设备领域发…...
B+树知识点总结
核心目标:减少磁盘 I/O 数据库系统(如 MySQL)的主要性能瓶颈通常在于磁盘 I/O(读取和写入数据到物理硬盘的速度远慢于内存访问)。B 树的设计核心就是最大限度地减少访问数据时所需的磁盘 I/O 次数。 一、B 树的基本结…...

Tomcat全方位监控实施方案指南
#作者:程宏斌 文章目录 一.二进制部署1、安装包信息2、新建配置文件2.1 配置config.yaml文件2.2 上传jar包 3、修改配置3.1 备份3.2 修改bin目录下的startup.sh文件 4、重启tomcat5、访问测试 二.docker部署1、临时方案1.1、重新启动容器1.2…...

C++算法-动态规划2
第 4 题 字符串分割 (Word Break) 难度: Medium备注:出自 leetcode题目描述 Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words. For example, given s "l…...
使用Python和TensorFlow实现图像分类
最近研学过程中发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击链接跳转到网站人工智能及编程语言学习教程。读者们可以通过里面的文章详细了解一下人工智能及其编程等教程和学习方法。下面开始对正文内容的…...

OpenCV CUDA模块特征检测------角点检测的接口createMinEigenValCorner()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 该函数创建一个 基于最小特征值(Minimum Eigenvalue)的角点响应计算对象,这是另一种经典的角点检测方法&…...