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…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...

uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...