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.js
  entry: { // 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 builds
  mode: "development", // enabled useful tools for development
  mode: "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.js
    filename: '[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.html
    new 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: false
    dry: true,
 
    // Write Logs to Console
    // (Always enabled when dry is true)
    // 将日志写入控制台
    // default: false
    verbose: true,
 
    // Automatically remove all unused webpack assets on rebuild
    // 重建时自动删除所有未使用的网页包资产
    // default: true
    cleanStaleWebpackAssets: false,
 
    // Do not allow removal of current webpack assets
    // 不允许删除当前网页包资产
    // default: true
    protectWebpackAssets: false,
​
});

copy-webpack-plugin

cnpm install copy-webpack-plugin@6 --save-dev
拷贝vue项目的s r c/assets 以及public目录下的图标 favicon.ico

const 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.css

html {
  background-color: #f66;
}
src/b.scss

html {
  background-color: #00f;
}
Src/c.less

html {
  background-color: #00f;
}
src/d.stylus

html 
  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') // 抽离css

const 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') // 抽离css

const 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/list
    proxy: {
      '/api': { // /api/pro/list
        target: 'http://121.89.205.189/api',
        pathRewrite: {
          '^/api': '' // 以 /api 开头的才去代理 
        }
      },
      '/2007': { // /api/pro/list
        target: '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"
  }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CSS高级技巧_精灵图_字体图标_CSS三角_vertical-align(图像和文字居中在同一行)_溢出文字省略号显示

目录 CSS高级技巧 1. 精灵图 1.1 为什么需要精灵图 1.2 精灵图&#xff08;sprites&#xff09;的使用 1.2 精灵图的使用 案例&#xff1a;拼出自己名字 2. 字体图标 2.1 字体图标的产生 2.2 字体图标的优点 2.3 字体图标的下载 2.4 字体图标的引入 2.4.1 字体文件格…

仪表板展示|DataEase看中国:历年双十一电商销售数据分析

背景介绍 2024年“双十一”购物季正在火热进行中。自2009年首次推出至今&#xff0c;“双十一”已经成为中国乃至全球最大的购物狂欢节&#xff0c;并且延伸到了全球范围内的电子商务平台。随着人们消费水平的提升以及电子商务的普及&#xff0c;线上销售模式也逐渐呈现多元化…

若依项目-结构解读

项目结构 admin模块 common模块 framework模块 service模块 配置 依赖关系 前端接口 src 表结构

RTSP前端实时流

因项目需求探索前端实时流&#xff0c;本文介绍了 RTSP 前端不能直接播放&#xff0c;需中间层转换协议&#xff0c;如 RTSP 转 RTMP、HLS、HTTP-FLV&#xff0c;分别阐述其特点、配置和播放方式&#xff0c;还提及关键帧、延迟与卡顿的关系&#xff0c;以及直播平台使用云服务…

植物大战僵尸杂交版v2.6.1最新版本(附下载链接)

B站游戏作者潜艇伟伟迷于11月3日更新了植物大战僵尸杂交版2.6.1版本&#xff01;&#xff01;&#xff01;&#xff0c;有b站账户的记得要给作者三连关注一下呀&#xff01; 不多废话下载链接放上&#xff1a; 夸克网盘链接&#xff1a;https://pan.quark.cn/s/279e7ed9f878 新…

qsqlmysql.lib的编译和使用

文章目录 打开源码 打开源码 打开qt源码安装路径 src相对路径下的文件Src\qtbase\src\plugins\sqldrivers\mysql 比如我是5.9.9版本我的路径就是&#xff1a;D:\Qt5.9.9\5.9.9\Src\qtbase\src\plugins\sqldrivers\mysql 可以看到待编译的mysql驱动文件 使用IDE打开pro文件进…

Window下PHP安装最新sg11(php5.3-php8.3)

链接: https://pan.baidu.com/s/10yyqTJdwH_oQJnQtWcwIeA 提取码: qz8y 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦 (链接失效联系L88467872) 1.下载后解压文件&#xff0c;将对应版本的ixed.xx.win文件放进php对应的ext目录下&#xff0c;如图所示 2.修改ph…

30.超市管理系统(基于springboot和Vue的Java项目)

目录 1.系统的受众说明 2.相关技术和开发环境 2.1 相关技术 2.1.1 Java语言 2.1.2 HTML、CSS、JavaScript 2.1.3 MySQL 2.1.4 Vue.js 2.1.5 SpringBoot 2.2 开发环境 3. 系统分析 3.1 可行性分析 3.1.1 经济可行性 3.1.2 技术可行性 3.1.3 运行可行性 3.2…

去地面算法——depth_clustering算法调试(1)

1 源码下载 论文&#xff1a; 《2016-Fast Range Image-Based Segmentation of Sparse 3D Laser Scans for Online Operation》 《2017-Efficient Online Segmentation for Sparse 3D Laser Scans》 代码&#xff1a;git链接 2 问题记录 2.1 无法找到qt问题 问题截图&…

pyspark入门基础详细讲解

1.前言介绍 学习目标&#xff1a;了解什么是Speak、PySpark&#xff0c;了解为什么学习PySpark&#xff0c;了解课程是如何和大数据开发方向进行衔接 使用pyspark库所写出来的代码&#xff0c;既可以在电脑上简单运行&#xff0c;进行数据分析处理&#xff0c;又可以把代码无缝…

Qt 编写插件plugin,支持接口定义信号

https://blog.csdn.net/u014213012/article/details/122434193?spm1001.2014.3001.5506 本教程基于该链接的内容进行升级&#xff0c;在编写插件的基础上&#xff0c;支持接口类定义信号。 环境&#xff1a;Qt5.12.12 MSVC2017 一、创建项目 新建一个子项目便于程序管理【…

【python】python使用虚拟环境

使用虚拟环境的好处是创建一个独立干净的环境 首先cd到新项目的目录下 创建虚拟环境 使用日期命名方便自己找到版本 python -m venv venv20241114激活虚拟环境 .\venv20241114\Scripts\activate会创建一个文件夹 点进去可以看到是python的脚本所存文件结构 纯净环境 p…

CSS 技巧:如何让 div 完美填充 td 高度

引言 一天哈比比突然冒出一个毫无理头的一个问题: 本文就该问题进行展开… 原文链接: 昆仑虚F2E 一、需求说明 大致需求如下, 当然这里做了些简化 有如下初始代码: 一个自适应的表格每个单元格的宽度固定 200px每个单元格高度则是自适应每个单元格内是一个 div 标签, div 标签…

跟上AI的浪潮

现在AI技术已广泛应用至语音助手、写作、绘图、视频&#xff0c;甚至是各种语言的代码编写。平常我们都是应用别人开发好的模型&#xff0c;或者说智能体&#xff0c;那么我们自己能否做那个开发AI智能体的人&#xff0c;近期加了一个AI学习的大社区&#xff0c;几万在AI道路上…

专题十八_动态规划_斐波那契数列模型_路径问题_算法专题详细总结

目录 动态规划 动态规范五步走&#xff1a; 1. 第 N 个泰波那契数&#xff08;easy&#xff09; 解析&#xff1a; 1.状态表达式&#xff1a; 2.状态转移方程&#xff1a; 3.初始化&#xff1a; 4.填表顺序&#xff1a; 5.返回值 编写代码&#xff1a; 总结&#xff…

MySQL技巧之跨服务器数据查询:基础篇-更新语句如何写

MySQL技巧之跨服务器数据查询&#xff1a;基础篇-更新语句如何写 上一篇已经描述&#xff1a;借用微软的SQL Server ODBC 即可实现MySQL跨服务器间的数据查询。 而且还介绍了如何获得一个在MS SQL Server 可以连接指定实例的MySQL数据库的连接名: MY_ODBC_MYSQL 以及用同样的…

C/C++语言 多项式加法和乘法

多项式加法和乘法 多项式的加法题目描述输入输出样例步骤代码段全局变量设定新建结点合并链表 完整代码 多项式乘法题目描述输入输出样例代码段计算两多项式结果输入 完整代码 多项式的加法 题目描述 输入输出 样例 步骤 总体思想是用链表来做 ① 我们发现输入样例中&#xf…

ArkTs面向对象编程

ArkTs面向对象编程 1.1 面向对象编程概述 1.1.1 什么是面向对象编程 面向对象编程是一种编程范式&#xff0c;它使用“对象”来设计软件和创建可重用的程序设计 对象是包含数据和方法的实体&#xff0c;可以与其他对象进行交互 面相对象编程鼓励使用已有的对象来组合或修改以…

乳腺癌诊断分析——基于聚类分析实现

一、研究背景 乳腺癌属于恶性肿瘤&#xff0c;在早期发现后需要及早将病变组织切除&#xff0c;而且术后还要化疗和放射等辅助治疗&#xff0c;能够抑制癌细胞的扩散和增长。 二、研究目的 研究乳腺癌病人的患病特征通过聚类分析方法对特征进行分类通过上述聚类结果对乳腺诊…

丹摩征文活动|FLUX.1 和 ComfyUI:从部署到上手,轻松驾驭!

FLUX.1 和 ComfyUI&#xff1a;从部署到上手&#xff0c;轻松驾驭&#xff01; FLUX.1历史曲线 黑森林实验室推出了一款名为FLUX.1的先进图像生成模型&#xff0c;根据不同用户需求&#xff0c;提供了三种独特的版本。 FLUX.1-pro&#xff1a;作为专为企业打造的强大闭源版本…