【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. 功能需求 低延迟:对于直播场景,低延迟是…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
