webpack指南
🌈个人主页:前端青山
🔥系列专栏:webpack篇
🔖人终将被年少不可得之物困其一生
依旧青山,本期给大家带来webpack篇专栏内容:webpack-指南
概念
中文: webpack | webpack中文文档 | webpack中文网
英文:webpack
webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
从 webpack v4.0.0 开始,可以不用引入一个配置文件。然而,webpack 仍然还是高度可配置的。
-
入口(entry)
-
输出(output)
-
loader
-
插件(plugins)
目录
概念
安装
创建webpack的配置文件
入口entry
demo
模式
输出output
插件
页面插件 html-webpack-plugin
安装
配置项
clean-webpack-plugin
copy-webpack-plugin
压缩js代码 UglifyJsPlugin
解析器 模块配置
解析样式相关模块
抽离css文件
封装解析器
自动补全css
图片资源处理
开发服务器设置 - HMR
处理js
开发vue
开发react
安装
cnpm i webpack@4 webpack-cli@4 -g
cnpm i webpack@4 webpack-cli@4 -S
// 打开package.json 查看版本
"dependencies": {"webpack": "^4.46.0","webpack-cli": "^3.3.12"
}
创建webpack的配置文件
// 项目根目录下创建即可 webpack.config.js
module.exports = { // webpack 基于 nodejs
}
入口entry
在 webpack 配置中有多种方式定义 entry
属性
demo
// string | object | array
entry: "./app/entry",
entry: ["./app/entry1", "./app/entry2"],
entry: {a: "./app/entry-a",b: ["./app/entry-b1", "./app/entry-b2"]
},
向 entry
属性传入「文件路径(file path)数组」将创建“多个主入口(multi-main entry)”。
在你想要多个依赖文件一起注入,并且将它们的依赖导向(graph)到一个“chunk”时,传入数组的方式就很有用。
对象语法会比较繁琐。然而,这是应用程序中定义入口的最可扩展的方式。
“可扩展的 webpack 配置”*是指,可重用并且可以与其他配置组合使用。这是一种流行的技术,用于将关注点(concern)从环境(environment)、构建目标(build target)、运行时(runtime)中分离。然后使用专门的工具(如* webpack-merge)将它们合并。
// webpack.config.js
module.exports = {// // 当前程序的入口,必不可少 打包时 通过 webpack 指令// entry: './src/index.js' // string 类型, 默认打包名称为 dist/main.js// entry: ['./src/index.js'] // array 类型, 默认打包名称为 dist/main.jsentry: { // object 类型app: './src/index.js' // 默认打包的名称为 dist/app.js}
}
控制台输入webpack 打包项目测试,注意不同的形式默认打包的文件名称不一样
此时控制台会输出如下信息
The 'mode' option has not been set, webpack will fallback to 'production' for this value.
Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior.
此时需要添加 mode 的配置
模式
mode: "production", // enable many optimizations for production buildsmode: "development", // enabled useful tools for developmentmode: "none", // no defaults
// webpack.config.js
module.exports = {// mode: 'development', // 开发环境mode: 'production', // 生产环境, 如果不设置 mode 选项,默认为 生产环境entry: { app: './src/index.js'}
}
以上的输出为默认输出路径以及文件成名,如果想要自定义,那么就需要配置 输出 选项 output
输出output
配置 output
选项可以控制 webpack 如何向硬盘写入编译文件。注意,即使可以存在多个入口
起点,但只指定一个输出
配置。
const path = require('path')
module.exports = {mode: 'production', entry: { app: './src/index.js' },output: { // 文件输出的配置// 指明打包的项目至 项目根目录下的 build 目录,默认为dist目录path: path.resolve(__dirname, 'build'), // filename: 'bundle.js' // 打包出来的文件的名称, 默认为 entry 对象形势下的 key.jsfilename: '[name].[hash:8].js' // 打包出 entry 对象下 key.随机数.js}
}
插件
页面插件 html-webpack-plugin
安装
cnpm i -S html-webpack-plugin@4
yarn add --dev html-webpack-plugin@4
配置项
Name | Type | Default | Description |
---|---|---|---|
title | {String} | Webpack App | 不指定模版默认生成的页面的 标题. <%= htmlWebpackPlugin.options.title %> |
filename | {String} | 'index.html' | 输出的文件的名称,默认为index.html |
template | {String} | `` | 指定页面的模版路径,可以使用相对或者绝对路径 |
templateContent | {string|Function|false} | false | 可以写行内的页面模版代替template内容 |
templateParameters | {Boolean|Object|Function} | false | 页面的参数信息 |
inject | {Boolean|String} | true | 是否自动引入js文件,以及引入的位置true || 'head' || 'body' || false |
publicPath | {String|'auto'} | 'auto' | 引入导出的js的路径前缀 |
scriptLoading | {'blocking'|'defer'} | 'blocking' | 现代浏览器支持非阻塞javascript加载(`'defer``),以提高页面启动性能。 |
favicon | {String} | `` | 设置导出的文件的小图标 |
meta | {Object} | {} | 设置meta属性E.g. meta: {viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'} |
base | {Object|String|false} | false | 导出的页面中引入base标签 |
minify | {Boolean|Object} | true if mode is 'production' , otherwise false | 生产环境自动压缩页面,其余的不压缩 |
hash | {Boolean} | false | 如果“true”,则将唯一的“webpack”编译哈希附加到所有包含的脚本和CSS文件中。这对于破坏缓存非常有用 |
cache | {Boolean} | true | 仅当文件已更改时才发出该文件 |
showErrors | {Boolean} | true | 错误详细信息将写入HTML页面 |
chunks | {?} | ? | 允许您只添加一些块(例如,只添加单元测试块) |
chunksSortMode | {String|Function} | auto | 允许控制在将块包含到HTML中之前如何对其进行排序。Allowed values are 'none' | 'auto' | 'manual' | {Function} |
excludeChunks | {Array.<string>} | `` | 允许您跳过某些块(例如不添加单元测试块) |
xhtml | {Boolean} | false | false Iftrue 将link 标记呈现为自动关闭(符合XHTML) |
如果在使用模版时还想设置自定义的值,可以在模版中直接 通过如下语句指定
<!--public/index.html-->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><!-- <title>webpack</title> --><title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body></body>
</html>
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {mode: 'production',entry: {app: './src/index.js'},output: {path: path.resolve(__dirname, 'build'), filename: '[name].[hash:8].js'},// 插件, 数组plugins: [new webpack.ProgressPlugin(), // 显示项目打包的进度// new HtmlWebpackPlugin() // 默认的不是 public/index.html,自动生成index.htmlnew HtmlWebpackPlugin({template: './public/index.html', // 将public/index.html打包至build目录下// filename: 'base.html' // 生成的html文件名为base.html,默认值为index.html// public/index.html <%= htmlWebpackPlugin.options.title %>title: '2008webpack' })]
}
发现每打包一次,都会生成 新的 一个 js文件,如果需要每次只打包出一个文件
clean-webpack-plugin
cnpm install --save-dev clean-webpack-plugin
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin') // 需要解构
module.exports = {mode: 'production',entry: {app: './src/index.js'},output: {path: path.resolve(__dirname, 'build'), filename: '[name].[hash:8].js'},plugins: [new webpack.ProgressPlugin(), // new CleanWebpackPlugin(), // 清除上一次的打包的文件new CleanWebpackPlugin({verbose: true // 打印清除操作的日志}), new HtmlWebpackPlugin({template: './public/index.html', title: '2008webpack' })]
}
拓展
new CleanWebpackPlugin({// Simulate the removal of files// 模拟删除文件// default: falsedry: true,// Write Logs to Console// (Always enabled when dry is true)// 将日志写入控制台// default: falseverbose: true,// Automatically remove all unused webpack assets on rebuild// 重建时自动删除所有未使用的网页包资产// default: truecleanStaleWebpackAssets: false,// Do not allow removal of current webpack assets// 不允许删除当前网页包资产// default: trueprotectWebpackAssets: false,
});
copy-webpack-plugin
cnpm install copy-webpack-plugin@6 --save-dev
拷贝vue项目的s r c/assets 以及public目录下的图标 favicon.icoconst path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin') // 需要解构
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = {mode: 'production',entry: {app: './src/index.js'},output: {path: path.resolve(__dirname, 'build'), filename: '[name].[hash:8].js'},// 插件, 数组plugins: [new webpack.ProgressPlugin(),new CleanWebpackPlugin({verbose: true}), new CopyWebpackPlugin({ // 克隆 src/assets 文件夹至输出目录下的 static 文件夹patterns: [ // 规则{from: './src/assets',to: 'static'},{from: './public/favicon.ico',to: ''}]}),new HtmlWebpackPlugin({template: './public/index.html',title: '2008webpack' })]
}
Name | Type | Default | Description |
---|---|---|---|
from | {String} | undefined | 从中复制文件的全局或路径。相对路径或者绝对路径 |
to | {String|Function} | compiler.options.output | 输出路径 |
context | {String} | options.context || compiler.options.context | 确定如何解释“from”路径的路径。 |
globOptions | {Object} | undefined | Options 传递到包含“ignore”选项的全局模式匹配库。 |
filter | {Function} | undefined | 允许筛选复制assets. |
toType | {String} | undefined | 确定什么是“to”选项-目录、文件或模板。 |
force | {Boolean} | false | 覆盖已在中的文件汇编.资产 (通常由其他插件/加载程序添加) |
transform | {Object} | undefined | 允许修改文件内容。启用“转换”缓存。您可以使用{transform:{cache:{key:'my cache key'}}} 使缓存失效。 |
noErrorOnMissing | {Boolean} | false | 不会对丢失的文件生成错误。 |
info | {Object|Function} | undefined | 允许添加assets信息。 |
压缩js代码 UglifyJsPlugin
如果是webpack5以前需要使用以下语句进行代码的压缩
new webpack.optimize.UglifyJsPlugin({compress: {warnings: false,drop_console: false,}}),
webpack5的话。可以通过 设置mode属性会自动压缩代码
解析器 模块配置
解析样式相关模块
cnpm i style-loader css-loader node-sass sass-loader@10 less less-loader@7 stylus stylus-loader@4 -S
Src/a.csshtml {background-color: #f66;
}
src/b.scsshtml {background-color: #00f;
}
Src/c.lesshtml {background-color: #00f;
}
src/d.stylushtml background-color #f66
Src/index.js// import './a.css'
// import './b.scss'
// import './c.less'
import './d.stylus'const path = require('path')
const webpack = require('webpack')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {mode: 'production', // production development 模式entry: { // 入口app: './src/index.js'},output: { // 出口path: path.resolve(__dirname, 'dist'),filename: '[name].[hash:8].js'},plugins: [ // 数组// 打包进度的显示new webpack.ProgressPlugin(),// 打包时清除之前的缓存文件new CleanWebpackPlugin({ // 清除之前打包出来的文件verbose: true // 显示删除的日志}),new CopyWebpackPlugin({patterns: [ // 规则{from: './src/assets', to: 'static'},{from: './public/favicon.ico', to: ''}]}),// new HTMLWebpackPlugin() // 自动生成一个html页面new HTMLWebpackPlugin({template: './public/index.html',title: '2008webpack'}) ],module: { // 解析器rules: [{test: /\.css$/,use: [ // 使用顺序是从后到前{ loader: 'style-loader'},{ loader: 'css-loader' }]},{test: /\.scss$/,use: [ // 使用顺序是从后到前{ loader: 'style-loader'},{ loader: 'css-loader' },{ loader: 'sass-loader' }]},{test: /\.less$/,use: [ // 使用顺序是从后到前{ loader: 'style-loader'},{ loader: 'css-loader' },{ loader: 'less-loader' }]},{test: /\.stylus$/,use: [ // 使用顺序是从后到前{ loader: 'style-loader'},{ loader: 'css-loader' },{ loader: 'stylus-loader' }]},]}
}
抽离css文件
cnpm install --save-dev mini-css-extract-plugin
const path = require('path')
const webpack = require('webpack')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // 抽离css
module.exports = {mode: 'production', // production development 模式entry: { // 入口app: './src/index.js'},output: { // 出口path: path.resolve(__dirname, 'dist'),filename: '[name].[hash:8].js'},plugins: [ // 数组// 打包进度的显示new webpack.ProgressPlugin(),// 打包时清除之前的缓存文件new CleanWebpackPlugin({ // 清除之前打包出来的文件verbose: true // 显示删除的日志}),new CopyWebpackPlugin({patterns: [ // 规则{from: './src/assets', to: 'static'},{from: './public/favicon.ico', to: ''}]}),new MiniCssExtractPlugin({filename: 'css/[name].[hash:8].css'}),// new HTMLWebpackPlugin() // 自动生成一个html页面new HTMLWebpackPlugin({template: './public/index.html',title: '2008webpack'}) ],module: { // 解析器rules: [{test: /\.css$/,use: [ // 使用顺序是从后到前{ loader: MiniCssExtractPlugin.loader },{ loader: 'css-loader' }]},{test: /\.scss$/,use: [ // 使用顺序是从后到前{ loader: MiniCssExtractPlugin.loader },{ loader: 'css-loader' },{ loader: 'sass-loader' }]},{test: /\.less$/,use: [ // 使用顺序是从后到前{ loader: MiniCssExtractPlugin.loader },{ loader: 'css-loader' },{ loader: 'less-loader' }]},{test: /\.stylus$/,use: [ // 使用顺序是从后到前{ loader: MiniCssExtractPlugin.loader },{ loader: 'css-loader' },{ loader: 'stylus-loader' }]},]}
}
封装解析器
const path = require('path')
const webpack = require('webpack')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // 抽离cssconst loaderUse = (type) => {return [ // 使用顺序是从后到前{ loader: MiniCssExtractPlugin.loader },{ loader: 'css-loader' },{ loader: type }]
}
module.exports = {mode: 'production', // production development 模式entry: { // 入口app: './src/index.js'},output: { // 出口path: path.resolve(__dirname, 'dist'),filename: '[name].[hash:8].js'},plugins: [ // 数组// 打包进度的显示new webpack.ProgressPlugin(),// 打包时清除之前的缓存文件new CleanWebpackPlugin({ // 清除之前打包出来的文件verbose: true // 显示删除的日志}),new CopyWebpackPlugin({patterns: [ // 规则{from: './src/assets', to: 'static'},{from: './public/favicon.ico', to: ''}]}),new MiniCssExtractPlugin({filename: 'css/[name].[hash:8].css'}),// new HTMLWebpackPlugin() // 自动生成一个html页面new HTMLWebpackPlugin({template: './public/index.html',title: '2008webpack'}) ],module: { // 解析器rules: [{test: /\.css$/,use: [ // 使用顺序是从后到前{ loader: MiniCssExtractPlugin.loader },{ loader: 'css-loader' }]},{test: /\.scss$/,use: loaderUse('sass-loader')},{test: /\.less$/,use: loaderUse('less-loader')},{test: /\.stylus$/,use: loaderUse('stylus-loader')},]}
自动补全css
cnpm i postcss postcss-loader@4 autoprefixer postcss-preset-env -D
创建postcss.config.js
module.exports = {plugins: [require('autoprefixer')({overrideBrowserslist: ['last 100 versions']})]
}
const path = require('path')
const webpack = require('webpack')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // 抽离cssconst loaderUse = (type) => {return [ // 使用顺序是从后到前{ loader: MiniCssExtractPlugin.loader },{ loader: 'css-loader' },{ loader: 'postcss-loader' }, // 处理css{ loader: type }]
}
module.exports = {mode: 'production', // production development 模式entry: { // 入口app: './src/index.js'},output: { // 出口path: path.resolve(__dirname, 'dist'),filename: '[name].[hash:8].js'},plugins: [ // 数组// 打包进度的显示new webpack.ProgressPlugin(),// 打包时清除之前的缓存文件new CleanWebpackPlugin({ // 清除之前打包出来的文件verbose: true // 显示删除的日志}),new CopyWebpackPlugin({patterns: [ // 规则{from: './src/assets', to: 'static'},{from: './public/favicon.ico', to: ''}]}),new MiniCssExtractPlugin({filename: 'css/[name].[hash:8].css'}),// new HTMLWebpackPlugin() // 自动生成一个html页面new HTMLWebpackPlugin({template: './public/index.html',title: '2008webpack'}) ],module: { // 解析器rules: [{test: /\.css$/,use: [ // 使用顺序是从后到前{ loader: MiniCssExtractPlugin.loader },{ loader: 'css-loader' }]},{test: /\.scss$/,use: loaderUse('sass-loader')},{test: /\.less$/,use: loaderUse('less-loader')},{test: /\.stylus$/,use: loaderUse('stylus-loader')},]}
}
如果不设置 外部配置文件
const loaderUse = (fileLoader) => {return [{loader: MiniCssExtractPlugin.loader},'css-loader',{loader: 'postcss-loader',options: {postcssOptions: {plugins: [['autoprefixer',{overrideBrowserslist: ['last 100 versions']}],['postcss-preset-env',{// Options}]]}}},fileLoader]
}
图片资源处理
假设css中含有 北京图片
cnpm i file-loader url-loader -S
module: {rules: [...,{test: /\.(jpg|jpeg|png|gif|webp|svg)$/,use: {loader: 'url-loader',options: {// 如果设置的值足够大,显示base64图片地址(内存中)// 如果设置的值足够小,显示图片的地址limit: 2048, // 单位为字节publicPath: './../../' // css 采取模块化,}}}]
}
每次都需要 webpack 打包然后再查看项目,设置类似于 vue 的 yarn serve 指令,修改代码,浏览器自动更新
开发服务器设置 - HMR
hot module replacement. 热替换
cnpm i webpack-dev-server @webpack-cli/serve -S
默认情况下,如果不去配置 开发服务器的话,直接可以使用 webpack-dev-server
开启服务器
webpack-dev-server
浏览器访问。http://localhsot:8080
如果需要配置服务器 -- 一般不需要
// webpack.config.js
devServer: { // 开发服务器配置// host: '0.0.0.0', // 在局域网下 可以通过 ip地址访问项目,默认值为 127.0.0.1// port: '8000', // 指定服务器的端口号// open: true// https://www.webpackjs.com/configuration/dev-server/#devserver-proxy// 请求 'http://121.89.205.189/api/pro/listproxy: {'/api': { // /api/pro/listtarget: 'http://121.89.205.189/api',pathRewrite: {'^/api': '' // 以 /api 开头的才去代理 }},'/2007': { // /api/pro/listtarget: 'http://121.89.205.189/api',pathRewrite: {'^/2007': '' // 以 /api 开头的才去代理 }}}}
处理js
cnpm i @babel/core @babel/preset-env babel-loader -S
{test: /\.js$/,exclude: /node_modules/,use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env'] // 处理js的高级语法}}
}
但是如果遇到js的高级语法
cnpm i @babel/plugin-transform-runtime @babel/runtime -S // 优化转换器
{test: /\.js$/,use: [{ loader: 'babel-loader',options: { // 如果遇到 js 的高级语法,需要用以下的预设去解决presets: ['@babel/preset-env'],plugins: [ // 插件 ['@babel/plugin-transform-runtime']]}}]},
如果遇到项目中含有 类的属性需要使用时
class Test {// constructor () {// this.state = {// a: 1// }// }state = {a: 1}
}
const test = new Test()
console.log('aaa', test.state.a) // aaa 1
Support for the experimental syntax 'classProperties' isn't currently enabled (17:9):
cnpm i @babel/plugin-proposal-class-properties -S // 遇到类的静态属性{test: /\.js$/,exclude: /node_modules/,use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env'],plugins: [['@babel/plugin-transform-runtime'],['@babel/plugin-proposal-class-properties', // 处理类的静态属性 state = { a: 1}{loose: true}],]}}}
如果项目中需要使用装饰器写法
function fn () {console.log('askjhksdjhksjghkfsjghksfj')
}
// 装饰器也是函数 使用时以 @ 开头
@fn()
class Test {// constructor () {// this.state = {// a: 1// }// }state = {a: 1}
}
const test = new Test()
console.log('aaa', test.state.a)
Support for the experimental syntax 'decorators-legacy' isn't currently enabled
cnpm i @babel/plugin-proposal-decorators -S // 装饰器语法
{test: /\.js$/,use: [{ loader: 'babel-loader',options: { // 如果遇到 js 的高级语法,需要用以下的预设去解决presets: ['@babel/preset-env'],plugins: [ // 插件 ['@babel/plugin-transform-runtime'],[ // 装饰器语法的配置'@babel/plugin-proposal-decorators',{ "legacy": true }],[ // 处理 类的 属性 时用的, 不写构造函数'@babel/plugin-proposal-class-properties',{loose: true}]]}}]},
如果遇到 浏览器解析不了的语句,不兼容老版本的写法。----- 垫片
cnpm i @babel/polyfill -S
-
1.入口处引入
import '@babel/polyfill'
-
2.webpack的配置文件的entry入口处,不需要在入口处引入
entry: {// app: './src/main.js',app: ['@babel/polyfill', './src/main.js'],},
-
3.添加配置项
{test: /\.js$/,exclude: /node_modules/,use: {loader: 'babel-loader',options: {// presets: ['@babel/preset-env'],presets: [// +++++++++++++++++++++++++++++++++['@babel/preset-env',{useBuiltIns: 'usage'}]],plugins: ['@babel/plugin-transform-runtime',// 处理async await['@babel/plugin-proposal-decorators', // 装饰器{legacy: true}],['@babel/plugin-proposal-class-properties', // 处理类的属性{loose: true}],]}}}
为什么要使用垫片
Babel默认只转换新的JavaScript句法(syntax),而不转换新的API,比如 Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局对象,以及一些定义在全局对象上的方法(比如Object.assign)都不会转码。举个栗子,ES6在Array对象上新增了Array.from方法。Babel就不会转码这个方法。如果想让这个方法运行,必须使用babel-polyfill,为当前环境提供一个垫片。
var obj = Object.assign({}, { a: 1}, {b:2})
console.log(obj)
设置成开发环境,打包项目,查询关键词,设置了 垫片 assign 有35个,不设置只有 12个
开发vue
拷贝 pubic文件夹 src文件夹 以及 package.json, postcss.config.js ,webpack.config.js 到vue文件夹
创建src/index.js 作为入口文件
cnpm i vue -S
cnpm i vue-template-compiler vue-loader -S
Vue/webpack.config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {plugins: [new VueLoaderPlugin(),new webpack.ProgressPlugin(),...],module: {rules: [{test: /\.vue$/,use: [{loader: 'vue-loader'}]},....]},
}
Src/index.js
import Vue from 'vue'
import App from './App.vue'
new Vue({render: h => h(App)
}).$mount('#app')
Src/App.vue<template><div>这里是vue<button @click="count+=10">{{count}}</button></div>
</template>
<script>
export default {data () {return {count: 10}}
}
</script>
开发react
拷贝 pubic文件夹 src文件夹 以及 package.json, postcss.config.js ,webpack.config.js 到vue文件夹
创建src/index.js 作为入口文件
cnpm i react react-dom @babel/preset-react -S
module.exports = {...,module: { // 解析器rules: [...,{test: /\.(js|jsx)$/, // +++++++++++++++++++++++++++++++++exclude: /node_modules/,use: {loader: 'babel-loader',options: {// presets: ['@babel/preset-env'], // 处理js的高级语法presets: [['@babel/preset-env',{useBuiltIns: 'usage'}],[ // +++++++++++++++++++++++++++++++++'@babel/preset-react']],plugins: [ // 插件 ['@babel/plugin-transform-runtime'],[ // 装饰器语法的配置'@babel/plugin-proposal-decorators',{ "legacy": true }],['@babel/plugin-proposal-class-properties', // 处理类的静态属性 state = { a: 1}{loose: true}],]}}}]}
}
参照webpack的版本号
{"dependencies": {"@babel/core": "^7.14.0","@babel/plugin-proposal-class-properties": "^7.13.0","@babel/plugin-proposal-decorators": "^7.13.15","@babel/plugin-transform-runtime": "^7.13.15","@babel/polyfill": "^7.12.1","@babel/preset-env": "^7.14.1","@babel/preset-react": "^7.13.13","@babel/runtime": "^7.14.0","@webpack-cli/serve": "^1.4.0","babel-loader": "^8.2.2","clean-webpack-plugin": "^4.0.0-alpha.0","css-loader": "^5.2.4","file-loader": "^6.2.0","html-webpack-plugin": "^4.5.2","less": "^4.1.1","less-loader": "^7.3.0","node-sass": "^5.0.0","react": "^17.0.2","react-dom": "^17.0.2","sass-loader": "^10.1.1","style-loader": "^2.0.0","stylus": "^0.54.8","stylus-loader": "^4.3.3","url-loader": "^4.1.1","webpack": "^4.46.0","webpack-cli": "^4.7.0","webpack-dev-server": "^3.11.2"},"devDependencies": {"autoprefixer": "^10.2.5","copy-webpack-plugin": "^6.4.1","mini-css-extract-plugin": "^1.6.0","postcss": "^8.2.14","postcss-loader": "^4.2.0","postcss-preset-env": "^6.7.0"}
}
相关文章:

webpack指南
🌈个人主页:前端青山 🔥系列专栏:webpack篇 🔖人终将被年少不可得之物困其一生 依旧青山,本期给大家带来webpack篇专栏内容:webpack-指南 概念 中文: webpack | webpack中文文档 | webpack中文网 英文&…...

关于QUERY_ALL_PACKAGES权限导致Google下架apk
谷歌商店被下架,原因是第三方使用了 QUERY_ALL_PACKAGES 权限; Google在高版本上限制了此权限的使用。当然,并不是 QUERY_ALL_PACKAGES 这个权限没有了,而是被列为敏感权限,必须有充分的理由说明,才允许上架 GP&#…...

优化时钟网络之时钟抖动
Note:文章内容以Xilinx 7系列FPGA进行讲解 1、什么是时钟抖动 时钟抖动就是时钟周期之间出现的偏差。比如一个时钟周期为10ns的时钟,理想情况下,其上升沿会出现在0ns,10ns,20ns时刻,假设某个上升沿出现的时…...

C++《继承》
在之前学习学习C类和对象时我们就初步了解到了C当中有三大特性,分别是封装、继承、多态,通过之前的学习我们已经了解了C的封装特性,那么接下来我们将继续学习另外的两大特性,在此将分为两个章节来分别讲解继承和多态。本篇就先来学…...

微澜:用 OceanBase 搭建基于知识图谱的实时资讯流的应用实践
本文作者: 北京深鉴智源科技有限公司架构师 郑荣凯 本文整理自北京深鉴智源科技有限公司架构师郑荣凯,在《深入浅出 OceanBase 第四期》的分享。 知识图谱是一项综合性的系统工程,需要在在各种应用场景中向用户展示经过分页的一度关系。 微…...

【LeetCode】【算法】538. 把二叉搜索树转换为累加树
LeetCode 538. 把二叉搜索树转换为累加树 题目 给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。 提醒一下…...

YoloV8改进策略:注意力改进|EPSANet,卷积神经网络上的高效金字塔挤压注意力块|即插即用|代码+改进方法
摘要 论文介绍 本文介绍的论文是“EPSANet:卷积神经网络上的高效金字塔挤压注意力块”,该论文提出了一种新颖、轻量且有效的注意力方法,即金字塔挤压注意力(PSA)模块。论文通过替换ResNet瓶颈块中的 3 3 3 \times 3 3...

Nextflow最佳实践:如何在云上高效处理大规模数据集
1. Nextflow 软件架构介绍 Nextflow 是一个用于简化数据驱动计算流程的工具,可以在各种计算环境中轻松部署。它采用了分布式计算和容器技术,实现了高度模块化、可重复性和可扩展性。NextFlow 的软件架构主要包括以下几个部分: 用户界面&…...

数据结构:顺序表(动态顺序表)
专栏说明:本专栏用于数据结构复习,文章中出现的代码由C语言实现,在专栏中会涉及到部分OJ题目,如对你学习有所帮助,可以点赞鼓励一下博主喔💓 博客主页:Duck Bro 博客主页系列专栏:数…...

springboot040社区医院信息平台
🍅点赞收藏关注 → 添加文档最下方联系方式领取本源代码、数据库🍅 本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目希望你能有所收获,少走一些弯路。🍅关注我不迷路🍅 项目视频 spr…...

windows下QT5.12.11使用MSVC编译器编译mysql驱动并使用详解
1、下载mysql开发库,后面驱动编译的时候需要引用到,下载地址:mysql开发库下载 2、使用everything搜索:msvc-version.conf,用记事本打开,添加:QMAKE_MSC_VER=1909。不然msvc下的mysql源码加载不上。...

c++写一个死锁并且自己解锁
刷算法题: 第一遍:1.看5分钟,没思路看题解 2.通过题解改进自己的解法,并且要写每行的注释以及自己的思路。 3.思考自己做到了题解的哪一步,下次怎么才能做对(总结方法) 4.整理到自己的自媒体平台。 5.再刷重复的类…...

JavaScript方法修改 input type=file 样式
html中的<input type "file">的样式很难修改,又跟页面风格很不匹配。我就尝试了几种方法,但是不管是用label还是用opacity:0都很麻烦,还老是出问题,所以最后还是用JavaScript来解决。 下面附上代码:…...

群控系统服务端开发模式-应用开发-前端个人信息功能
个人信息功能我把他分为了3部分:第一部分是展示登录者信息;第二步就是登录者登录退出信息;第三部分就是修改个人资料。 一、展示登录者信息 1、优先添加固定路由 在根目录下src文件夹下route文件夹下index.js文件中,添加如下代码 …...

【jupyter】文件路径的更改
使用过 jupyter notebook 环境的同行, 都体会过随机生成 .html 静态网页的过程, 虽然文档较小, 但是不堪反复使用积少成多。本文基于windows系统。 找到 runtime 目录 一般 jupyter 默认 runtime 在下述格式目录中 C:\Users\用户名\AppData…...

Ruby编程语言全景解析:从基础到进阶
Ruby是一种动态的、面向对象的编程语言,以其优雅的语法和强大的功能而闻名于世。自从1995年由日本程序员松本行弘(Yukihiro Matsumoto)发布以来,Ruby便迅速成为了开发者中颇受欢迎的编程语言之一。无论是构建简单的脚本还是复杂的…...

Elasticsearch 8.16:适用于生产的混合对话搜索和创新的向量数据量化,其性能优于乘积量化 (PQ)
作者:来自 Elastic Ranjana Devaji, Dana Juratoni Elasticsearch 8.16 引入了 BBQ(Better Binary Quantization - 更好的二进制量化)—— 一种压缩向量化数据的创新方法,其性能优于传统方法,例如乘积量化 (Product Qu…...

解决vscode不能像pycharm一样从其他同级文件夹导包
在vscode中选择:文件-首选项-设置-扩展-Python-settings.json 向setting.json添加如下代码: "terminal.integrated.env.osx": {"PYTHONPATH": "${workspaceFolder}/",},"terminal.integrated.env.linux": {"PYTHON…...

DAY24|回溯算法Part03|LeetCode:93.复原IP地址、78.子集、90.子集II
目录 LeetCode:93.复原IP地址 基本思路 C代码 LeetCode:78.子集 基本思路 C代码 LeetCode:90.子集II 基本思路 C代码 通过used实现去重 通过set实现去重 不使用used和set版本 LeetCode:93.复原IP地址 力扣代码链接 文字讲解:LeetCode:93.复原IP地…...

接口自动化测试做到什么程度的覆盖算是合格的
接口自动化测试的覆盖程度是一个衡量测试质量与效率的重要指标,其“好”的标准并非绝对,而是根据项目特性和团队需求动态调整的结果。然而,有几个原则和实践可以帮助我们确定一个相对合理的覆盖范围,以及为何这些覆盖是必要的。 1…...

Kubernetes-ArgoCD篇-01-简介
1、什么是Argo CD Argo CD 是针对 Kubernetes 的声明式 GitOps 持续交付工具。 Argo CD官方文档地址:https://argo-cd.readthedocs.io Argo CD源码地址:https://github.com/argoproj/argo-cd 1.1 关于Argo Argo是一个开源的项目,主要是扩…...

阿里云通义大模型团队开源Qwen2.5-Coder:AI编程新纪元
🚀 11月12日,阿里云通义大模型团队宣布开源通义千问代码模型全系列,共6款Qwen2.5-Coder模型。这些模型在同等尺寸下均取得了业界最佳效果,其中32B尺寸的旗舰代码模型在十余项基准评测中均取得开源最佳成绩,成为全球最强…...

【大数据学习 | HBASE高级】hbase的参数优化
Zookeeper 会话超时时间 属性:zookeeper.session.timeout 解释:默认值为 90000 毫秒(90s) hbase.client.pause(默认值 100ms)重试间隔 hbase.client.retries.number(默认 15 次)重试…...

两个链表求并集、交集、差集
两个链表求并集、交集、差集 两个链表求并集、交集、差集其实都是创建一个新链表然后遍历插入的题型,所以下边就举并集一个例子。 首先将l1里的所有节点遍历存储到新节点l中开始遍历l2,如果l中不存在l2中的节点就将其尾插到l中 下面是两个链表求并集、交集、差集的代…...

C++中的栈(Stack)和堆(Heap)
在C中,堆(heap)和栈(stack)是两种用于存储数据的内存区域。理解它们的原理和区别,对于优化代码性能和确保代码的安全性至关重要。以下是对C中堆栈的详细解析,包括它们的分配方式、优缺点、应用场…...

Linux系统编程学习 NO.11——进程的概念(2)
谈谈进程的性质 进程的竞争性 由于CPU资源是稀缺的,进程数量是众多的。不可避免需要造成进程排队等待CPU资源的动作,内核的设计者为了让操作系统合理的去调度这这些进程,就产生了进程优先级的概念。设置合理的进程优先级能让不同进程公平的去竞争CPU资…...

QT自定义控件封装
QT自定义控件封装 1.概述 这篇文章介绍如何创建UI文件,通过自定义方式将两个控件联动起来,实现自定义功能。 2.创建UI文件 新建一个widget的普通项目,然后在项目名称上右键选择And New... 新建文件,然后选择QT 再选择Qt Desig…...

【搜索结构】AVL树的学习与实现
目录 什么是AVL树 AVL树的定义 插入函数的实现 左单旋和右单旋 左右双旋与右左双旋 什么是AVL树 AVL树实际上就是二叉搜索树的一种变体,我们都知道二i叉搜索树可以将查找的时间复杂度提升到O(logn),极大提升搜索效率。但是在极端情况下,当…...

LeetCode40:组合总和II
原题地址:. - 力扣(LeetCode) 题目描述 给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用 一次 。 注意ÿ…...

基于Python+Vue开发的旅游景区管理系统
项目简介 该项目是基于PythonVue开发的旅游景区管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Python编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Python的旅游景…...