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

配置项

NameTypeDefaultDescription
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}falsefalseIftruelink标记呈现为自动关闭(符合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' })]
}
​
NameTypeDefaultDescription
from{String}undefined从中复制文件的全局或路径。相对路径或者绝对路径
to{String|Function}compiler.options.output输出路径
context{String}options.context || compiler.options.context确定如何解释“from”路径的路径。
globOptions{Object}undefinedOptions 传递到包含“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"}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/14637.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

把越南语翻译成中文一般用什么翻译工具?《越南语翻译通》App或许能满足你的技术痛点需求!

在多语言交流日益频繁的今天&#xff0c;掌握越南语对于商务、旅游或学术交流都是一项重要技能。《越南语翻译通》App应运而生&#xff0c;旨在通过技术手段简化越南语学习和翻译过程&#xff0c;满足用户在不同场景下的需求。 核心技术 《越南语翻译通》App采用了先进的自然语…

Android Framework AMS(16)进程管理

该系列文章总纲链接&#xff1a;专题总纲目录 Android Framework 总纲 本章关键点总结 & 说明&#xff1a; 说明&#xff1a;本章节主要解读AMS 进程方面的知识。关注思维导图中左上侧部分即可。 我们本章节主要是对Android进程管理相关知识有一个基本的了解。先来了解下L…

Rust Struct 属性初始化

结构体是用户定义的数据类型&#xff0c;其中包含定义特定实例的字段。结构有助于实现更容易理解的抽象概念。本文介绍几种初始化结构体对象的方法&#xff0c;包括常规方法、Default特征、第三方包实现以及构建器模式。 Struct声明与初始化 struct Employee {id: i32,name: …

Vue全栈开发旅游网项目(10)-用户管理后端接口开发

1.异步用户登录\登出接口开发 1.设计公共响应数据类型 文件地址&#xff1a;utils/response404.py from django.http import JsonResponseclass BadRequestJsonResponse(JsonResponse):status_code 400def __init__(self, err_list, *args, **kwargs):data {"error_c…

数据结构:队列

目录 概念与结构底层结构的选择队列的实现队列头文件&#xff08;queue.h&#xff09;队列初始化队列的销毁入队列检查队列是否为空出队列查询队列第一个数据查询队列末尾数据查询队列有效数据个数代码试运行 概念与结构 概念&#xff1a;只允许在⼀端进行插⼊数据操作&#x…

Clickhouse集群新建用户、授权以及remote权限问题

新建用户 create user if not exists user on cluster 集群名称 IDENTIFIED WITH plaintext_password BY 密码;给用户授查询、建表、删表的权限 GRANT create table,select,drop table ON 数据库实例.* TO user on cluster 集群名称 ;再其他节点下用户建本地表成功&#…

JavaWeb--MySQL

1. MySQL概述 首先来了解一下什么是数据库。 数据库&#xff1a;英文为 DataBase&#xff0c;简称DB&#xff0c;它是存储和管理数据的仓库。 像我们日常访问的电商网站京东&#xff0c;企业内部的管理系统OA、ERP、CRM这类的系统&#xff0c;以及大家每天都会刷的头条、抖音…

i春秋-SQLi(无逗号sql注入,-- -注释)

练习平台地址 竞赛中心 题目描述 后台有获取flag的线索应该是让我们检查源码找到后台 题目内容 空白一片 F12检查源码 发现login.php 访问login.php?id1 F12没有提示尝试sql注入 常规sql注入 //联合注入得到表格列数 1 order by 3 # 1 union select 1,2,3 #&#xff08…

基于Spring Boot的电子商务平台架构

2 相关技术 2.1 SpringBoot框架介绍 Spring Boot是一种不需要代码生成的一种框架&#xff0c;并且可以不需要配置任何的XML文件就可以&#xff0c;因为Spring Boot里面自带了很多接口&#xff0c;只需要配置不同的接口就会自动的应用并且识别需要的依赖&#xff0c;在配置方面非…

华为云分布式缓存服务(DCS)专家深度解析Valkey,助力openEuler峰会

在数字化时代&#xff0c;开源技术已成为推动创新和协作的重要力量。 11月15日&#xff0c;openEuler峰会将于北京中关村国际创新中心举行。本次峰会&#xff0c;华为云分布式缓存服务&#xff08;DCS&#xff09;的两位专家将为大家深入讲解Valkey的核心特性与优势。 更多大…

如何进行产线高阶能耗数据的计算和可视化?

一、前言 在当前经济下行时期&#xff0c;越来越来多企业开始对产线进行数字化转型&#xff0c;提高企业竞争力。在产线数字化转型过程中&#xff0c;产线高阶能耗数据的计算和可视化是比较重要的一环&#xff0c;今天小编就和大家分享如何对产线能耗数据进行计算和可视化。 …

vsftp 修改端口 限制用户登录 开启防火墙 pasv模式

安装设置开机启动 yum -y install vsftpd systemctl start vsftpd systemctl enable vsftpd 修改配置&#xff0c;追加端口号到最后一行 vim /etc/vsftpd/vsftpd.conf listen_port5510 编辑 /etc/services 文件&#xff0c;将其中的三行端口改成5510 vim /etc/services ftp …

IntelliJ IDEA插件开发-代码补全插件入门开发

使用IntelliJ IDEA想必大家都有使用过代码自动补全功能&#xff0c;如输入ab&#xff0c;会自动触发补全&#xff0c;提供相应的补全建议列表。作为有追求的程序员&#xff0c;有没有想过这样的功能是如何实现的&#xff1f;本节将详细介绍如何实现一个类似的代码自动补全插件。…

❤React-React 组件基础(类组件)

❤React-React 组件基础 1、组件化开发介绍 组件化开发思想&#xff1a;分而治之 React的组件按照不同的方式可以分成类组件&#xff1a; 划分方式一&#xff08;按照组件的定义方式&#xff09; 函数组件(Functional Component )和类组件(Class Component)&#xff1b; …

Python →爬虫实践

爬取研究中心的书目 现在&#xff0c;想要把如下网站中的书目信息爬取出来。 案例一 耶鲁 Publications | Yale Law School 分析网页&#xff0c;如下图所示&#xff0c;需要爬取的页面&#xff0c;标签信息是“<p>”&#xff0c;所以用 itemssoup.find_all("p&…

机器学习: LightGBM模型(优化版)——高效且强大的树形模型

LightGBM&#xff08;Light Gradient Boosting Machine&#xff09;是一种基于梯度提升决策树&#xff08;GBDT&#xff09;的框架&#xff0c;由微软提出。它具有高效的训练速度、低内存占用、支持并行和GPU加速等特点&#xff0c;非常适合大规模数据的训练任务&#xff0c;尤…

《内存函数》

内存函数 1. memcpy函数 &#xff08;1&#xff09;介绍 这里通过memcpy的定义我们可以看这个函数包含三个参数&#xff0c;destination就是拷贝的目的地&#xff0c;source就是拷贝的源头&#xff0c;num就是拷贝的个数。 &#xff08;2&#xff09;使用 这里要包含头文件s…

不泄密的安全远程控制软件需要哪些技术

在数字化浪潮中&#xff0c;远程控制软件已不再是简单的辅助工具&#xff0c;而是成为企业运作和日常工作中不可或缺的一部分。随着远程办公模式的广泛采纳&#xff0c;这些软件提供了一种既安全又高效的途径来管理和访问远端系统。无论是在家办公、技术支持还是远程教育&#…

Pycharm打开终端时报错:Cannot open Local,Failed to start[powershell.exe]

问题如下&#xff1a; 解决办法&#xff1a; 修改设置中的shell path路径 英文版pycharm&#xff1a;file -> settings -> Tools -> Terminal -> Shell path 中文版pycharm&#xff1a;文件 -> 设置 -> 工具 -> 终端 -> Shell路径 将Shell路径不全 …

15分钟学 Go 第 51 天 :通用库与工具使用

第51天&#xff1a;通用库与工具使用 一、学习目标 类别工具/库用途命令行工具cobra构建命令行应用JSON处理gjson高效JSON解析HTTP客户端restyHTTP请求处理日期处理carbon时间日期操作配置管理viper配置文件处理 二、详细实现 让我们通过具体示例来学习这些库的使用&#x…