2025年3月15日 星期六 甲辰(龙)年 月十四 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > JavaScript

webpack指南

时间:02-17来源:作者:点击数:11
城东书院 www.cdsy.xyz

概念

中文: webpack | webpack中文文档 | webpack中文网(link:https://www.webpackjs.com/)

英文:webpack(link:https://webpack.js.org/)

webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle

从 webpack v4.0.0 开始,可以不用引入一个配置文件。然而,webpack 仍然还是高度可配置的。

  • 入口(entry)
  • 输出(output)
  • loader
  • 插件(plugins)

安装

  • 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

配置项

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 falseIftruelink标记呈现为自动关闭(符合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'
  •   })
  • ]
  • }
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.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"
  • }
  • }
城东书院 www.cdsy.xyz
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐